import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/subscription_model.dart';
import '../providers/category_provider.dart';
import '../providers/payment_card_provider.dart';
import '../providers/locale_provider.dart';
import '../services/subscription_url_matcher.dart';
import '../services/currency_util.dart';
import '../utils/billing_date_util.dart';
import '../utils/payment_card_utils.dart';
import 'website_icon.dart';
import 'app_navigator.dart';
// import '../theme/app_colors.dart';
import '../theme/color_scheme_ext.dart';
// import 'glassmorphism_card.dart';
import '../l10n/app_localizations.dart';

class SubscriptionCard extends StatefulWidget {
  final SubscriptionModel subscription;
  final VoidCallback? onTap;

  const SubscriptionCard({
    super.key,
    required this.subscription,
    this.onTap,
  });

  @override
  State<SubscriptionCard> createState() => _SubscriptionCardState();
}

class _SubscriptionCardState extends State<SubscriptionCard>
    with SingleTickerProviderStateMixin {
  late AnimationController _hoverController;
  bool _isHovering = false;
  String? _displayName;
  static const int _nearBillingThresholdDays = 3;

  @override
  void initState() {
    super.initState();
    _hoverController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 200),
    );
    _loadDisplayName();
  }

  Future<void> _loadDisplayName() async {
    if (!mounted) return;

    final localeProvider = context.read<LocaleProvider>();
    final locale = localeProvider.locale.languageCode;

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

    if (mounted) {
      setState(() {
        _displayName = displayName;
      });
    }
  }

  @override
  void didUpdateWidget(SubscriptionCard oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.subscription.serviceName != widget.subscription.serviceName) {
      _loadDisplayName();
    }
  }

  @override
  void dispose() {
    _hoverController.dispose();
    super.dispose();
  }

  void _onHover(bool isHovering) {
    setState(() {
      _isHovering = isHovering;
      if (isHovering) {
        _hoverController.forward();
      } else {
        _hoverController.reverse();
      }
    });
  }

  // 다음 결제 예정일 정보를 생성
  String _getNextBillingText() {
    final now = DateTime.now();
    final nextBillingDate = widget.subscription.nextBillingDate;

    // 날짜 비교를 위해 시간 제거 (날짜만 비교)
    final dateOnlyNow = DateTime(now.year, now.month, now.day);
    final dateOnlyBilling = DateTime(
        nextBillingDate.year, nextBillingDate.month, nextBillingDate.day);

    // 오늘이 결제일인 경우
    if (dateOnlyNow.isAtSameMomentAs(dateOnlyBilling)) {
      return AppLocalizations.of(context).paymentDueToday;
    }

    // 미래 날짜인 경우 남은 일수 계산
    if (dateOnlyBilling.isAfter(dateOnlyNow)) {
      final difference = dateOnlyBilling.difference(dateOnlyNow).inDays;
      return AppLocalizations.of(context).paymentDueInDays(difference);
    }

    // 과거 날짜인 경우, 다음 결제일 계산
    final billingCycle = widget.subscription.billingCycle;
    final norm = BillingDateUtil.normalizeCycle(billingCycle);

    // 분기/반기 구독 처리
    if (norm == 'quarterly' || norm == 'half-yearly') {
      final nextDate =
          BillingDateUtil.ensureFutureDate(nextBillingDate, billingCycle);
      final days = nextDate.difference(dateOnlyNow).inDays;
      if (days == 0) return AppLocalizations.of(context).paymentDueToday;
      return AppLocalizations.of(context).paymentDueInDays(days);
    }

    // 월간 구독인 경우
    if (SubscriptionModel.normalizeBillingCycle(billingCycle) == 'monthly') {
      // 결제일에 해당하는 날짜 가져오기
      int day = nextBillingDate.day;
      int nextMonth = now.month;
      int nextYear = now.year;

      // 해당 월의 마지막 날짜 확인 (예: 31일이 없는 달)
      final lastDayOfMonth = DateTime(now.year, now.month + 1, 0).day;
      if (day > lastDayOfMonth) {
        day = lastDayOfMonth;
      }

      // 결제일이 이번 달에서 이미 지났으면 다음 달로 설정
      if (now.day > day) {
        nextMonth++;
        if (nextMonth > 12) {
          nextMonth = 1;
          nextYear++;
        }

        // 다음 달의 마지막 날짜 확인
        final lastDayOfNextMonth = DateTime(nextYear, nextMonth + 1, 0).day;
        if (day > lastDayOfNextMonth) {
          day = lastDayOfNextMonth;
        }
      }

      final nextDate = DateTime(nextYear, nextMonth, day);
      final days = nextDate.difference(dateOnlyNow).inDays;

      if (days == 0) return AppLocalizations.of(context).paymentDueToday;
      return AppLocalizations.of(context).paymentDueInDays(days);
    }

    // 연간 구독인 경우
    if (SubscriptionModel.normalizeBillingCycle(billingCycle) == 'yearly') {
      // 결제일에 해당하는 날짜와 월 가져오기
      int day = nextBillingDate.day;
      int month = nextBillingDate.month;
      int year = now.year;

      // 해당 월의 마지막 날짜 확인
      final lastDayOfMonth = DateTime(year, month + 1, 0).day;
      if (day > lastDayOfMonth) {
        day = lastDayOfMonth;
      }

      // 올해의 결제일
      final thisYearDate = DateTime(year, month, day);

      // 올해 결제일이 이미 지났으면 내년으로 계산
      if (thisYearDate.isBefore(dateOnlyNow) ||
          thisYearDate.isAtSameMomentAs(dateOnlyNow)) {
        year++;

        // 내년 해당 월의 마지막 날짜 확인
        final lastDayOfNextYear = DateTime(year, month + 1, 0).day;
        if (day > lastDayOfNextYear) {
          day = lastDayOfNextYear;
        }

        final nextYearDate = DateTime(year, month, day);
        final days = nextYearDate.difference(dateOnlyNow).inDays;

        if (days == 0) return AppLocalizations.of(context).paymentDueToday;
        return AppLocalizations.of(context).paymentDueInDays(days);
      } else {
        final days = thisYearDate.difference(dateOnlyNow).inDays;

        if (days == 0) return AppLocalizations.of(context).paymentDueToday;
        return AppLocalizations.of(context).paymentDueInDays(days);
      }
    }

    // 주간 구독인 경우
    if (SubscriptionModel.normalizeBillingCycle(billingCycle) == 'weekly') {
      // 결제 요일 가져오기
      final billingWeekday = nextBillingDate.weekday;
      // 현재 요일
      final currentWeekday = now.weekday;

      // 다음 같은 요일까지 남은 일수 계산
      int daysUntilNext;
      if (currentWeekday < billingWeekday) {
        daysUntilNext = billingWeekday - currentWeekday;
      } else if (currentWeekday > billingWeekday) {
        daysUntilNext = 7 - (currentWeekday - billingWeekday);
      } else {
        // 같은 요일
        daysUntilNext = 7; // 다음 주 같은 요일
      }

      if (daysUntilNext == 0) {
        return AppLocalizations.of(context).paymentDueToday;
      }
      return AppLocalizations.of(context).paymentDueInDays(daysUntilNext);
    }

    // 기본값 - 예상할 수 없는 경우
    return AppLocalizations.of(context).paymentInfoNeeded;
  }

  int _daysUntilNextBilling() {
    final now = DateTime.now();
    final dateOnlyNow = DateTime(now.year, now.month, now.day);
    final nbd = widget.subscription.nextBillingDate;
    final dateOnlyBilling = DateTime(nbd.year, nbd.month, nbd.day);

    if (dateOnlyBilling.isAfter(dateOnlyNow)) {
      return dateOnlyBilling.difference(dateOnlyNow).inDays;
    }

    final next =
        BillingDateUtil.ensureFutureDate(nbd, widget.subscription.billingCycle);
    return next.difference(dateOnlyNow).inDays;
  }

  // 결제일이 가까운지 확인
  bool _isNearBilling() {
    final days = _daysUntilNextBilling();
    return days <= _nearBillingThresholdDays;
  }

  // 카테고리별 그라데이션 색상 생성
  List<Color> _getCategoryGradientColors(BuildContext context) {
    try {
      if (widget.subscription.categoryId == null) {
        return [Theme.of(context).colorScheme.primary];
      }

      final categoryProvider = context.watch<CategoryProvider>();
      final category =
          categoryProvider.getCategoryById(widget.subscription.categoryId!);

      if (category == null) {
        return [Theme.of(context).colorScheme.primary];
      }

      final categoryColor =
          Color(int.parse(category.color.replaceAll('#', '0xFF')));

      return [categoryColor];
    } catch (e) {
      // 색상 파싱 실패 시 기본 primary 색 반환
      return [Theme.of(context).colorScheme.primary];
    }
  }

  // 가격 포맷팅 함수 (언어별 통화)
  Future<String> _getFormattedPrice() async {
    final locale = context.read<LocaleProvider>().locale.languageCode;
    if (widget.subscription.isCurrentlyInEvent) {
      // 이벤트 중인 경우 원래 가격과 현재 가격 모두 표시
      final originalPrice = await CurrencyUtil.formatAmountWithLocale(
        widget.subscription.monthlyCost,
        widget.subscription.currency,
        locale,
      );
      final currentPrice = await CurrencyUtil.formatAmountWithLocale(
        widget.subscription.currentPrice,
        widget.subscription.currency,
        locale,
      );
      return '$originalPrice|$currentPrice';
    } else {
      return CurrencyUtil.formatAmountWithLocale(
        widget.subscription.currentPrice,
        widget.subscription.currency,
        locale,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    // LocaleProvider를 watch하여 언어 변경시 자동 업데이트
    final localeProvider = context.watch<LocaleProvider>();
    final paymentCardProvider = context.watch<PaymentCardProvider>();

    // 언어가 변경되면 displayName 다시 로드
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _loadDisplayName();
    });

    final isNearBilling = _isNearBilling();

    return Hero(
      tag: 'subscription_${widget.subscription.id}',
      child: MouseRegion(
        onEnter: (_) => _onHover(true),
        onExit: (_) => _onHover(false),
        child: Card(
          elevation: _isHovering ? 2 : 1,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(16),
            side: BorderSide(
              color:
                  Theme.of(context).colorScheme.outline.withValues(alpha: 0.4),
              width: 1,
            ),
          ),
          clipBehavior: Clip.antiAlias,
          child: InkWell(
            onTap: widget.onTap ??
                () async {
                  // ignore: use_build_context_synchronously
                  await AppNavigator.toDetail(context, widget.subscription);
                },
            child: Column(
              children: [
                // 그라데이션 상단 바 효과
                AnimatedContainer(
                  duration: const Duration(milliseconds: 200),
                  height: 4,
                  // 카테고리 우선: 상단 바는 항상 카테고리 색
                  color: _getCategoryGradientColors(context).first,
                ),

                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      // 서비스 아이콘
                      WebsiteIcon(
                        key: ValueKey(
                            'subscription_icon_${widget.subscription.id}'),
                        url: widget.subscription.websiteUrl,
                        serviceName: widget.subscription.serviceName,
                        size: 48,
                        isHovered: _isHovering,
                      ),
                      const SizedBox(width: 16),

                      // 서비스 정보
                      Expanded(
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: [
                                // 서비스명
                                Flexible(
                                  child: Text(
                                    _displayName ??
                                        widget.subscription.serviceName,
                                    style: TextStyle(
                                      fontWeight: FontWeight.w600,
                                      fontSize: 18,
                                      color: Theme.of(context)
                                          .colorScheme
                                          .onSurface,
                                    ),
                                    maxLines: 1,
                                    overflow: TextOverflow.ellipsis,
                                  ),
                                ),

                                // 배지들
                                Row(
                                  mainAxisSize: MainAxisSize.min,
                                  children: [
                                    // 이벤트 배지
                                    if (widget
                                        .subscription.isCurrentlyInEvent) ...[
                                      Container(
                                        padding: const EdgeInsets.symmetric(
                                          horizontal: 8,
                                          vertical: 3,
                                        ),
                                        decoration: BoxDecoration(
                                          color: Theme.of(context)
                                              .colorScheme
                                              .error,
                                          borderRadius:
                                              BorderRadius.circular(12),
                                        ),
                                        child: Row(
                                          mainAxisSize: MainAxisSize.min,
                                          children: [
                                            Icon(
                                              Icons.local_offer_rounded,
                                              size: 11,
                                              color: Theme.of(context)
                                                  .colorScheme
                                                  .onError,
                                            ),
                                            const SizedBox(width: 3),
                                            Text(
                                              AppLocalizations.of(context)
                                                  .event,
                                              style: TextStyle(
                                                fontSize: 11,
                                                fontWeight: FontWeight.w600,
                                                color: Theme.of(context)
                                                    .colorScheme
                                                    .onError,
                                              ),
                                            ),
                                          ],
                                        ),
                                      ),
                                      const SizedBox(width: 6),
                                    ],

                                    // 결제 주기 배지
                                    Container(
                                      padding: const EdgeInsets.symmetric(
                                        horizontal: 8,
                                        vertical: 3,
                                      ),
                                      decoration: BoxDecoration(
                                        color: Theme.of(context)
                                            .colorScheme
                                            .surface,
                                        borderRadius: BorderRadius.circular(12),
                                        border: Border.all(
                                          color: Theme.of(context)
                                              .colorScheme
                                              .outline
                                              .withValues(alpha: 0.5),
                                          width: 0.5,
                                        ),
                                      ),
                                      child: Text(
                                        AppLocalizations.of(context)
                                            .getBillingCycleName(widget
                                                .subscription.billingCycle),
                                        style: TextStyle(
                                          fontSize: 11,
                                          fontWeight: FontWeight.w600,
                                          color: Theme.of(context)
                                              .colorScheme
                                              .onSurfaceVariant,
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                              ],
                            ),

                            const SizedBox(height: 8),
                            _buildPaymentCardBadge(
                                context, paymentCardProvider),
                            const SizedBox(height: 8),

                            // 가격 정보
                            Row(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                // 가격 표시 (이벤트 가격 반영)
                                Expanded(
                                  child: FutureBuilder<String>(
                                    future: _getFormattedPrice(),
                                    builder: (context, snapshot) {
                                      if (!snapshot.hasData) {
                                        return const SizedBox();
                                      }

                                      if (widget.subscription
                                              .isCurrentlyInEvent &&
                                          snapshot.data!.contains('|')) {
                                        final prices =
                                            snapshot.data!.split('|');
                                        return Wrap(
                                          spacing: 8,
                                          runSpacing: 4,
                                          crossAxisAlignment:
                                              WrapCrossAlignment.center,
                                          children: [
                                            Text(
                                              prices[0],
                                              style: TextStyle(
                                                fontSize: 14,
                                                fontWeight: FontWeight.w500,
                                                color: Theme.of(context)
                                                    .colorScheme
                                                    .onSurfaceVariant,
                                                decoration:
                                                    TextDecoration.lineThrough,
                                              ),
                                            ),
                                            Text(
                                              prices[1],
                                              style: TextStyle(
                                                fontSize: 16,
                                                fontWeight: FontWeight.w700,
                                                color: Theme.of(context)
                                                    .colorScheme
                                                    .error,
                                              ),
                                            ),
                                          ],
                                        );
                                      } else {
                                        return Text(
                                          snapshot.data!,
                                          maxLines: 2,
                                          overflow: TextOverflow.ellipsis,
                                          style: TextStyle(
                                            fontSize: 16,
                                            fontWeight: FontWeight.w700,
                                            color: widget.subscription
                                                    .isCurrentlyInEvent
                                                ? Theme.of(context)
                                                    .colorScheme
                                                    .error
                                                : Theme.of(context)
                                                    .colorScheme
                                                    .primary,
                                          ),
                                        );
                                      }
                                    },
                                  ),
                                ),
                                const SizedBox(width: 12),

                                // 결제 예정일 정보
                                Container(
                                  padding: const EdgeInsets.symmetric(
                                    horizontal: 8,
                                    vertical: 3,
                                  ),
                                  decoration: BoxDecoration(
                                    color: (isNearBilling
                                            ? Theme.of(context)
                                                .colorScheme
                                                .warning
                                            : Theme.of(context)
                                                .colorScheme
                                                .success)
                                        .withValues(alpha: 0.1),
                                    borderRadius: BorderRadius.circular(12),
                                  ),
                                  child: Row(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      Icon(
                                        isNearBilling
                                            ? Icons.access_time_filled_rounded
                                            : Icons.check_circle_rounded,
                                        size: 12,
                                        color: isNearBilling
                                            ? Theme.of(context)
                                                .colorScheme
                                                .warning
                                            : Theme.of(context)
                                                .colorScheme
                                                .success,
                                      ),
                                      const SizedBox(width: 4),
                                      Text(
                                        _getNextBillingText(),
                                        style: TextStyle(
                                          fontSize: 11,
                                          fontWeight: FontWeight.w600,
                                          color: isNearBilling
                                              ? Theme.of(context)
                                                  .colorScheme
                                                  .warning
                                              : Theme.of(context)
                                                  .colorScheme
                                                  .success,
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ],
                            ),

                            // 이벤트 절약액 표시
                            if (widget.subscription.isCurrentlyInEvent &&
                                widget.subscription.eventSavings > 0) ...[
                              const SizedBox(height: 4),
                              Row(
                                children: [
                                  Container(
                                    padding: const EdgeInsets.symmetric(
                                      horizontal: 6,
                                      vertical: 2,
                                    ),
                                    decoration: BoxDecoration(
                                      color: Theme.of(context)
                                          .colorScheme
                                          .error
                                          .withValues(alpha: 0.1),
                                      borderRadius: BorderRadius.circular(8),
                                    ),
                                    child: Row(
                                      mainAxisSize: MainAxisSize.min,
                                      children: [
                                        Icon(
                                          Icons.savings_rounded,
                                          size: 14,
                                          color: Theme.of(context)
                                              .colorScheme
                                              .error,
                                        ),
                                        const SizedBox(width: 4),
                                        // 이벤트 절약액 표시 (언어별 통화)
                                        FutureBuilder<String>(
                                          future: CurrencyUtil
                                              .formatEventSavingsWithLocale(
                                            widget.subscription,
                                            localeProvider.locale.languageCode,
                                          ),
                                          builder: (context, snapshot) {
                                            if (!snapshot.hasData) {
                                              return const SizedBox();
                                            }
                                            return Text(
                                              '${snapshot.data!} ${AppLocalizations.of(context).saving}',
                                              style: TextStyle(
                                                fontSize: 12,
                                                fontWeight: FontWeight.w600,
                                                color: Theme.of(context)
                                                    .colorScheme
                                                    .error,
                                              ),
                                            );
                                          },
                                        ),
                                      ],
                                    ),
                                  ),
                                  const SizedBox(width: 8),
                                  // 이벤트 종료일까지 남은 일수
                                  if (widget.subscription.eventEndDate !=
                                      null) ...[
                                    Text(
                                      AppLocalizations.of(context)
                                          .daysRemaining(widget
                                              .subscription.eventEndDate!
                                              .difference(DateTime.now())
                                              .inDays),
                                      style: TextStyle(
                                        fontSize: 11,
                                        color: Theme.of(context)
                                            .colorScheme
                                            .onSurfaceVariant,
                                      ),
                                    ),
                                  ],
                                ],
                              ),
                            ],
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildPaymentCardBadge(
      BuildContext context, PaymentCardProvider provider) {
    final scheme = Theme.of(context).colorScheme;
    final loc = AppLocalizations.of(context);
    final card = provider.getCardById(widget.subscription.paymentCardId);

    if (card == null) {
      return Chip(
        avatar: Icon(
          Icons.credit_card_off_rounded,
          size: 14,
          color: scheme.onSurfaceVariant,
        ),
        label: Text(
          loc.paymentCardUnassigned,
          style: TextStyle(
            fontSize: 12,
            color: scheme.onSurfaceVariant,
          ),
        ),
        backgroundColor: scheme.surfaceContainerHighest.withValues(alpha: 0.5),
        padding: const EdgeInsets.symmetric(horizontal: 6),
        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
      );
    }

    final color = PaymentCardUtils.colorFromHex(card.colorHex);
    final icon = PaymentCardUtils.iconForName(card.iconName);

    return Chip(
      avatar: Container(
        width: 20,
        height: 20,
        decoration: BoxDecoration(
          color: color.withValues(alpha: 0.15),
          shape: BoxShape.circle,
        ),
        alignment: Alignment.center,
        child: Icon(
          icon,
          size: 12,
          color: color,
        ),
      ),
      label: Text(
        '${card.issuerName} · ****${card.last4}',
        style: TextStyle(
          fontSize: 12,
          fontWeight: FontWeight.w600,
          color: color,
        ),
      ),
      side: BorderSide(color: color.withValues(alpha: 0.3)),
      backgroundColor: color.withValues(alpha: 0.12),
      padding: const EdgeInsets.symmetric(horizontal: 8),
      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
    );
  }
}
