// packages/feature_game_sudoku/lib/screens/sudoku_lobby_screen.dart
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

// [C] 서비스 import
import 'package:service_api/service_api.dart';
// [A] 공통 셸(Shell) 위젯 import
import 'package:feature_common/feature_common.dart'; 
// [B] 같은 패키지 내의 화면/모델 import
import 'game_screen.dart';
import '../models/game_level.dart'; // 👈 스도쿠 전용 레벨

class SudokuLobbyScreen extends StatefulWidget {
  const SudokuLobbyScreen({ super.key });

  @override
  State<SudokuLobbyScreen> createState() => _SudokuLobbyScreenState();
}

class _SudokuLobbyScreenState extends State<SudokuLobbyScreen> {
  int _maxUnlockedLevel = 1; 
  Map<int, (int, int)> _rankHistory = {};
  // ❌ String? _userName; (SessionNotifier가 관리)
  late String _selectedThemeName;
  bool _isLoading = false;
  
  // 🔽 [수정] SessionNotifier를 사용하기 위해 IdentityService 대신 추가
  late final SessionNotifier _sessionNotifier;
  final PuzzleService _puzzleService = PuzzleService();
  final IdentityService _identityService = IdentityService(); // 👈 (save/load progress를 위해 유지)

  @override
  void initState() {
    super.initState();
    _selectedThemeName = AppThemes.random;
    
    // 🔽 [수정] initState에서 SessionNotifier를 read
    _sessionNotifier = context.read<SessionNotifier>();

    // 🔽 [수정] _loadProgress가 랭킹까지 모두 새로고침 (최초 1회)
    _loadProgress(forceRefreshRanks: true);
  }

  /// 🔽 [수정] _loadProgress 메서드 (SessionNotifier 사용 및 로직 분리)
  Future<void> _loadProgress({bool forceRefreshRanks = false}) async {
    // 1. (가벼움) 레벨 정보 새로고침
    final maxLevel = await _identityService.getMaxUnlockedLevel();
    if (mounted) { setState(() { _maxUnlockedLevel = maxLevel; }); }

    // 2. (무거움) 랭킹 정보 새로고침 (필요할 때만)
    if (!forceRefreshRanks) return;

    // 🔽 [수정] _sessionNotifier에서 유저 이름을 가져옴
    final String? myName = _sessionNotifier.session?.userName;
    if (myName == null) return; // 게스트이거나 아직 이름 저장을 안 함
    
    try {
      final Map<int, int> oldRankMap = await _identityService.getLastSavedRankMap();
      List<Future<List<GameRankDto>>> rankFutures = [];
      for (final level in AppLevels.allLevels) {
        rankFutures.add(_puzzleService.fetchRanks('SUDOKU', level.contextId));
      }
      final List<List<GameRankDto>> allRankResults = await Future.wait(rankFutures);
      Map<int, int> newRankMapForStorage = {};
      Map<int, (int, int)> newRankHistoryForState = {};
      for (int i = 0; i < AppLevels.allLevels.length; i++) {
        final level = AppLevels.allLevels[i];
        final currentRanks = allRankResults[i];
        final int levelIndex = level.levelIndex;
        final int oldRank = oldRankMap[levelIndex] ?? 0;
        int currentRank = 0;
        int myRankIndex = currentRanks.indexWhere((r) => r.playerName == myName);
        if (myRankIndex != -1) { currentRank = myRankIndex + 1; }
        newRankMapForStorage[levelIndex] = currentRank;
        newRankHistoryForState[levelIndex] = (oldRank, currentRank);
      }
      await _identityService.saveLastRankMap(newRankMapForStorage);
      if (mounted) { setState(() { _rankHistory = newRankHistoryForState; }); }
      log("모든 레벨 랭킹 변동 확인 완료. (유저: $myName)");
    } catch (e) {
      log("SudokuLobbyScreen: 랭킹 확인 실패: $e");
    }
  }

  /// 🔽 [수정] _startGame 메서드 (SessionNotifier 사용)
  Future<void> _startGame(GameLevel level) async {
    setState(() { _isLoading = true; });
    
    try {
      // 1. [수정] SessionNotifier에서 유저 정보 가져오기
      final session = _sessionNotifier.session;
      if (session == null) {
        throw Exception("세션이 로드되지 않았습니다.");
      }
      
      final String difficulty = level.levelIndex.toString();
      final SudokuGameDto gameData = await _puzzleService.startGame(difficulty);
      
      final String userId = session.userId;
      final String? userName = session.userName; 
      
      if (mounted) {
        await Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => GameScreen( 
              gameData: gameData,
              themeName: _selectedThemeName,
              userId: userId,
              userName: userName,
              levelIndex: level.levelIndex,
            ),
          ),
        );
        
        // 🔽 [핵심 수정]
        // 랭킹(forceRefreshRanks: true)은 새로고침하지 않고,
        // 레벨 잠금 상태(forceRefreshRanks: false)만 새로고침합니다.
        _loadProgress(forceRefreshRanks: false);
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('게임 로딩 실패: $e')),
        );
      }
    } finally {
      if (mounted) {
        setState(() { _isLoading = false; });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    // 🔽 [수정] ThemeNotifier와 SessionNotifier를 모두 watch
    context.watch<ThemeNotifier>(); // 테마 감지
    context.watch<SessionNotifier>(); // 👈 세션 변경(로그인/로그아웃) 감지
    
    final bool allLevelsUnlocked = _maxUnlockedLevel >= 99;
    final theme = Theme.of(context);

    // [A] feature_common의 CommonGameShell을 사용
    return CommonGameShell(
      title: '스도쿠 게임', // 셸의 AppBar에 표시될 제목
      
      // 🔽 [수정] 랭킹 버튼 클릭 시 실행될 함수를 주입
      onRankingPressed: () {
        
        // 1. 스도쿠 레벨(AppLevels)을 공통 모델(GameDifficulty)로 변환
        final List<GameDifficulty> sudokuDifficulties = AppLevels.allLevels
            .map((level) => GameDifficulty(
                  name: level.name,
                  contextId: level.contextId,
                ))
            .toList();

        // 2. 공통 랭킹 화면(RankingScreen)에 주입하며 호출
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => RankingScreen(
              gameType: 'SUDOKU', // 👈 이 게임은 스도쿠
              difficulties: sudokuDifficulties, // 👈 스도쿠 난이도 목록
              initialDifficultyName: AppLevels.getLevel(_maxUnlockedLevel).name,
            ),
          ),
        );
      },

      // 🔽 셸의 'body'에 스도쿠 레벨 목록을 전달
      body: LayoutBuilder(
        builder: (context, constraints) {
          const double maxContentRatio = 0.6;
          final double constrainedWidth = (constraints.maxHeight * maxContentRatio) > 500
                                          ? 500 : (constraints.maxHeight * maxContentRatio);
          return Center(
            child: ConstrainedBox(
              constraints: BoxConstraints(maxWidth: constrainedWidth),
              child: Column(
                children: [
                  // 테마 선택 Dropdown
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        const Text("테마: ", style: TextStyle(fontSize: 18)),
                        DropdownButton<String>(
                          value: _selectedThemeName,
                          items: AppThemes.selectableThemeNames.map((themeName) {
                            return DropdownMenuItem<String>(
                              value: themeName,
                              child: Text(themeName, style: const TextStyle(fontSize: 20)),
                            );
                          }).toList(),
                          onChanged: (themeName) {
                            if (themeName != null) {
                              setState(() { _selectedThemeName = themeName; });
                            }
                          },
                        ),
                      ],
                    ),
                  ),
                  // 레벨 목록 ListView
                  Expanded(
                    // 🔽 [수정] RefreshIndicator 추가 (당겨서 랭킹 새로고침)
                    child: RefreshIndicator(
                      onRefresh: () => _loadProgress(forceRefreshRanks: true),
                      child: ListView.builder(
                        itemCount: AppLevels.allLevels.length,
                        itemBuilder: (context, index) {
                          // ... (이하 ListTile 로직은 모두 동일)
                          final GameLevel level = AppLevels.allLevels[index];
                          final bool isUnlocked = allLevelsUnlocked || level.levelIndex <= _maxUnlockedLevel;
                          final (int oldRank, int currentRank) = _rankHistory[level.levelIndex] ?? (0, 0);
                          Widget? trailingWidget = isUnlocked ? const Icon(Icons.play_arrow_rounded) : null;
                          String? subtitleText;
                          Color? subtitleColor;
                          
                          if (currentRank > 0) {
                            String rankStr = "${currentRank}위";
                            if (oldRank > 0) {
                              int change = oldRank - currentRank;
                              if (change > 0) {
                                subtitleText = "$rankStr (▲ $change)";
                                subtitleColor = Colors.green;
                                trailingWidget = const Icon(Icons.arrow_circle_up_rounded, color: Colors.green, size: 28);
                              } else if (change < 0) {
                                subtitleText = "$rankStr (▼ ${change.abs()})";
                                subtitleColor = Colors.red;
                                trailingWidget = const Icon(Icons.arrow_circle_down_rounded, color: Colors.red, size: 28);
                              } else {
                                subtitleText = "$rankStr (유지)";
                                subtitleColor = Colors.grey;
                                trailingWidget = const Icon(Icons.check_circle_outline_rounded, color: Colors.grey, size: 28);
                              }
                            } else {
                              subtitleText = "$rankStr (신규 진입)";
                              subtitleColor = Colors.blue;
                              trailingWidget = const Icon(Icons.new_releases_rounded, color: Colors.blue, size: 28);
                            }
                          } else {
                            if (oldRank > 0) {
                              subtitleText = "랭킹 이탈 (이전 ${oldRank}위)";
                              subtitleColor = Colors.orange;
                              trailingWidget = const Icon(Icons.warning_amber_rounded, color: Colors.orange, size: 28);
                            }
                          }
                          
                          return Card(
                            margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
                            child: ListTile(
                              leading: Icon(
                                isUnlocked ? Icons.lock_open_rounded : Icons.lock_rounded,
                                color: isUnlocked ? theme.primaryColor : Colors.grey,
                              ),
                              title: Text(level.name, style: TextStyle(
                                fontSize: 18,
                                fontWeight: isUnlocked ? FontWeight.bold : FontWeight.normal,
                                color: isUnlocked ? theme.textTheme.bodyLarge?.color : Colors.grey,
                              )),
                              subtitle: subtitleText != null
                                ? Text(subtitleText, style: TextStyle(color: subtitleColor, fontWeight: FontWeight.bold))
                                : null,
                              trailing: trailingWidget, 
                              onTap: isUnlocked && !_isLoading
                                  ? () => _startGame(level)
                                  : null,
                            ),
                          );
                        },
                      ),
                    ),
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}