import 'package:flutter/material.dart';

import 'package:asciineverdie/data/game_text_l10n.dart' as game_l10n;
import 'package:asciineverdie/l10n/app_localizations.dart';
import 'package:asciineverdie/src/core/audio/audio_service.dart';
import 'package:asciineverdie/src/core/engine/ad_service.dart';
import 'package:asciineverdie/src/core/engine/debug_settings_service.dart';
import 'package:asciineverdie/src/core/engine/iap_service.dart';
import 'package:asciineverdie/src/app_theme.dart';
import 'package:asciineverdie/src/splash_screen.dart';
import 'package:asciineverdie/src/core/engine/game_mutations.dart';
import 'package:asciineverdie/src/core/engine/progress_service.dart';
import 'package:asciineverdie/src/core/engine/reward_service.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/pq_config.dart';
import 'package:asciineverdie/src/core/notification/notification_service.dart';
import 'package:asciineverdie/src/core/storage/save_manager.dart';
import 'package:asciineverdie/src/core/storage/save_repository.dart';
import 'package:asciineverdie/src/core/storage/hall_of_fame_storage.dart';
import 'package:asciineverdie/src/core/storage/settings_repository.dart';
import 'package:asciineverdie/src/core/model/hall_of_fame.dart';
import 'package:asciineverdie/src/features/arena/arena_screen.dart';
import 'package:asciineverdie/src/features/front/front_screen.dart';
import 'package:asciineverdie/src/features/front/save_picker_dialog.dart';
import 'package:asciineverdie/src/features/game/game_play_screen.dart';
import 'package:asciineverdie/src/features/game/game_session_controller.dart';
import 'package:asciineverdie/src/features/game/widgets/notification_overlay.dart';
import 'package:asciineverdie/src/features/hall_of_fame/hall_of_fame_screen.dart';
import 'package:asciineverdie/src/features/new_character/new_character_screen.dart';
import 'package:asciineverdie/src/features/settings/settings_screen.dart';

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

  @override
  State<AskiiNeverDieApp> createState() => _AskiiNeverDieAppState();
}

/// 저장된 게임 미리보기 정보
class SavedGamePreview {
  const SavedGamePreview({
    required this.characterName,
    required this.level,
    required this.actName,
  });

  final String characterName;
  final int level;
  final String actName;
}

class _AskiiNeverDieAppState extends State<AskiiNeverDieApp>
    with WidgetsBindingObserver {
  late final GameSessionController _controller;
  late final NotificationService _notificationService;
  late final SettingsRepository _settingsRepository;
  late final AudioService _audioService;
  late final HallOfFameStorage _hallOfFameStorage;
  final RouteObserver<ModalRoute<void>> _routeObserver =
      RouteObserver<ModalRoute<void>>();
  bool _isCheckingSave = true;
  bool _hasSave = false;
  SavedGamePreview? _savedGamePreview;
  HallOfFame _hallOfFame = HallOfFame.empty();
  Locale? _locale; // 사용자 선택 로케일 (null이면 시스템 기본값)
  bool _isAdRemovalPurchased = false;
  String? _removeAdsPrice;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    const config = PqConfig();
    final mutations = GameMutations(config);
    final rewards = RewardService(mutations, config);

    _controller = GameSessionController(
      progressService: ProgressService(
        config: config,
        mutations: mutations,
        rewards: rewards,
      ),
      saveManager: SaveManager(SaveRepository()),
    );
    _notificationService = NotificationService();
    _settingsRepository = SettingsRepository();
    _audioService = AudioService(settingsRepository: _settingsRepository);
    _hallOfFameStorage = HallOfFameStorage();

    // 초기 설정 및 오디오 서비스 로드
    _loadSettings();
    _audioService.init();
    // IAP 서비스 초기화
    _initIAP();
    // 세이브 파일 존재 여부 확인
    _checkForExistingSave();
    // 명예의 전당 로드
    _loadHallOfFame();
  }

  /// IAP 및 광고 서비스 초기화
  Future<void> _initIAP() async {
    await IAPService.instance.initialize();
    await AdService.instance.initialize();
    _updateIAPState();
  }

  /// IAP 상태 업데이트 (구매 여부, 가격)
  void _updateIAPState() {
    if (mounted) {
      setState(() {
        _isAdRemovalPurchased = IAPService.instance.isAdRemovalPurchased;
        _removeAdsPrice = IAPService.instance.isStoreAvailable
            ? IAPService.instance.removeAdsPrice
            : null;
      });
    }
  }

  /// 명예의 전당 로드
  Future<void> _loadHallOfFame() async {
    final hallOfFame = await _hallOfFameStorage.load();
    if (mounted) {
      setState(() {
        _hallOfFame = hallOfFame;
      });
    }
  }

  /// 저장된 설정 불러오기
  Future<void> _loadSettings() async {
    // 디버그 설정 먼저 초기화 (광고/IAP 시뮬레이션 설정 동기화)
    await DebugSettingsService.instance.initialize();

    final localeCode = await _settingsRepository.loadLocale();
    if (mounted) {
      setState(() {
        // 저장된 로케일이 있으면 적용
        if (localeCode != null) {
          _locale = Locale(localeCode);
          game_l10n.setGameLocale(localeCode);
        }
      });
    }
  }

  /// 로케일 변경
  void _changeLocale(String localeCode) {
    setState(() {
      _locale = Locale(localeCode);
    });
  }

  /// 세이브 파일 존재 여부 확인 및 미리보기 정보 로드
  Future<void> _checkForExistingSave() async {
    final exists = await _controller.saveManager.saveExists();
    SavedGamePreview? preview;

    if (exists) {
      // 세이브 파일에서 미리보기 정보 추출
      final (outcome, state, _, _) = await _controller.saveManager.loadState();
      if (outcome.success && state != null) {
        final actName = _getActName(state.progress.plotStageCount);
        preview = SavedGamePreview(
          characterName: state.traits.name,
          level: state.traits.level,
          actName: actName,
        );
      }
    }

    if (mounted) {
      setState(() {
        _hasSave = exists;
        _savedGamePreview = preview;
        _isCheckingSave = false;
      });
      // 세이브 확인 완료 후 타이틀 BGM 재생 (앱이 포그라운드일 때만)
      final lifecycleState = WidgetsBinding.instance.lifecycleState;
      if (lifecycleState == AppLifecycleState.resumed) {
        _audioService.playBgm('title');
      }
    }
  }

  /// plotStageCount를 Act 이름으로 변환
  String _getActName(int plotStageCount) {
    return switch (plotStageCount) {
      1 => 'Prologue',
      2 => 'Act I',
      3 => 'Act II',
      4 => 'Act III',
      5 => 'Act IV',
      6 => 'Act V',
      _ => 'Act V',
    };
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _controller.dispose();
    _notificationService.dispose();
    _audioService.dispose();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // 앱이 백그라운드로 내려가면 오디오 정지
    if (state == AppLifecycleState.paused ||
        state == AppLifecycleState.inactive) {
      _audioService.pauseAll();
    } else if (state == AppLifecycleState.resumed) {
      _audioService.resumeAll().then((_) {
        // 복귀 후 BGM이 없고 시작 화면이면 타이틀 BGM 재생
        if (_audioService.currentBgm == null && !_isCheckingSave) {
          _audioService.playBgm('title');
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ASCII NEVER DIE',
      debugShowCheckedModeBanner: false,
      localizationsDelegates: L10n.localizationsDelegates,
      supportedLocales: L10n.supportedLocales,
      locale: _locale, // 사용자 선택 로케일 (null이면 시스템 기본값)
      theme: buildAppTheme(),
      navigatorObservers: [_routeObserver],
      builder: (context, child) {
        // 현재 로케일을 게임 텍스트 l10n 시스템에 동기화
        final locale = Localizations.localeOf(context);
        game_l10n.setGameLocale(locale.languageCode);
        return child ?? const SizedBox.shrink();
      },
      home: NotificationOverlay(
        notificationService: _notificationService,
        child: _buildHomeScreen(),
      ),
    );
  }

  /// 홈 화면 결정: 세이브 확인 중 → 스플래시, 그 외 → 프론트
  Widget _buildHomeScreen() {
    // 세이브 확인 중이면 로딩 스플래시 표시
    if (_isCheckingSave) {
      return const SplashScreen();
    }

    return FrontScreen(
      onNewCharacter: _navigateToNewCharacter,
      onLoadSave: _loadSave,
      onHallOfFame: _navigateToHallOfFame,
      onLocalArena: _navigateToArena,
      onSettings: _showSettings,
      onPurchaseRemoveAds: _purchaseRemoveAds,
      onRestorePurchase: _restorePurchase,
      hasSaveFile: _hasSave,
      savedGamePreview: _savedGamePreview,
      hallOfFameCount: _hallOfFame.count,
      isAdRemovalPurchased: _isAdRemovalPurchased,
      removeAdsPrice: _removeAdsPrice,
      routeObserver: _routeObserver,
      onRefresh: () {
        _checkForExistingSave();
        _loadHallOfFame();
        _updateIAPState();
      },
    );
  }

  void _navigateToNewCharacter(BuildContext context) {
    Navigator.of(context)
        .push(
          MaterialPageRoute<void>(
            builder: (context) => NewCharacterScreen(
              onCharacterCreated: (initialState, {bool testMode = false}) {
                _startGame(context, initialState, testMode: testMode);
              },
            ),
          ),
        )
        .then((_) {
          // 새 게임 후 돌아오면 세이브 정보 및 명예의 전당 갱신
          _checkForExistingSave();
          _loadHallOfFame();
        });
  }

  Future<void> _loadSave(BuildContext context) async {
    // 저장 파일 목록 조회
    final saves = await _controller.saveManager.listSaves();

    if (!context.mounted) return;

    String? selectedFileName;

    if (saves.isEmpty) {
      // 저장 파일이 없으면 안내 메시지
      _notificationService.showInfo(L10n.of(context).noSavedGames);
      return;
    } else if (saves.length == 1) {
      // 파일이 하나면 바로 선택
      selectedFileName = saves.first.fileName;
    } else {
      // 여러 개면 다이얼로그 표시
      selectedFileName = await SavePickerDialog.show(context, saves);
    }

    if (selectedFileName == null || !context.mounted) return;

    // 선택된 파일 로드 (치트 모드는 저장된 상태에서 복원)
    await _controller.loadAndStart(fileName: selectedFileName);

    if (_controller.status == GameSessionStatus.running) {
      if (context.mounted) {
        _navigateToGame(context);
      }
    } else if (_controller.status == GameSessionStatus.error &&
        context.mounted) {
      _notificationService.showWarning(
        L10n.of(context).loadError(_controller.error ?? 'Unknown error'),
      );
    }
  }

  Future<void> _startGame(
    BuildContext context,
    GameState initialState, {
    bool testMode = false,
  }) async {
    await _controller.startNew(initialState, cheatsEnabled: testMode);

    if (context.mounted) {
      // NewCharacterScreen을 pop하고 GamePlayScreen으로 이동
      Navigator.of(context).pushReplacement(
        MaterialPageRoute<void>(
          builder: (context) => GamePlayScreen(
            controller: _controller,
            audioService: _audioService,
            forceCarouselLayout: testMode,
          ),
        ),
      );
    }
  }

  void _navigateToGame(BuildContext context) {
    Navigator.of(context)
        .push(
          MaterialPageRoute<void>(
            builder: (context) => GamePlayScreen(
              controller: _controller,
              audioService: _audioService,
              // 디버그 모드로 저장된 게임 로드 시 캐로셀 레이아웃 강제
              forceCarouselLayout: _controller.cheatsEnabled,
            ),
          ),
        )
        .then((_) {
          // 게임에서 돌아오면 세이브 정보 및 명예의 전당 갱신
          _checkForExistingSave();
          _loadHallOfFame();
        });
  }

  /// Phase 10: 명예의 전당 화면으로 이동
  void _navigateToHallOfFame(BuildContext context) {
    Navigator.of(context)
        .push(
          MaterialPageRoute<void>(
            builder: (context) => const HallOfFameScreen(),
          ),
        )
        .then((_) {
          // 명예의 전당에서 돌아오면 명예의 전당 갱신 및 타이틀 BGM 재생
          _loadHallOfFame();
          _audioService.playBgm('title');
        });
  }

  /// 로컬 아레나 화면으로 이동
  void _navigateToArena(BuildContext context) {
    Navigator.of(context)
        .push(
          MaterialPageRoute<void>(builder: (context) => const ArenaScreen()),
        )
        .then((_) {
          // 아레나에서 돌아오면 명예의 전당 다시 로드 및 타이틀 BGM 재생
          _loadHallOfFame();
          _audioService.playBgm('title');
        });
  }

  /// 설정 화면 표시 (모달 바텀시트)
  void _showSettings(BuildContext context) {
    SettingsScreen.show(
      context,
      settingsRepository: _settingsRepository,
      onLocaleChange: _changeLocale,
      onBgmVolumeChange: _audioService.setBgmVolume,
      onSfxVolumeChange: _audioService.setSfxVolume,
    );
  }

  /// 광고 제거 구매
  Future<void> _purchaseRemoveAds(BuildContext context) async {
    final result = await IAPService.instance.purchaseRemoveAds();
    _updateIAPState();

    if (!context.mounted) return;

    switch (result) {
      case IAPResult.success:
      case IAPResult.debugSimulated:
        _notificationService.showInfo(game_l10n.iapPurchaseSuccess);
      case IAPResult.alreadyPurchased:
        _notificationService.showInfo(game_l10n.iapAlreadyPurchased);
      case IAPResult.cancelled:
        // 취소는 무시
        break;
      case IAPResult.storeUnavailable:
        _notificationService.showWarning(game_l10n.iapStoreUnavailable);
      case IAPResult.productNotFound:
      case IAPResult.failed:
        _notificationService.showWarning(game_l10n.iapPurchaseFailed);
    }
  }

  /// 구매 복원
  Future<void> _restorePurchase(BuildContext context) async {
    final result = await IAPService.instance.restorePurchases();
    _updateIAPState();

    if (!context.mounted) return;

    switch (result) {
      case IAPResult.success:
      case IAPResult.debugSimulated:
        if (_isAdRemovalPurchased) {
          _notificationService.showInfo(game_l10n.iapRestoreSuccess);
        } else {
          _notificationService.showInfo(game_l10n.iapRestoreFailed);
        }
      case IAPResult.storeUnavailable:
        _notificationService.showWarning(game_l10n.iapStoreUnavailable);
      case IAPResult.alreadyPurchased:
      case IAPResult.cancelled:
      case IAPResult.productNotFound:
      case IAPResult.failed:
        _notificationService.showWarning(game_l10n.iapRestoreFailed);
    }
  }
}
