import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:provider/provider.dart';
import '../models/subscription_model.dart';
import '../models/category_model.dart';
import '../providers/subscription_provider.dart';
import '../providers/category_provider.dart';
import '../providers/locale_provider.dart';
import '../services/subscription_url_matcher.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:intl/intl.dart';
import '../widgets/dialogs/delete_confirmation_dialog.dart';
import '../widgets/common/snackbar/app_snackbar.dart';
import '../l10n/app_localizations.dart';
import '../utils/billing_date_util.dart';

/// DetailScreen의 비즈니스 로직을 관리하는 Controller
class DetailScreenController extends ChangeNotifier {
  final BuildContext context;
  final SubscriptionModel subscription;

  // Text Controllers
  late TextEditingController serviceNameController;
  late TextEditingController monthlyCostController;
  late TextEditingController websiteUrlController;
  late TextEditingController eventPriceController;

  // Display Names
  String? _displayName;
  String? get displayName => _displayName;

  // Form State
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  late String _billingCycle;
  late DateTime _nextBillingDate;
  String? _selectedCategoryId;
  String? _selectedPaymentCardId;
  late String _currency;
  bool _isLoading = false;

  // Event State
  late bool _isEventActive;
  DateTime? _eventStartDate;
  DateTime? _eventEndDate;

  // Getters
  String get billingCycle => _billingCycle;
  DateTime get nextBillingDate => _nextBillingDate;
  String? get selectedCategoryId => _selectedCategoryId;
  String? get selectedPaymentCardId => _selectedPaymentCardId;
  String get currency => _currency;
  bool get isLoading => _isLoading;
  bool get isEventActive => _isEventActive;
  DateTime? get eventStartDate => _eventStartDate;
  DateTime? get eventEndDate => _eventEndDate;

  // Setters
  set billingCycle(String value) {
    if (_billingCycle != value) {
      _billingCycle = value;
      notifyListeners();
    }
  }

  set nextBillingDate(DateTime value) {
    if (_nextBillingDate != value) {
      _nextBillingDate = value;
      notifyListeners();
    }
  }

  set selectedCategoryId(String? value) {
    if (_selectedCategoryId != value) {
      _selectedCategoryId = value;
      notifyListeners();
    }
  }

  set selectedPaymentCardId(String? value) {
    if (_selectedPaymentCardId != value) {
      _selectedPaymentCardId = value;
      notifyListeners();
    }
  }

  set currency(String value) {
    if (_currency != value) {
      _currency = value;
      _updateMonthlyCostFormat();
      notifyListeners();
    }
  }

  set isLoading(bool value) {
    if (_isLoading != value) {
      _isLoading = value;
      notifyListeners();
    }
  }

  set isEventActive(bool value) {
    if (_isEventActive != value) {
      _isEventActive = value;
      notifyListeners();
    }
  }

  set eventStartDate(DateTime? value) {
    if (_eventStartDate != value) {
      _eventStartDate = value;
      notifyListeners();
    }
  }

  set eventEndDate(DateTime? value) {
    if (_eventEndDate != value) {
      _eventEndDate = value;
      notifyListeners();
    }
  }

  // Focus Nodes
  final serviceNameFocus = FocusNode();
  final monthlyCostFocus = FocusNode();
  final billingCycleFocus = FocusNode();
  final nextBillingDateFocus = FocusNode();
  final websiteUrlFocus = FocusNode();
  final categoryFocus = FocusNode();
  final currencyFocus = FocusNode();

  // UI State
  final ScrollController scrollController = ScrollController();
  double scrollOffset = 0;
  int currentEditingField = -1;
  bool isDeleteHovered = false;
  bool isSaveHovered = false;
  bool isCancelHovered = false;

  // Animation Controller
  AnimationController? animationController;
  Animation<double>? fadeAnimation;
  Animation<Offset>? slideAnimation;
  Animation<double>? rotateAnimation;

  DetailScreenController({
    required this.context,
    required this.subscription,
  });

  /// 초기화
  void initialize({required TickerProvider vsync}) {
    // Text Controllers 초기화
    serviceNameController =
        TextEditingController(text: subscription.serviceName);
    monthlyCostController =
        TextEditingController(text: subscription.monthlyCost.toString());
    websiteUrlController =
        TextEditingController(text: subscription.websiteUrl ?? '');
    eventPriceController = TextEditingController();

    // Form State 초기화
    _billingCycle = subscription.billingCycle;
    _nextBillingDate = subscription.nextBillingDate;
    _selectedCategoryId = subscription.categoryId;
    _selectedPaymentCardId = subscription.paymentCardId;
    _currency = subscription.currency;

    // Event State 초기화
    _isEventActive = subscription.isEventActive;
    _eventStartDate = subscription.eventStartDate;
    _eventEndDate = subscription.eventEndDate;

    // 이벤트 가격 초기화
    if (subscription.eventPrice != null) {
      if (currency == 'KRW') {
        eventPriceController.text = NumberFormat.decimalPattern()
            .format(subscription.eventPrice!.toInt());
      } else {
        eventPriceController.text =
            NumberFormat('#,##0.00').format(subscription.eventPrice!);
      }
    }

    // 통화 단위에 따른 금액 표시 형식 조정
    _updateMonthlyCostFormat();

    // 애니메이션 초기화
    animationController = AnimationController(
      duration: const Duration(milliseconds: 800),
      vsync: vsync,
    );

    fadeAnimation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: animationController!,
      curve: Curves.easeInOut,
    ));

    slideAnimation = Tween<Offset>(
      begin: const Offset(0.0, 0.3),
      end: Offset.zero,
    ).animate(CurvedAnimation(
      parent: animationController!,
      curve: Curves.easeOutCubic,
    ));

    rotateAnimation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: animationController!,
      curve: Curves.easeOutCubic,
    ));

    // 애니메이션 시작
    animationController!.forward();

    // 로케일에 맞는 서비스명 로드
    _loadDisplayName();

    // 서비스명 변경 감지 리스너
    serviceNameController.addListener(onServiceNameChanged);

    // 스크롤 리스너
    scrollController.addListener(() {
      scrollOffset = scrollController.offset;
    });
  }

  /// 로케일에 맞는 서비스명 로드
  Future<void> _loadDisplayName() async {
    final localeProvider = context.read<LocaleProvider>();
    final locale = localeProvider.locale.languageCode;

    final displayName = await SubscriptionUrlMatcher.getServiceDisplayName(
      serviceName: subscription.serviceName,
      locale: locale,
    );

    _displayName = displayName;
    notifyListeners();
  }

  /// 리소스 정리
  @override
  void dispose() {
    // Controllers
    serviceNameController.dispose();
    monthlyCostController.dispose();
    websiteUrlController.dispose();
    eventPriceController.dispose();

    // Focus Nodes
    serviceNameFocus.dispose();
    monthlyCostFocus.dispose();
    billingCycleFocus.dispose();
    nextBillingDateFocus.dispose();
    websiteUrlFocus.dispose();
    categoryFocus.dispose();
    currencyFocus.dispose();

    // Animation
    animationController?.dispose();

    // Scroll
    scrollController.dispose();

    super.dispose();
  }

  /// 통화 단위에 따른 금액 표시 형식 업데이트
  void _updateMonthlyCostFormat() {
    if (_currency == 'KRW') {
      // 원화는 소수점 없이 표시
      final intValue = subscription.monthlyCost.toInt();
      monthlyCostController.text =
          NumberFormat.decimalPattern().format(intValue);
    } else {
      // 달러는 소수점 2자리까지 표시
      monthlyCostController.text =
          NumberFormat('#,##0.00').format(subscription.monthlyCost);
    }
  }

  /// 서비스명 변경시 카테고리 자동 선택
  void onServiceNameChanged() {
    autoSelectCategory();
  }

  /// 카테고리 자동 선택
  void autoSelectCategory() {
    final categoryProvider =
        Provider.of<CategoryProvider>(context, listen: false);
    final categories = categoryProvider.categories;

    final serviceName = serviceNameController.text.toLowerCase();

    // 서비스명에 기반한 카테고리 매칭 로직
    CategoryModel? matchedCategory;

    // 엔터테인먼트 관련 키워드
    if (serviceName.contains('netflix') ||
        serviceName.contains('youtube') ||
        serviceName.contains('disney') ||
        serviceName.contains('왓챠') ||
        serviceName.contains('티빙') ||
        serviceName.contains('웨이브') ||
        serviceName.contains('coupang play') ||
        serviceName.contains('쿠팡플레이')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == 'OTT 서비스',
        orElse: () => categories.first,
      );
    }
    // 음악 관련 키워드
    else if (serviceName.contains('spotify') ||
        serviceName.contains('apple music') ||
        serviceName.contains('멜론') ||
        serviceName.contains('지니') ||
        serviceName.contains('플로') ||
        serviceName.contains('벅스')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == 'music',
        orElse: () => categories.first,
      );
    }
    // 생산성 관련 키워드
    else if (serviceName.contains('notion') ||
        serviceName.contains('microsoft') ||
        serviceName.contains('office') ||
        serviceName.contains('google') ||
        serviceName.contains('dropbox') ||
        serviceName.contains('icloud') ||
        serviceName.contains('adobe')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == 'collaborationOffice',
        orElse: () => categories.first,
      );
    }
    // AI 관련 키워드
    else if (serviceName.contains('chatgpt') ||
        serviceName.contains('claude') ||
        serviceName.contains('gemini') ||
        serviceName.contains('copilot') ||
        serviceName.contains('midjourney')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == 'aiService',
        orElse: () => categories.first,
      );
    }
    // 교육 관련 키워드
    else if (serviceName.contains('coursera') ||
        serviceName.contains('udemy') ||
        serviceName.contains('인프런') ||
        serviceName.contains('패스트캠퍼스') ||
        serviceName.contains('클래스101')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == 'programming',
        orElse: () => categories.first,
      );
    }
    // 쇼핑 관련 키워드
    else if (serviceName.contains('쿠팡') ||
        serviceName.contains('coupang') ||
        serviceName.contains('amazon') ||
        serviceName.contains('네이버') ||
        serviceName.contains('11번가')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == 'other',
        orElse: () => categories.first,
      );
    }

    if (matchedCategory != null) {
      selectedCategoryId = matchedCategory.id;
    }
  }

  /// 구독 정보 업데이트
  Future<void> updateSubscription() async {
    // Form 검증
    if (formKey.currentState != null && !formKey.currentState!.validate()) {
      AppSnackBar.showError(
        context: context,
        message: AppLocalizations.of(context).requiredFieldsError,
      );
      return;
    }

    final provider = Provider.of<SubscriptionProvider>(context, listen: false);

    // 웹사이트 URL이 비어있는 경우 자동 매칭 다시 시도
    String? websiteUrl = websiteUrlController.text;
    if (websiteUrl.isEmpty) {
      websiteUrl =
          SubscriptionUrlMatcher.suggestUrl(serviceNameController.text);
    }

    // 구독 정보 업데이트

    // 콤마 제거하고 숫자만 추출
    double monthlyCost = 0.0;
    try {
      monthlyCost =
          double.parse(monthlyCostController.text.replaceAll(',', ''));
    } catch (e) {
      // 파싱 오류 발생 시 기본값 사용
      monthlyCost = subscription.monthlyCost;
    }

    debugPrint('[DetailScreenController] 구독 업데이트 시작: '
        '${subscription.serviceName} → ${serviceNameController.text}, '
        '금액: $subscription.monthlyCost → $monthlyCost $_currency');

    subscription.serviceName = serviceNameController.text;
    subscription.monthlyCost = monthlyCost;
    subscription.websiteUrl = websiteUrl;
    subscription.billingCycle = _billingCycle;
    // 선택일이 오늘(또는 과거)이면 결제 주기에 맞춰 다음 회차로 보정하여 저장
    final originalDateOnly = DateTime(
        _nextBillingDate.year, _nextBillingDate.month, _nextBillingDate.day);
    var adjustedNext =
        BillingDateUtil.ensureFutureDate(originalDateOnly, _billingCycle);
    subscription.nextBillingDate = adjustedNext;
    subscription.categoryId = _selectedCategoryId;
    subscription.paymentCardId = _selectedPaymentCardId;
    subscription.currency = _currency;

    // 이벤트 정보 업데이트
    subscription.isEventActive = _isEventActive;
    subscription.eventStartDate = _eventStartDate;
    subscription.eventEndDate = _eventEndDate;

    // 이벤트 가격 파싱
    if (_isEventActive && eventPriceController.text.isNotEmpty) {
      try {
        subscription.eventPrice =
            double.parse(eventPriceController.text.replaceAll(',', ''));
      } catch (e) {
        subscription.eventPrice = null;
      }
    } else {
      subscription.eventPrice = null;
    }

    debugPrint('[DetailScreenController] 업데이트 정보: '
        '현재가격=${subscription.currentPrice}, '
        '이벤트활성=${subscription.isEventActive}');

    // 구독 업데이트
    // 자동 보정이 발생했으면 안내
    if (adjustedNext.isAfter(originalDateOnly)) {
      AppSnackBar.showInfo(
        context: context,
        message: AppLocalizations.of(context).nextBillingDateAdjusted,
      );
    }

    await provider.updateSubscription(subscription);

    if (context.mounted) {
      AppSnackBar.showSuccess(
        context: context,
        message: AppLocalizations.of(context).subscriptionUpdated,
      );

      // 변경 사항이 반영될 시간을 주기 위해 짧게 지연 후 결과 반환
      await Future.delayed(const Duration(milliseconds: 100));
      if (context.mounted) {
        Navigator.of(context).pop(true);
      }
    }
  }

  /// 구독 삭제
  Future<void> deleteSubscription() async {
    if (context.mounted) {
      // 로케일에 맞는 서비스명 가져오기
      final localeProvider =
          Provider.of<LocaleProvider>(context, listen: false);
      final locale = localeProvider.locale.languageCode;
      final displayName = await SubscriptionUrlMatcher.getServiceDisplayName(
        serviceName: subscription.serviceName,
        locale: locale,
      );
      if (!context.mounted) return;

      // 삭제 확인 다이얼로그 표시
      final shouldDelete = await DeleteConfirmationDialog.show(
        context: context,
        serviceName: displayName,
      );
      if (!context.mounted) return;

      if (!shouldDelete) return;

      // 사용자가 확인한 경우에만 삭제 진행
      if (context.mounted) {
        final provider =
            Provider.of<SubscriptionProvider>(context, listen: false);
        await provider.deleteSubscription(subscription.id);

        if (context.mounted) {
          AppSnackBar.showError(
            context: context,
            message:
                AppLocalizations.of(context).subscriptionDeleted(displayName),
            icon: Icons.delete_forever_rounded,
          );
          Navigator.of(context).pop();
        }
      }
    }
  }

  /// 해지 페이지 열기
  Future<void> openCancellationPage() async {
    try {
      // 1. 현재 언어 설정 가져오기
      final locale = Localizations.localeOf(context).languageCode;

      // 2. 해지 안내 URL 찾기
      String? cancellationUrl =
          await SubscriptionUrlMatcher.findCancellationUrl(
        serviceName: subscription.serviceName,
        websiteUrl: subscription.websiteUrl,
        locale: locale == 'ko' ? 'kr' : 'en',
      );

      // 3. 해지 안내 URL이 없으면 구글 검색
      if (cancellationUrl == null) {
        final searchQuery =
            '${subscription.serviceName} ${locale == 'ko' ? '해지 방법' : 'cancel subscription'}';
        cancellationUrl =
            'https://www.google.com/search?q=${Uri.encodeComponent(searchQuery)}';

        if (context.mounted) {
          AppSnackBar.showInfo(
            context: context,
            message: AppLocalizations.of(context).officialCancelPageNotFound,
          );
        }
      }

      // 4. URL 열기
      final Uri url = Uri.parse(cancellationUrl);
      if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
        if (context.mounted) {
          AppSnackBar.showError(
            context: context,
            message: AppLocalizations.of(context).cannotOpenWebsite,
          );
        }
      }
    } catch (e) {
      if (kDebugMode) {
        // ignore: avoid_print
        print('DetailScreenController: 해지 페이지 열기 실패 - $e');
      }

      // 오류 발생시 일반 웹사이트로 폴백
      if (subscription.websiteUrl != null &&
          subscription.websiteUrl!.isNotEmpty) {
        final Uri url = Uri.parse(subscription.websiteUrl!);
        if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
          if (context.mounted) {
            AppSnackBar.showError(
              context: context,
              message: AppLocalizations.of(context).cannotOpenWebsite,
            );
          }
        }
      } else {
        if (context.mounted) {
          AppSnackBar.showWarning(
            context: context,
            message: AppLocalizations.of(context).noWebsiteInfo,
          );
        }
      }
    }
  }

  /// 카드 색상 가져오기
  Color getCardColor() {
    // 서비스 이름에 따라 일관된 색상 생성
    final int hash = subscription.serviceName.hashCode.abs();
    final List<Color> colors = [
      const Color(0xFF3B82F6), // 파랑
      const Color(0xFF10B981), // 초록
      const Color(0xFF8B5CF6), // 보라
      const Color(0xFFF59E0B), // 노랑
      const Color(0xFFEF4444), // 빨강
      const Color(0xFF0EA5E9), // 하늘
      const Color(0xFFEC4899), // 분홍
    ];

    return colors[hash % colors.length];
  }

  // getGradient 제거됨 (그라데이션 미사용)
}
