import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:provider/provider.dart';
import 'package:permission_handler/permission_handler.dart' as permission;
import 'dart:io' show Platform;

import '../services/sms_scanner.dart';
import '../services/ad_service.dart';
import '../services/sms_scan/subscription_converter.dart';
import '../services/sms_scan/subscription_filter.dart';
import '../services/sms_scan/sms_scan_result.dart';
import '../models/subscription.dart';
import '../models/payment_card_suggestion.dart';
import '../providers/subscription_provider.dart';
import '../providers/navigation_provider.dart';
import '../providers/category_provider.dart';
import '../providers/payment_card_provider.dart';
import '../l10n/app_localizations.dart';
import '../utils/logger.dart';

class SmsScanController extends ChangeNotifier {
  // 상태 관리
  bool _isLoading = false;
  bool get isLoading => _isLoading;

  String? _errorMessage;
  String? get errorMessage => _errorMessage;

  List<Subscription> _scannedSubscriptions = [];
  List<Subscription> get scannedSubscriptions => _scannedSubscriptions;
  PaymentCardSuggestion? _currentSuggestion;
  PaymentCardSuggestion? get currentSuggestion => _currentSuggestion;
  bool _shouldSuggestCardCreation = false;
  bool get shouldSuggestCardCreation => _shouldSuggestCardCreation;

  int _currentIndex = 0;
  int get currentIndex => _currentIndex;

  String? _selectedCategoryId;
  String? get selectedCategoryId => _selectedCategoryId;
  String? _selectedPaymentCardId;
  String? get selectedPaymentCardId => _selectedPaymentCardId;

  final TextEditingController websiteUrlController = TextEditingController();
  final TextEditingController serviceNameController = TextEditingController();

  // 의존성
  final SmsScanner _smsScanner = SmsScanner();
  final SubscriptionConverter _converter = SubscriptionConverter();
  final SubscriptionFilter _filter = SubscriptionFilter();
  final AdService _adService = AdService();
  bool _forceServiceNameEditing = false;
  bool get isServiceNameEditable => _forceServiceNameEditing;

  @override
  void dispose() {
    serviceNameController.dispose();
    websiteUrlController.dispose();
    super.dispose();
  }

  void setSelectedCategoryId(String? categoryId) {
    _selectedCategoryId = categoryId;
    notifyListeners();
  }

  void setSelectedPaymentCardId(String? paymentCardId) {
    _selectedPaymentCardId = paymentCardId;
    if (paymentCardId != null) {
      _shouldSuggestCardCreation = false;
    }
    notifyListeners();
  }

  void resetWebsiteUrl() {
    websiteUrlController.text = '';
    serviceNameController.text = '';
  }

  void updateCurrentServiceName(BuildContext context, String value) {
    if (_currentIndex >= _scannedSubscriptions.length) return;
    final trimmed = value.trim();
    final unknownLabel = _unknownServiceLabel(context);
    final updated = _scannedSubscriptions[_currentIndex]
        .copyWith(serviceName: trimmed.isEmpty ? unknownLabel : trimmed);
    _scannedSubscriptions[_currentIndex] = updated;
    notifyListeners();
  }

  /// SMS 스캔 시작 (전면 광고 표시 후 스캔 진행)
  Future<void> startScan(BuildContext context) async {
    if (_isLoading) return;

    // 웹/비지원 플랫폼은 바로 스캔
    if (kIsWeb || !(Platform.isAndroid || Platform.isIOS)) {
      await scanSms(context);
      return;
    }

    // 광고 표시 (완료까지 대기)
    // 광고 실패해도 스캔 진행 (사용자 경험 우선)
    await _adService.showInterstitialAd(context);

    if (!context.mounted) return;

    // 광고 완료 후 SMS 스캔 실행
    await scanSms(context);
  }

  Future<void> scanSms(BuildContext context) async {
    _isLoading = true;
    _errorMessage = null;
    _scannedSubscriptions = [];
    _currentIndex = 0;
    notifyListeners();

    await _performSmsScan(context);
  }

  /// 실제 SMS 스캔 수행 (로딩 상태는 이미 설정되어 있음)
  Future<void> _performSmsScan(BuildContext context) async {
    try {
      // Android에서 SMS 권한 확인 및 요청
      final ctx = context;
      if (!kIsWeb) {
        final smsStatus = await permission.Permission.sms.status;
        if (!smsStatus.isGranted) {
          if (smsStatus.isPermanentlyDenied) {
            // 설정 유도 다이얼로그 표시
            if (!ctx.mounted) return;
            await _showPermissionSettingsDialog(ctx);
            _isLoading = false;
            notifyListeners();
            return;
          }

          final req = await permission.Permission.sms.request();
          if (!ctx.mounted) return;
          if (!req.isGranted) {
            // 거부됨: 안내 후 종료
            if (!ctx.mounted) return;
            _errorMessage = AppLocalizations.of(ctx).smsPermissionRequired;
            _isLoading = false;
            notifyListeners();
            return;
          }
        }
      }

      // SMS 스캔 실행
      Log.i('SMS 스캔 시작');
      final List<SmsScanResult> scanResults =
          await _smsScanner.scanForSubscriptions();
      Log.d('스캔된 구독: ${scanResults.length}개');

      if (scanResults.isNotEmpty) {
        Log.d(
            '첫 번째 구독: ${scanResults[0].model.serviceName}, 반복 횟수: ${scanResults[0].model.repeatCount}');
      }

      if (!context.mounted) return;

      if (scanResults.isEmpty) {
        Log.i('스캔된 구독이 없음');
        _errorMessage = AppLocalizations.of(context).subscriptionNotFound;
        _isLoading = false;
        notifyListeners();
        return;
      }

      // SubscriptionModel을 Subscription으로 변환
      final scannedSubscriptions =
          _converter.convertResultsToSubscriptions(scanResults);

      // 2회 이상 반복 결제된 구독만 필터링
      final repeatSubscriptions =
          _filter.filterByRepeatCount(scannedSubscriptions, 2);
      Log.d('반복 결제된 구독: ${repeatSubscriptions.length}개');

      if (repeatSubscriptions.isNotEmpty) {
        Log.d(
            '첫 번째 반복 구독: ${repeatSubscriptions[0].serviceName}, 반복 횟수: ${repeatSubscriptions[0].repeatCount}');
      }

      if (repeatSubscriptions.isEmpty) {
        Log.i('반복 결제된 구독이 없음');
        _errorMessage = AppLocalizations.of(context).repeatSubscriptionNotFound;
        _isLoading = false;
        notifyListeners();
        return;
      }

      // 구독 목록 가져오기
      final provider =
          Provider.of<SubscriptionProvider>(context, listen: false);
      final existingSubscriptions = provider.subscriptions;
      Log.d('기존 구독: ${existingSubscriptions.length}개');

      // 중복 구독 필터링
      final filteredSubscriptions =
          _filter.filterDuplicates(repeatSubscriptions, existingSubscriptions);
      Log.d('중복 제거 후 구독: ${filteredSubscriptions.length}개');

      if (filteredSubscriptions.isNotEmpty) {
        Log.d(
            '첫 번째 필터링된 구독: ${filteredSubscriptions[0].serviceName}, 반복 횟수: ${filteredSubscriptions[0].repeatCount}');
      }

      // 중복 제거 후 신규 구독이 없는 경우
      if (filteredSubscriptions.isEmpty) {
        Log.i('중복 제거 후 신규 구독이 없음');
        _isLoading = false;
        notifyListeners();
        return;
      }

      _scannedSubscriptions = filteredSubscriptions;
      _isLoading = false;
      websiteUrlController.text = '';
      _currentSuggestion = null;
      _prepareCurrentSelection(context);
      notifyListeners();
    } catch (e) {
      Log.e('SMS 스캔 중 오류 발생', e);
      if (context.mounted) {
        _errorMessage =
            AppLocalizations.of(context).smsScanErrorWithMessage(e.toString());
        _isLoading = false;
        notifyListeners();
      }
    }
  }

  Future<void> _showPermissionSettingsDialog(BuildContext context) async {
    final loc = AppLocalizations.of(context);
    await showDialog(
      context: context,
      builder: (_) => AlertDialog(
        title: Text(loc.smsPermissionRequired),
        content: Text(loc.permanentlyDeniedMessage),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: Text(loc.cancel),
          ),
          TextButton(
            onPressed: () async {
              await permission.openAppSettings();
              if (context.mounted) Navigator.of(context).pop();
            },
            child: Text(loc.openSettings),
          ),
        ],
      ),
    );
  }

  Future<void> addCurrentSubscription(BuildContext context) async {
    if (_currentIndex >= _scannedSubscriptions.length) return;

    final subscription = _scannedSubscriptions[_currentIndex];
    final inputName = serviceNameController.text.trim();
    final resolvedServiceName =
        inputName.isNotEmpty ? inputName : subscription.serviceName;

    try {
      final provider =
          Provider.of<SubscriptionProvider>(context, listen: false);
      final categoryProvider =
          Provider.of<CategoryProvider>(context, listen: false);
      final paymentCardProvider =
          Provider.of<PaymentCardProvider>(context, listen: false);

      final finalCategoryId = _selectedCategoryId ??
          subscription.category ??
          getDefaultCategoryId(categoryProvider);
      final finalPaymentCardId =
          _selectedPaymentCardId ?? paymentCardProvider.defaultCard?.id;

      // websiteUrl 처리
      final websiteUrl = websiteUrlController.text.trim().isNotEmpty
          ? websiteUrlController.text.trim()
          : subscription.websiteUrl;

      Log.d(
          '구독 추가 시도: ${subscription.serviceName}, 카테고리: $finalCategoryId, URL: $websiteUrl');

      // addSubscription 호출
      await provider.addSubscription(
        serviceName: resolvedServiceName,
        monthlyCost: subscription.monthlyCost,
        billingCycle: subscription.billingCycle,
        nextBillingDate: subscription.nextBillingDate,
        websiteUrl: websiteUrl,
        isAutoDetected: true,
        repeatCount: subscription.repeatCount,
        lastPaymentDate: subscription.lastPaymentDate,
        categoryId: finalCategoryId,
        paymentCardId: finalPaymentCardId,
        currency: subscription.currency,
      );

      Log.i('구독 추가 성공: ${subscription.serviceName}');
      if (!context.mounted) return;
      moveToNextSubscription(context);
    } catch (e) {
      Log.e('구독 추가 중 오류 발생', e);
      // 오류가 있어도 다음 구독으로 이동
      if (!context.mounted) return;
      moveToNextSubscription(context);
    }
  }

  void skipCurrentSubscription(BuildContext context) {
    final subscription = _scannedSubscriptions[_currentIndex];
    Log.i('구독 건너뛰기: ${subscription.serviceName}');
    moveToNextSubscription(context);
  }

  void moveToNextSubscription(BuildContext context) {
    _currentIndex++;
    websiteUrlController.text = '';
    serviceNameController.text = '';
    _selectedCategoryId = null;
    _forceServiceNameEditing = false;
    _prepareCurrentSelection(context);

    // 모든 구독을 처리했으면 홈 화면으로 이동
    if (_currentIndex >= _scannedSubscriptions.length) {
      navigateToHome(context);
    }

    notifyListeners();
  }

  void navigateToHome(BuildContext context) {
    // NavigationProvider를 사용하여 홈 화면으로 이동
    final navigationProvider =
        Provider.of<NavigationProvider>(context, listen: false);
    navigationProvider.updateCurrentIndex(0);
  }

  void resetState() {
    _scannedSubscriptions = [];
    _currentIndex = 0;
    _errorMessage = null;
    _selectedPaymentCardId = null;
    _currentSuggestion = null;
    _shouldSuggestCardCreation = false;
    serviceNameController.clear();
    _forceServiceNameEditing = false;
    notifyListeners();
  }

  String getDefaultCategoryId(CategoryProvider categoryProvider) {
    final otherCategory = categoryProvider.categories.firstWhere(
      (cat) => cat.name == 'other',
      orElse: () => categoryProvider.categories.first,
    );
    Log.d('기본 카테고리 설정: ${otherCategory.name} (ID: ${otherCategory.id})');
    return otherCategory.id;
  }

  void initializeWebsiteUrl(BuildContext context) {
    if (_currentIndex < _scannedSubscriptions.length) {
      final currentSub = _scannedSubscriptions[_currentIndex];
      if (websiteUrlController.text.isEmpty && currentSub.websiteUrl != null) {
        websiteUrlController.text = currentSub.websiteUrl!;
      }
      final unknownLabel = _unknownServiceLabel(context);
      if (_shouldEnableServiceNameEditing(currentSub, unknownLabel)) {
        if (serviceNameController.text != currentSub.serviceName) {
          serviceNameController.clear();
        }
      } else {
        serviceNameController.text = currentSub.serviceName;
      }
    }
  }

  String? _getDefaultPaymentCardId(BuildContext context) {
    try {
      final provider = Provider.of<PaymentCardProvider>(context, listen: false);
      return provider.defaultCard?.id;
    } catch (_) {
      return null;
    }
  }

  void _prepareCurrentSelection(BuildContext context) {
    if (_currentIndex >= _scannedSubscriptions.length) {
      _selectedPaymentCardId = null;
      _currentSuggestion = null;
      _forceServiceNameEditing = false;
      serviceNameController.clear();
      return;
    }

    final current = _scannedSubscriptions[_currentIndex];
    final unknownLabel = _unknownServiceLabel(context);
    _forceServiceNameEditing =
        _shouldEnableServiceNameEditing(current, unknownLabel);
    if (_forceServiceNameEditing && current.serviceName == unknownLabel) {
      serviceNameController.clear();
    } else {
      serviceNameController.text = current.serviceName;
    }

    // URL 기본값
    if (current.websiteUrl != null && current.websiteUrl!.isNotEmpty) {
      websiteUrlController.text = current.websiteUrl!;
    } else {
      websiteUrlController.clear();
    }

    _currentSuggestion = current.paymentCardSuggestion;

    final matchedCardId = _matchCardWithSuggestion(context, _currentSuggestion);
    _shouldSuggestCardCreation =
        _currentSuggestion != null && matchedCardId == null;
    if (matchedCardId != null) {
      _selectedPaymentCardId = matchedCardId;
      return;
    }

    // 모델에 직접 카드 정보가 존재하면 우선 사용
    if (current.paymentCardId != null) {
      _selectedPaymentCardId = current.paymentCardId;
      return;
    }

    _selectedPaymentCardId = _getDefaultPaymentCardId(context);
  }

  String? _matchCardWithSuggestion(
      BuildContext context, PaymentCardSuggestion? suggestion) {
    if (suggestion == null) return null;
    try {
      final provider = Provider.of<PaymentCardProvider>(context, listen: false);
      final cards = provider.cards;
      if (cards.isEmpty) return null;

      if (suggestion.hasLast4) {
        for (final card in cards) {
          if (card.last4 == suggestion.last4) {
            return card.id;
          }
        }
      }

      final normalizedIssuer = suggestion.issuerName.toLowerCase();
      for (final card in cards) {
        final issuer = card.issuerName.toLowerCase();
        if (issuer.contains(normalizedIssuer) ||
            normalizedIssuer.contains(issuer)) {
          return card.id;
        }
      }
    } catch (_) {
      return null;
    }
    return null;
  }

  bool _shouldEnableServiceNameEditing(
      Subscription subscription, String unknownLabel) {
    final name = subscription.serviceName.trim();
    return name.isEmpty || name == unknownLabel;
  }

  String _unknownServiceLabel(BuildContext context) {
    return AppLocalizations.of(context).unknownService;
  }
}
