import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode;
import 'package:provider/provider.dart';
import 'package:intl/intl.dart';
import '../providers/subscription_provider.dart';
import '../providers/category_provider.dart';
import '../providers/payment_card_provider.dart';
import '../services/sms_service.dart';
import '../services/subscription_url_matcher.dart';
import '../widgets/common/snackbar/app_snackbar.dart';
import '../l10n/app_localizations.dart';
import '../utils/billing_date_util.dart';
import 'package:permission_handler/permission_handler.dart' as permission;

/// AddSubscriptionScreen의 비즈니스 로직을 관리하는 Controller
class AddSubscriptionController {
  final BuildContext context;

  // Form Key
  final formKey = GlobalKey<FormState>();

  // Text Controllers
  final serviceNameController = TextEditingController();
  final monthlyCostController = TextEditingController();
  final nextBillingDateController = TextEditingController();
  final websiteUrlController = TextEditingController();
  final eventPriceController = TextEditingController();

  // Form State
  String billingCycle = 'monthly';
  String currency = 'KRW';
  DateTime? nextBillingDate;
  bool isLoading = false;
  String? selectedCategoryId;
  String? selectedPaymentCardId;

  // Event State
  bool isEventActive = false;
  DateTime? eventStartDate = DateTime.now();
  DateTime? eventEndDate = DateTime.now().add(const Duration(days: 30));

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

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

  // Scroll Controller
  final ScrollController scrollController = ScrollController();
  double scrollOffset = 0;

  // UI State
  int currentEditingField = -1;
  bool isSaveHovered = false;

  // Gradient Colors
  final List<Color> gradientColors = [
    const Color(0xFF3B82F6),
    const Color(0xFF0EA5E9),
    const Color(0xFF06B6D4),
  ];

  AddSubscriptionController({required this.context});

  /// 초기화
  void initialize({required TickerProvider vsync}) {
    // 결제일 기본값을 오늘 날짜로 설정
    nextBillingDate = DateTime.now();

    // 서비스명 컨트롤러에 리스너 추가
    serviceNameController.addListener(onServiceNameChanged);

    // 웹사이트 URL 컨트롤러에 리스너 추가
    websiteUrlController.addListener(onWebsiteUrlChanged);

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

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

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

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

    // 언어별 기본 통화 설정
    try {
      final lang = Localizations.localeOf(context).languageCode;
      switch (lang) {
        case 'ko':
          currency = 'KRW';
          break;
        case 'ja':
          currency = 'JPY';
          break;
        case 'zh':
          currency = 'CNY';
          break;
        default:
          currency = 'USD';
      }
    } catch (_) {
      // Localizations가 아직 준비되지 않은 경우 기본값 유지
    }

    // 기본 결제수단 설정
    try {
      final paymentCardProvider =
          Provider.of<PaymentCardProvider>(context, listen: false);
      selectedPaymentCardId = paymentCardProvider.defaultCard?.id;
    } catch (_) {}

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

  /// 리소스 정리
  void dispose() {
    // Controllers
    serviceNameController.dispose();
    monthlyCostController.dispose();
    nextBillingDateController.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();
  }

  /// 서비스명 변경시 호출
  void onServiceNameChanged() {
    autoSelectCategory();
  }

  /// 웹사이트 URL 변경시 호출
  void onWebsiteUrlChanged() async {
    final url = websiteUrlController.text.trim();

    // URL이 비어있거나 너무 짧으면 무시
    if (url.isEmpty || url.length < 5) return;

    // 이미 서비스명이 입력되어 있으면 자동 매칭하지 않음
    if (serviceNameController.text.isNotEmpty) return;

    try {
      // URL로 서비스 정보 찾기
      final serviceInfo = await SubscriptionUrlMatcher.findServiceByUrl(url);

      if (serviceInfo != null && context.mounted) {
        // 서비스명 자동 입력
        serviceNameController.text = serviceInfo.serviceName;

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

        // 카테고리 ID로 매칭
        final matchedCategory = categories.firstWhere(
          (cat) =>
              cat.name == serviceInfo.categoryNameKr ||
              cat.name == serviceInfo.categoryNameEn,
          orElse: () => categories.first,
        );

        selectedCategoryId = matchedCategory.id;

        // 스낵바로 알림
        if (context.mounted) {
          AppSnackBar.showSuccess(
            context: context,
            message: AppLocalizations.of(context)
                .serviceRecognized(serviceInfo.serviceName),
          );
        }
      }
    } catch (e) {
      if (kDebugMode) {
        // ignore: avoid_print
        print('AddSubscriptionController: URL 자동 매칭 중 오류 - $e');
      }
    }
  }

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

    final serviceName = serviceNameController.text.toLowerCase();

    // 서비스명에 기반한 카테고리 매칭 로직
    dynamic 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 == '엔터테인먼트',
        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 == '생산성',
        orElse: () => categories.first,
      );
    }
    // 게임 관련 키워드
    else if (serviceName.contains('xbox') ||
        serviceName.contains('playstation') ||
        serviceName.contains('nintendo') ||
        serviceName.contains('steam') ||
        serviceName.contains('게임')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == '게임',
        orElse: () => categories.first,
      );
    }
    // 교육 관련 키워드
    else if (serviceName.contains('coursera') ||
        serviceName.contains('udemy') ||
        serviceName.contains('인프런') ||
        serviceName.contains('패스트캠퍼스') ||
        serviceName.contains('클래스101')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == '교육',
        orElse: () => categories.first,
      );
    }
    // 쇼핑 관련 키워드
    else if (serviceName.contains('쿠팡') ||
        serviceName.contains('coupang') ||
        serviceName.contains('amazon') ||
        serviceName.contains('네이버') ||
        serviceName.contains('11번가')) {
      matchedCategory = categories.firstWhere(
        (cat) => cat.name == '쇼핑',
        orElse: () => categories.first,
      );
    }

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

  /// SMS 스캔
  Future<void> scanSMS({required Function setState}) async {
    if (kIsWeb) return;

    setState(() => isLoading = true);

    try {
      final ctx = context;
      if (!await SMSService.hasSMSPermission()) {
        final granted = await SMSService.requestSMSPermission();
        if (!ctx.mounted) return;
        if (!granted) {
          if (ctx.mounted) {
            // 영구 거부 여부 확인 후 설정 화면 안내
            final status = await permission.Permission.sms.status;
            if (!ctx.mounted) return;
            if (status.isPermanentlyDenied) {
              await showDialog(
                context: ctx,
                builder: (_) => AlertDialog(
                  title: Text(AppLocalizations.of(ctx).smsPermissionRequired),
                  content:
                      Text(AppLocalizations.of(ctx).permanentlyDeniedMessage),
                  actions: [
                    TextButton(
                      onPressed: () => Navigator.of(ctx).pop(),
                      child: Text(AppLocalizations.of(ctx).cancel),
                    ),
                    TextButton(
                      onPressed: () async {
                        await permission.openAppSettings();
                        if (ctx.mounted) Navigator.of(ctx).pop();
                      },
                      child: Text(AppLocalizations.of(ctx).openSettings),
                    ),
                  ],
                ),
              );
            } else {
              AppSnackBar.showError(
                context: ctx,
                message: AppLocalizations.of(ctx).smsPermissionRequired,
              );
            }
          }
          return;
        }
      }

      final subscriptions = await SMSService.scanSubscriptions();
      if (!ctx.mounted) return;
      if (subscriptions.isEmpty) {
        if (ctx.mounted) {
          AppSnackBar.showWarning(
            context: ctx,
            message: AppLocalizations.of(ctx).noSubscriptionSmsFound,
          );
        }
        return;
      }

      final subscription = subscriptions.first;

      // SMS에서 서비스 정보 추출 시도
      ServiceInfo? serviceInfo;
      final smsContent = subscription['smsContent'] ?? '';

      if (smsContent.isNotEmpty) {
        try {
          serviceInfo =
              await SubscriptionUrlMatcher.extractServiceFromSms(smsContent);
        } catch (e) {
          if (kDebugMode) {
            // ignore: avoid_print
            print('AddSubscriptionController: SMS 서비스 추출 실패 - $e');
          }
        }
      }

      setState(() {
        // 서비스 정보가 있으면 우선 사용, 없으면 SMS에서 추출한 정보 사용
        if (serviceInfo != null) {
          serviceNameController.text = serviceInfo.serviceName;
          websiteUrlController.text = serviceInfo.serviceUrl ?? '';

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

          final matchedCategory = categories.firstWhere(
            (cat) =>
                cat.name == serviceInfo!.categoryNameKr ||
                cat.name == serviceInfo.categoryNameEn,
            orElse: () => categories.first,
          );

          selectedCategoryId = matchedCategory.id;
        } else {
          // 기존 로직 사용
          serviceNameController.text = subscription['serviceName'] ?? '';
        }

        // 비용 처리 및 통화 단위 자동 감지
        final costValue = subscription['monthlyCost']?.toString() ?? '';

        if (costValue.isNotEmpty) {
          // 달러 표시가 있거나 소수점이 있으면 달러로 판단
          if (costValue.contains('\$') || costValue.contains('.')) {
            currency = 'USD';
            String numericValue = costValue.replaceAll('\$', '').trim();
            if (!numericValue.contains('.')) {
              numericValue = '$numericValue.00';
            }
            final double parsedValue =
                double.tryParse(numericValue.replaceAll(',', '')) ?? 0.0;
            monthlyCostController.text =
                NumberFormat('#,##0.00').format(parsedValue);
          } else {
            currency = 'KRW';
            String numericValue =
                costValue.replaceAll('₩', '').replaceAll(',', '').trim();
            final int parsedValue = int.tryParse(numericValue) ?? 0;
            monthlyCostController.text =
                NumberFormat.decimalPattern().format(parsedValue);
          }
        } else {
          monthlyCostController.text = '';
        }

        billingCycle = subscription['billingCycle'] ?? '월간';
        nextBillingDate = subscription['nextBillingDate'] != null
            ? DateTime.parse(subscription['nextBillingDate'])
            : DateTime.now();

        // 서비스 정보가 없고 서비스명이 있으면 URL 자동 매칭 시도
        if (serviceInfo == null &&
            subscription['serviceName'] != null &&
            subscription['serviceName'].isNotEmpty) {
          final suggestedUrl =
              SubscriptionUrlMatcher.suggestUrl(subscription['serviceName']);
          if (suggestedUrl != null && websiteUrlController.text.isEmpty) {
            websiteUrlController.text = suggestedUrl;
          }

          // 서비스명 기반으로 카테고리 자동 선택
          autoSelectCategory();
        }

        // 애니메이션 재생
        animationController!.reset();
        animationController!.forward();
      });
    } catch (e) {
      if (context.mounted) {
        AppSnackBar.showError(
          context: context,
          message: AppLocalizations.of(context)
              .smsScanErrorWithMessage(e.toString()),
        );
      }
    } finally {
      if (context.mounted) {
        setState(() => isLoading = false);
      }
    }
  }

  /// 구독 저장
  Future<void> saveSubscription({required Function setState}) async {
    if (formKey.currentState!.validate() && nextBillingDate != null) {
      setState(() {
        isLoading = true;
      });

      try {
        // 콤마 제거하고 숫자만 추출
        final monthlyCost =
            double.parse(monthlyCostController.text.replaceAll(',', ''));

        // 이벤트 가격 파싱
        double? eventPrice;
        if (isEventActive && eventPriceController.text.isNotEmpty) {
          eventPrice =
              double.tryParse(eventPriceController.text.replaceAll(',', ''));
        }

        // 선택일이 오늘(또는 과거)이면 결제 주기에 맞춰 다음 회차로 보정하여 저장 + 영업일 이월
        final originalDateOnly = DateTime(
          nextBillingDate!.year,
          nextBillingDate!.month,
          nextBillingDate!.day,
        );
        var adjustedNext =
            BillingDateUtil.ensureFutureDate(originalDateOnly, billingCycle);

        await Provider.of<SubscriptionProvider>(context, listen: false)
            .addSubscription(
          serviceName: serviceNameController.text.trim(),
          monthlyCost: monthlyCost,
          billingCycle: billingCycle,
          nextBillingDate: adjustedNext,
          websiteUrl: websiteUrlController.text.trim(),
          categoryId: selectedCategoryId,
          paymentCardId: selectedPaymentCardId,
          currency: currency,
          isEventActive: isEventActive,
          eventStartDate: eventStartDate,
          eventEndDate: eventEndDate,
          eventPrice: eventPrice,
        );

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

        if (context.mounted) {
          Navigator.pop(context, true); // 성공 여부 반환
        }
      } catch (e) {
        setState(() {
          isLoading = false;
        });

        if (context.mounted) {
          AppSnackBar.showError(
            context: context,
            message:
                AppLocalizations.of(context).saveErrorWithMessage(e.toString()),
          );
        }
      }
    } else {
      scrollController.animateTo(
        0.0,
        duration: const Duration(milliseconds: 300),
        curve: Curves.easeOut,
      );
    }
  }
}
