import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:url_launcher/url_launcher.dart';

import 'package:lunchpick/core/constants/app_colors.dart';
import 'package:lunchpick/core/constants/app_typography.dart';
import 'package:lunchpick/domain/entities/restaurant.dart';
import 'package:lunchpick/presentation/providers/restaurant_provider.dart';
import 'edit_restaurant_dialog.dart';

/// 맛집 카드 위젯
/// [lastVisitDate]를 외부에서 주입받아 리스트 렌더링 최적화
class RestaurantCard extends ConsumerWidget {
  final Restaurant restaurant;
  final double? distanceKm;
  final DateTime? lastVisitDate;

  const RestaurantCard({
    super.key,
    required this.restaurant,
    this.distanceKm,
    this.lastVisitDate,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final isDark = Theme.of(context).brightness == Brightness.dark;

    final hasNaverUrl = restaurant.naverUrl != null &&
        restaurant.naverUrl!.isNotEmpty;

    return Card(
      margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      child: InkWell(
        onTap: hasNaverUrl ? () => _openNaverUrl(restaurant.naverUrl!) : null,
        borderRadius: BorderRadius.circular(12),
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  // 카테고리 아이콘
                  Container(
                    width: 48,
                    height: 48,
                    decoration: BoxDecoration(
                      color: AppColors.lightPrimary.withOpacity(0.1),
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: Icon(
                      _getCategoryIcon(restaurant.category),
                      color: AppColors.lightPrimary,
                      size: 24,
                    ),
                  ),
                  const SizedBox(width: 12),

                  // 가게 정보
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          children: [
                            Expanded(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text(
                                    restaurant.name,
                                    style: AppTypography.heading2(isDark),
                                    overflow: TextOverflow.ellipsis,
                                  ),
                                  const SizedBox(height: 4),
                                  Row(
                                    children: [
                                      Text(
                                        restaurant.category,
                                        style: AppTypography.body2(isDark),
                                      ),
                                      if (restaurant.subCategory !=
                                          restaurant.category) ...[
                                        Text(
                                          ' • ',
                                          style: AppTypography.body2(isDark),
                                        ),
                                        Text(
                                          restaurant.subCategory,
                                          style: AppTypography.body2(isDark),
                                        ),
                                      ],
                                    ],
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),

                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      _BadgesRow(
                        distanceKm: distanceKm,
                        needsAddressVerification:
                            restaurant.needsAddressVerification,
                        isDark: isDark,
                      ),
                      const SizedBox(height: 8),
                      // 더보기 버튼
                      PopupMenuButton<_RestaurantMenuAction>(
                        icon: Icon(
                          Icons.more_vert,
                          color: isDark
                              ? AppColors.darkTextSecondary
                              : AppColors.lightTextSecondary,
                        ),
                        offset: const Offset(0, 8),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(12),
                        ),
                        onSelected: (action) =>
                            _handleMenuAction(action, context, ref),
                        itemBuilder: (context) => [
                          const PopupMenuItem(
                            value: _RestaurantMenuAction.edit,
                            child: Row(
                              children: [
                                Icon(Icons.edit, color: AppColors.lightPrimary),
                                SizedBox(width: 8),
                                Text('수정'),
                              ],
                            ),
                          ),
                          const PopupMenuItem(
                            value: _RestaurantMenuAction.delete,
                            child: Row(
                              children: [
                                Icon(Icons.delete, color: AppColors.lightError),
                                SizedBox(width: 8),
                                Text('삭제'),
                              ],
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),

              if (restaurant.description != null) ...[
                const SizedBox(height: 12),
                Text(
                  restaurant.description!,
                  style: AppTypography.body2(isDark),
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                ),
              ],

              const SizedBox(height: 12),

              // 주소
              Row(
                children: [
                  Icon(
                    Icons.location_on,
                    size: 16,
                    color: isDark
                        ? AppColors.darkTextSecondary
                        : AppColors.lightTextSecondary,
                  ),
                  const SizedBox(width: 4),
                  Expanded(
                    child: Text(
                      restaurant.roadAddress,
                      style: AppTypography.caption(isDark),
                      overflow: TextOverflow.ellipsis,
                    ),
                  ),
                ],
              ),

              // 마지막 방문일
              if (lastVisitDate != null)
                Padding(
                  padding: const EdgeInsets.only(top: 8),
                  child: Row(
                    children: [
                      Icon(
                        Icons.schedule,
                        size: 16,
                        color: isDark
                            ? AppColors.darkTextSecondary
                            : AppColors.lightTextSecondary,
                      ),
                      const SizedBox(width: 4),
                      Text(
                        _formatLastVisit(lastVisitDate!),
                        style: AppTypography.caption(isDark),
                      ),
                    ],
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _openNaverUrl(String url) async {
    final uri = Uri.tryParse(url);
    if (uri == null) return;

    try {
      await launchUrl(uri, mode: LaunchMode.externalApplication);
    } catch (_) {
      // 웹 환경에서 실패 시 platformDefault 모드로 재시도
      await launchUrl(uri, mode: LaunchMode.platformDefault);
    }
  }

  IconData _getCategoryIcon(String category) {
    switch (category) {
      case '한식':
        return Icons.rice_bowl;
      case '중식':
        return Icons.ramen_dining;
      case '일식':
        return Icons.set_meal;
      case '양식':
        return Icons.restaurant;
      case '카페':
        return Icons.coffee;
      case '분식':
        return Icons.fastfood;
      case '치킨':
        return Icons.egg;
      case '피자':
        return Icons.local_pizza;
      default:
        return Icons.restaurant_menu;
    }
  }

  String _formatLastVisit(DateTime date) {
    final daysSinceVisit = DateTime.now().difference(date).inDays;
    return daysSinceVisit == 0 ? '오늘 방문' : '$daysSinceVisit일 전 방문';
  }

  void _handleMenuAction(
    _RestaurantMenuAction action,
    BuildContext context,
    WidgetRef ref,
  ) async {
    switch (action) {
      case _RestaurantMenuAction.edit:
        await showDialog<bool>(
          context: context,
          builder: (context) => EditRestaurantDialog(restaurant: restaurant),
        );
        break;
      case _RestaurantMenuAction.delete:
        final confirmed = await showDialog<bool>(
          context: context,
          builder: (context) => AlertDialog(
            title: const Text('맛집 삭제'),
            content: Text('${restaurant.name}을(를) 삭제하시겠습니까?'),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(context, false),
                child: const Text('취소'),
              ),
              TextButton(
                onPressed: () => Navigator.pop(context, true),
                child: const Text(
                  '삭제',
                  style: TextStyle(color: AppColors.lightError),
                ),
              ),
            ],
          ),
        );

        if (confirmed == true) {
          await ref
              .read(restaurantNotifierProvider.notifier)
              .deleteRestaurant(restaurant.id);
        }
        break;
    }
  }
}

class _DistanceBadge extends StatelessWidget {
  final double distanceKm;
  final bool isDark;

  const _DistanceBadge({required this.distanceKm, required this.isDark});

  @override
  Widget build(BuildContext context) {
    final text = _formatDistance(distanceKm);
    final isFar = distanceKm * 1000 >= 2000;
    final Color bgColor;
    final Color textColor;

    if (isFar) {
      bgColor = isDark
          ? AppColors.darkError.withOpacity(0.15)
          : AppColors.lightError.withOpacity(0.15);
      textColor = AppColors.lightError;
    } else {
      bgColor = isDark
          ? AppColors.darkPrimary.withOpacity(0.12)
          : AppColors.lightPrimary.withOpacity(0.12);
      textColor = AppColors.lightPrimary;
    }

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
      decoration: BoxDecoration(
        color: bgColor,
        borderRadius: BorderRadius.circular(16),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.place, size: 16, color: textColor),
          const SizedBox(width: 4),
          Text(
            text,
            style: AppTypography.caption(
              isDark,
            ).copyWith(color: textColor, fontWeight: FontWeight.w600),
          ),
        ],
      ),
    );
  }

  String _formatDistance(double distanceKm) {
    final meters = distanceKm * 1000;
    if (meters >= 2000) {
      return '2.0km 이상';
    }
    if (meters >= 1000) {
      return '${distanceKm.toStringAsFixed(1)}km';
    }
    return '${meters.round()}m';
  }
}

enum _RestaurantMenuAction { edit, delete }

class _BadgesRow extends StatelessWidget {
  final double? distanceKm;
  final bool needsAddressVerification;
  final bool isDark;

  const _BadgesRow({
    required this.distanceKm,
    required this.needsAddressVerification,
    required this.isDark,
  });

  @override
  Widget build(BuildContext context) {
    final badges = <Widget>[];
    if (needsAddressVerification) {
      badges.add(_AddressVerificationChip(isDark: isDark));
    }
    if (distanceKm != null) {
      badges.add(_DistanceBadge(distanceKm: distanceKm!, isDark: isDark));
    }

    if (badges.isEmpty) return const SizedBox.shrink();

    return Wrap(
      spacing: 8,
      runSpacing: 4,
      alignment: WrapAlignment.end,
      children: badges,
    );
  }
}

class _AddressVerificationChip extends StatelessWidget {
  final bool isDark;

  const _AddressVerificationChip({required this.isDark});

  @override
  Widget build(BuildContext context) {
    final bgColor = isDark
        ? AppColors.darkError.withOpacity(0.12)
        : AppColors.lightError.withOpacity(0.12);
    final textColor = isDark ? AppColors.darkError : AppColors.lightError;

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
      decoration: BoxDecoration(
        color: bgColor,
        borderRadius: BorderRadius.circular(16),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.error_outline, size: 16, color: textColor),
          const SizedBox(width: 4),
          Text(
            '주소확인',
            style: TextStyle(color: textColor, fontWeight: FontWeight.w600),
          ),
        ],
      ),
    );
  }
}
