import 'package:flutter/material.dart';
import 'dart:async';
import 'package:firebase_database/firebase_database.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'main_page.dart';
import 'finish_private_page.dart'; // 게임 종료 후 이동할 페이지
import '../../plugins/api.dart';
import '../../dialogs/response_dialog.dart';
import '../../dialogs/score_edit_dialog.dart';   // 점수 수정 모달
import '../../dialogs/user_info_basic_dialog.dart'; // 일반 유저 정보 모달
import '../../plugins/admob.dart';
import '../../config/config.dart';

class PlayingPrivatePage extends StatefulWidget {
  final int roomSeq;
  final String roomTitle;

  const PlayingPrivatePage({
    Key? key,
    required this.roomSeq,
    required this.roomTitle,
  }) : super(key: key);

  @override
  State<PlayingPrivatePage> createState() => _PlayingPrivatePageState();
}

class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
  // Firebase Realtime Database (FRD)
  late DatabaseReference _roomRef;
  Stream<DatabaseEvent>? _roomStream;
  StreamSubscription<DatabaseEvent>? _roomStreamSubscription;

  // ─────────────────────────────────────────
  // One-hour countdown (운영시간 카운트다운)
  // ─────────────────────────────────────────
  Timer? _countdownTimer;
  Duration _remaining = const Duration(hours: 1); // 기본 1시간
  DateTime? _roomStartDt; // roomInfo.room_start_dt
  String _roomRunningTime = '0'; // 운영시간
  bool _roomTimeOut = false;
  String _roomExitYn = 'N';

  String roomMasterYn = 'N'; // 방장 여부
  String roomTitle = '';

  int myScore = 0;
  List<Map<String, dynamic>> _scoreList = [];

  bool _isLoading = true;
  bool _movedToFinishPage = false; // 종료 페이지 이동 중복 방지

  // 점수 공개 범위
  String scoreOpenRange = 'ALL';

  String mySeq = '0';

  // My participant type (나의 참가 타입)
  String myParticipantType = 'PLAYER';

  // userListMap: { userSeq: true/false }
  Map<String, bool> _userListMap = {};

  @override
  void initState() {
    super.initState();
    // (1) Restore FRD connection (FRD 연결 복원)
    FirebaseDatabase.instance.goOnline();

    roomTitle = widget.roomTitle;
    // (D) Initialize room info (방 정보 초기화)
    _initFirebase();
  }

  @override
  void dispose() {
    _countdownTimer?.cancel();
    _roomStreamSubscription?.cancel();
    super.dispose();
  }

  Future<void> _initFirebase() async {
    final prefs = await SharedPreferences.getInstance();
    mySeq = prefs.getInt('my_user_seq')?.toString() ?? '0';

    final roomKey = 'korea-${widget.roomSeq}';
    _roomRef = FirebaseDatabase.instance.ref('rooms/$roomKey');

    _listenRoomData();
  }

  void _listenRoomData() {
    _roomStream = _roomRef.onValue;
    _roomStream?.listen((event) {
      final snapshot = event.snapshot;
      if (!snapshot.exists) {
        setState(() {
          _isLoading = false;
          roomTitle = 'No Room Info'; // '방 정보 없음'
          _scoreList = [];
          myScore = 0;
        });
        return;
      }

      final data = snapshot.value as Map<dynamic, dynamic>? ?? {};
      final roomInfoData = data['roomInfo'] as Map<dynamic, dynamic>? ?? {};
      final userInfoData = data['userInfo'] as Map<dynamic, dynamic>? ?? {};
      final userListData = data['userList'] as Map<dynamic, dynamic>? ?? {};

      // Check room status (방 상태 체크)
      final roomStatus = (roomInfoData['room_status'] ?? 'WAIT').toString().toUpperCase();
      if (roomStatus == 'FINISH') {
        // If finished, move to finish page (종료 페이지)
        if (mounted) {
          Navigator.pushAndRemoveUntil(
            context,
            MaterialPageRoute(builder: (_) => FinishPrivatePage(roomSeq: widget.roomSeq, enterType: 'game')),
            (route) => false,
          );
        }
        return;
      }

      setState(() {
        // Running time (운영시간)
        _roomRunningTime = roomInfoData['running_time'] ?? '0';
        // Score open range (점수 공개 범위)
        scoreOpenRange = roomInfoData['score_open_range'] ?? 'ALL';

        // Check if master (방장 여부)
        final masterSeq = roomInfoData['master_user_seq'];
        roomMasterYn = (masterSeq != null && masterSeq.toString() == mySeq) ? 'Y' : 'N';

        // Room title (방 제목)
        final newTitle = (roomInfoData['room_title'] ?? '') as String;
        if (newTitle.isNotEmpty) roomTitle = newTitle;

        // userListMap
        _userListMap.clear();
        if (userListData != null) {
          userListData.forEach((k, v) {
            _userListMap[k.toString().replaceAll('_', '')] = (v == true);
          });
        }

        // Build user list (전체 유저 목록)
        final List<Map<String, dynamic>> rawList = [];
        userInfoData.forEach((uSeq, uData) {
          uSeq = uSeq.toString().replaceAll('_', '');
          // Mark room master (방장 표시)
          if (uSeq == roomInfoData['master_user_seq'].toString()) {
            uData['nickname'] = '★' + (uData['nickname'] ?? 'User'); 
            // '유저'
          } else if ((uData['participant_type'] ?? '').toString().toUpperCase() == 'ADMIN') {
            // Mark admin (사회자 표시)
            uData['nickname'] = '☆' + (uData['nickname'] ?? 'User'); 
          }
          rawList.add({
            'user_seq': uSeq,
            'participant_type': (uData['participant_type'] ?? '').toString().toUpperCase(),
            'nickname': uData['nickname'] ?? 'User', // '유저'
            'score': uData['score'] ?? 0,
            'profile_img': uData['profile_img'] ?? '',
            'department': uData['department'] ?? '',
            'introduce_myself': uData['introduce_myself'] ?? '',
            'is_my_score': (uSeq.toString() == mySeq) ? 'Y' : 'N',
          });

          if (uSeq.toString() == mySeq) {
            myParticipantType = (uData['participant_type'] ?? '').toString().toUpperCase();
          }
        });

        // Find my score (내 점수)
        int tmpMyScore = 0;
        for (var user in rawList) {
          if ((user['is_my_score'] ?? 'N') == 'Y') {
            tmpMyScore = user['score'] ?? 0;
          }
        }

        // Sort by score descending (점수 내림차순)
        final playerList = rawList.toList();
        playerList.sort((a, b) {
          final scoreA = a['score'] ?? 0;
          final scoreB = b['score'] ?? 0;
          return scoreB.compareTo(scoreA);
        });

        myScore = tmpMyScore;
        _scoreList = playerList;

        _isLoading = false;
      });

      // If FINISH => move
      if (roomStatus == 'FINISH' && !_movedToFinishPage) {
        _movedToFinishPage = true;
        Navigator.pushAndRemoveUntil(
          context,
          MaterialPageRoute(builder: (_) => FinishPrivatePage(roomSeq: widget.roomSeq, enterType: 'game')),
          (route) => false,
        );
        return;
      }

      // For countdown (room_start_dt) (운영시간 카운트다운)
      final roomStartDtStr = (roomInfoData['start_dt'] ?? '') as String;
      if (roomStartDtStr.isNotEmpty) {
        final dt = DateTime.tryParse(roomStartDtStr);
        if (dt != null) {
          setState(() {
            _roomStartDt = dt;
          });
          _startCountdownTimer();
        }
      }
    }, onError: (err) {
      setState(() {
        _isLoading = false;
        roomTitle = 'Error occurred'; // '오류 발생'
      });
    });
  }

  // Countdown timer (운영시간 카운트다운 타이머)
  void _startCountdownTimer() {
    if (_countdownTimer != null && _countdownTimer!.isActive) {
      return; 
    }
    if (_roomStartDt == null) return;

    _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      // End time = roomStartDt + running time (roomStartDt + 운영시간)
      final endTime = _roomStartDt!.add(Duration(hours: int.parse(_roomRunningTime)));
      final now = DateTime.now();
      final diff = endTime.difference(now);

      if (diff.isNegative) {
        // Time's up -> auto finish
        timer.cancel();
        _remaining = const Duration(seconds: 0);
        _onAutoTimeout();
      } else {
        setState(() {
          _remaining = diff;
        });
      }
    });
  }

  // Auto finish when time is up (운영시간 만료 후 자동 종료)
  void _onAutoTimeout() {
    setState(() {
      _roomTimeOut = true;
      _roomExitYn = 'Y';
    });
    _requestFinish();
  }

  /// If master, call finish API (방장이면 Finish API)
  Future<void> _requestFinish() async {
    final reqBody = {
      "room_seq": "${widget.roomSeq}",
      "room_type": "PRIVATE",
    };
    try {
      await Api.serverRequest(uri: '/room/score/game/finish', body: reqBody);
    } catch (e) {
      // ignore
    }
  }

  /// On back press (뒤로가기)
  Future<bool> _onWillPop() async {
    if (roomMasterYn == 'Y') {
      // If master (방장)
      final confirm = await showDialog<bool>(
        context: context,
        barrierDismissible: false,
        builder: (_) {
          return AlertDialog(
            backgroundColor: Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(16),
              side: const BorderSide(color: Colors.black, width: 1),
            ),
            title: const Text(
              'Leave', // '나가기'
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            content: const Text(
              'If the master leaves, the game will end.\nAre you sure you want to leave?', 
              // '방장이 나가면 게임이 종료됩니다.\n정말 나가시겠습니까?'
              style: TextStyle(fontSize: 14),
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context, false),
                style: TextButton.styleFrom(
                  backgroundColor: Colors.black,
                  foregroundColor: Colors.white,
                ),
                child: const Text('Cancel'), // '취소'
              ),
              TextButton(
                onPressed: () => Navigator.pop(context, true),
                style: TextButton.styleFrom(
                  backgroundColor: Colors.black,
                  foregroundColor: Colors.white,
                ),
                child: const Text('End'), // '종료'
              ),
            ],
          );
        },
      );
      if (confirm != true) return false;

      // Finish API
      await _requestFinish();
    } else {
      // If not master (일반 유저)
      final confirm = await showDialog<bool>(
        context: context,
        barrierDismissible: false,
        builder: (_) {
          return AlertDialog(
            backgroundColor: Colors.white,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(16),
              side: const BorderSide(color: Colors.black, width: 1),
            ),
            title: const Text(
              'Leave', // '나가기'
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            content: const Text(
              'If you leave this ongoing game, you cannot rejoin.\nAre you sure you want to leave?', 
              // '진행중인 방에서 나가면 재입장이 불가능합니다.\n정말 나가시겠습니까?'
              style: TextStyle(fontSize: 14),
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context, false),
                style: TextButton.styleFrom(
                  backgroundColor: Colors.black,
                  foregroundColor: Colors.white,
                ),
                child: const Text('Cancel'), // '취소'
              ),
              TextButton(
                onPressed: () => Navigator.pop(context, true),
                style: TextButton.styleFrom(
                  backgroundColor: Colors.black,
                  foregroundColor: Colors.white,
                ),
                child: const Text('Leave'), // '나가기'
              ),
            ],
          );
        },
      );

      if (confirm != true) {
        return false;
      }
    }

    // userList => false
    final userRef = _roomRef.child('userList').child('_$mySeq');
    await userRef.set(false);

    if (!mounted) return false;
    Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (_) => const MainPage()), (route) => false);
    return false;
  }

  /// Build participant card (참가자 카드)
  Widget _buildScoreItem(Map<String, dynamic> user) {
    final userSeq = user['user_seq'].toString();
    final tempScore = user['score'] ?? 0;
    final score = (scoreOpenRange == 'ALL') ? tempScore : '-';
    final nickname = user['nickname'] ?? 'User'; // '유저'

    final bool isActive = _userListMap[userSeq] ?? true;
    final hasExited = !isActive;

    return GestureDetector(
      onTap: () => _onTapUser(user),
      child: Container(
        width: 60,
        margin: const EdgeInsets.all(4),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            hasExited
                ? Text(
                    'X', 
                    // 'X'
                    style: const TextStyle(fontSize: 20, color: Colors.redAccent, fontWeight: FontWeight.bold),
                  )
                : Text(
                    '$score',
                    style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                  ),
            const SizedBox(height: 2),
            Container(
              width: 30,
              height: 30,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                border: Border.all(color: hasExited ? Colors.redAccent : Colors.black),
              ),
              child: hasExited
                  ? const Center(
                      child: Text(
                        'X',
                        style: TextStyle(fontSize: 14, color: Colors.redAccent, fontWeight: FontWeight.bold),
                      ),
                    )
                  : ClipOval(
                      child: Image.network(
                        '${Config.baseUrl}/images${user['profile_img']}',
                        fit: BoxFit.cover,
                        errorBuilder: (_, __, ___) =>
                            const Center(child: Text('ERR', style: TextStyle(fontSize: 8))),
                      ),
                    ),
            ),
            const SizedBox(height: 2),
            Text(
              nickname,
              style: TextStyle(fontSize: 11, color: hasExited ? Colors.redAccent : Colors.black),
              overflow: TextOverflow.ellipsis,
              maxLines: 1,
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _onTapUser(Map<String, dynamic> userData) async {
    if (myParticipantType == 'ADMIN') { 
      // If admin (점수 수정 가능)
      await showDialog(
        context: context,
        builder: (_) => ScoreEditDialog(
          roomSeq: widget.roomSeq,
          roomType: 'PRIVATE',
          userData: userData,
        ),
      );
    } else {
      // Normal user info (일반 유저 정보)
      await showDialog(
        context: context,
        builder: (_) => UserInfoBasicDialog(userData: userData),
      );
    }
  }

  // (★) Format countdown display (카운트다운 표시용)
  String _formatDuration(Duration d) {
    final hh = d.inHours.toString().padLeft(2, '0');
    final mm = d.inMinutes.remainder(60).toString().padLeft(2, '0');
    final ss = d.inSeconds.remainder(60).toString().padLeft(2, '0');
    return '$hh:$mm:$ss';
  }

  @override
  Widget build(BuildContext context) {
    final countdownStr = _formatDuration(_remaining);

    return WillPopScope(
      onWillPop: _onWillPop,
      child: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          backgroundColor: Colors.black,
          elevation: 0,
          leading: IconButton(
            icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
            onPressed: () => _onWillPop(),
          ),
          title: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Expanded(
                child: Text(
                  roomTitle.isNotEmpty ? roomTitle : 'Room Title', // '방 제목'
                  style: const TextStyle(color: Colors.white),
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
              const SizedBox(width: 4),
              // Right: countdown (남은시간)
              Text(
                countdownStr, // e.g. "10:23"
                style: const TextStyle(color: Colors.white),
              ),
            ],
          ),
          actions: [
            if (roomMasterYn == 'Y')
              TextButton(
                onPressed: _requestFinish,
                child: const Text(
                  'End Game', // '게임종료'
                  style: TextStyle(color: Colors.white),
                ),
              ),
          ],
        ),
        body: _isLoading
            ? const Center(child: CircularProgressIndicator())
            : Column(
                children: [
                  // My score (내 점수)
                  Container(
                    width: double.infinity,
                    padding: const EdgeInsets.symmetric(vertical: 16),
                    child: Column(
                      children: [
                        const Text(
                          'My Score', // '내 점수'
                          style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
                        ),
                        const SizedBox(height: 4),
                        Text(
                          '$myScore',
                          style: const TextStyle(fontSize: 36, fontWeight: FontWeight.bold),
                        ),
                      ],
                    ),
                  ),
                  const Divider(height: 1, color: Colors.black),
                  Expanded(
                    child: SingleChildScrollView(
                      padding: const EdgeInsets.all(8),
                      child: Wrap(
                        spacing: 8,
                        runSpacing: 8,
                        children: _scoreList.map(_buildScoreItem).toList(),
                      ),
                    ),
                  ),
                ],
              ),
        bottomNavigationBar: AdBannerWidget(),
      ),
    );
  }
}
