import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lucide_icons/lucide_icons.dart';
import '../../theme/app_colors.dart';
import '../../providers/sakenowa_providers.dart';
import '../../providers/sake_list_provider.dart';
import '../../models/sakenowa/sakenowa_models.dart';
import 'dart:math' as math;

/// さけのわ新規開拓おすすめセクション
///
/// ユーザーの全体的な好みから、まだ飲んでいない新しい日本酒を推薦
/// 「あなたへの新しいおすすめ」形式
class SakenowaNewRecommendationSection extends ConsumerWidget {
  final int displayCount;

  const SakenowaNewRecommendationSection({
    super.key,
    this.displayCount = 5,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final appColors = Theme.of(context).extension<AppColors>()!;
    final userItemsAsync = ref.watch(allSakeItemsProvider);
    final rankingsAsync = ref.watch(sakenowaRankingsProvider);
    final brandsAsync = ref.watch(sakenowaBrandsProvider);
    final chartsAsync = ref.watch(sakenowaFlavorChartsProvider);

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Section Header
        Row(
          children: [
            Icon(LucideIcons.compass, color: appColors.brandPrimary, size: 24),
            const SizedBox(width: 8),
            Text(
              'あなたへの新しいおすすめ',
              style: Theme.of(context).textTheme.titleLarge?.copyWith(
                    fontWeight: FontWeight.bold,
                    color: appColors.brandPrimary,
                  ),
            ),
          ],
        ),
        const SizedBox(height: 4),
        Text(
          'さけのわTOP100から未飲銘柄をセレクト',
          style: Theme.of(context).textTheme.bodySmall?.copyWith(
                color: appColors.textSecondary,
              ),
        ),
        const SizedBox(height: 16),

        // Content
        userItemsAsync.when(
          data: (userItems) {
            if (userItems.isEmpty) {
              return _buildEmptyState(context, appColors);
            }

            return rankingsAsync.when(
              data: (rankings) => brandsAsync.when(
                data: (brands) => chartsAsync.when(
                  data: (charts) => _buildRecommendations(
                    context,
                    appColors,
                    userItems,
                    rankings,
                    brands,
                    charts,
                  ),
                  loading: () => _buildLoadingState(context),
                  error: (e, s) => _buildErrorState(context, appColors, e),
                ),
                loading: () => _buildLoadingState(context),
                error: (e, s) => _buildErrorState(context, appColors, e),
              ),
              loading: () => _buildLoadingState(context),
              error: (e, s) => _buildErrorState(context, appColors, e),
            );
          },
          loading: () => _buildLoadingState(context),
          error: (e, s) => _buildErrorState(context, appColors, e),
        ),
      ],
    );
  }

  Widget _buildEmptyState(BuildContext context, AppColors appColors) {
    return Container(
      padding: const EdgeInsets.all(32),
      decoration: BoxDecoration(
        color: appColors.surfaceSubtle,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: appColors.divider.withValues(alpha: 0.3)),
      ),
      child: Column(
        children: [
          Icon(LucideIcons.packageOpen, size: 48, color: appColors.textSecondary.withValues(alpha: 0.5)),
          const SizedBox(height: 16),
          Text(
            '日本酒を登録すると\nおすすめが表示されます',
            textAlign: TextAlign.center,
            style: TextStyle(
              fontSize: 14,
              color: appColors.textSecondary,
              height: 1.6,
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildLoadingState(BuildContext context) {
    return const Center(
      child: Padding(
        padding: EdgeInsets.all(32.0),
        child: CircularProgressIndicator(),
      ),
    );
  }

  Widget _buildErrorState(BuildContext context, AppColors appColors, Object error) {
    return Container(
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        color: appColors.error.withValues(alpha: 0.1),
        borderRadius: BorderRadius.circular(16),
      ),
      child: Row(
        children: [
          Icon(LucideIcons.alertCircle, color: appColors.error, size: 20),
          const SizedBox(width: 12),
          Expanded(
            child: Text(
              'データの読み込みに失敗しました',
              style: TextStyle(color: appColors.error, fontSize: 13),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildRecommendations(
    BuildContext context,
    AppColors appColors,
    List userItems,
    List<SakenowaRanking> rankings,
    List<SakenowaBrand> brands,
    List<SakenowaFlavorChart> charts,
  ) {
    // Calculate user's overall taste profile (average of all items)
    final userAverageTaste = _calculateUserAverageTaste(userItems);

    // Map data for quick lookup
    final brandMap = {for (var b in brands) b.id: b};
    final chartMap = {for (var c in charts) c.brandId: c};

    // Get owned sake names (lowercase)
    final ownedNames = userItems.map((i) => i.displayData.displayName.toLowerCase()).toSet();

    // Calculate similarity scores for all unowned sake in TOP100
    final recommendations = <_NewRecommendationItem>[];

    for (final ranking in rankings.take(100)) {
      final brand = brandMap[ranking.brandId];
      final chart = chartMap[ranking.brandId];

      if (brand == null || chart == null) continue;

      // Skip owned sake
      if (ownedNames.contains(brand.name.toLowerCase())) continue;

      // Calculate similarity with user's average taste
      final targetTaste = chart.toFiveAxisTaste();
      final similarity = _calculateCosineSimilarity(userAverageTaste, targetTaste);

      recommendations.add(_NewRecommendationItem(
        ranking: ranking,
        brand: brand,
        flavorChart: chart,
        similarityScore: similarity,
        reason: _generateReason(userAverageTaste, targetTaste, similarity),
      ));
    }

    // Sort by similarity score (descending)
    recommendations.sort((a, b) => b.similarityScore.compareTo(a.similarityScore));

    // Take top N items
    final topRecommendations = recommendations.take(displayCount).toList();

    if (topRecommendations.isEmpty) {
      return Container(
        padding: const EdgeInsets.all(32),
        decoration: BoxDecoration(
          color: appColors.surfaceSubtle,
          borderRadius: BorderRadius.circular(16),
          border: Border.all(color: appColors.divider.withValues(alpha: 0.3)),
        ),
        child: Column(
          children: [
            Icon(LucideIcons.checkCircle2, size: 48, color: appColors.brandAccent.withValues(alpha: 0.5)),
            const SizedBox(height: 16),
            Text(
              'TOP100の銘柄は\nすべて登録済みです！',
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 14,
                color: appColors.textSecondary,
                height: 1.6,
              ),
            ),
          ],
        ),
      );
    }

    // Display recommendations
    return Column(
      children: topRecommendations.asMap().entries.map((entry) {
        final index = entry.key;
        final rec = entry.value;
        return Padding(
          padding: EdgeInsets.only(bottom: index < topRecommendations.length - 1 ? 12 : 0),
          child: _buildRecommendationCard(context, appColors, rec, index + 1),
        );
      }).toList(),
    );
  }

  Widget _buildRecommendationCard(
    BuildContext context,
    AppColors appColors,
    _NewRecommendationItem item,
    int rank,
  ) {
    return InkWell(
      onTap: () => _showRecommendationDialog(context, appColors, item),
      borderRadius: BorderRadius.circular(16),
      child: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topLeft,
            end: Alignment.bottomRight,
            colors: [
              appColors.surfaceSubtle,
              appColors.surfaceElevated,
            ],
          ),
          borderRadius: BorderRadius.circular(16),
          border: Border.all(
            color: appColors.brandAccent.withValues(alpha: 0.2),
            width: 1.5,
          ),
          boxShadow: [
            BoxShadow(
              color: appColors.divider.withValues(alpha: 0.1),
              blurRadius: 8,
              offset: const Offset(0, 4),
            ),
          ],
        ),
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // Rank badge
              Container(
                width: 36,
                height: 36,
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    colors: [
                      appColors.brandPrimary,
                      appColors.brandAccent,
                    ],
                  ),
                  shape: BoxShape.circle,
                  boxShadow: [
                    BoxShadow(
                      color: appColors.brandPrimary.withValues(alpha: 0.3),
                      blurRadius: 4,
                      offset: const Offset(0, 2),
                    ),
                  ],
                ),
                child: Center(
                  child: Text(
                    '$rank',
                    style: const TextStyle(
                      color: Colors.white,
                      fontWeight: FontWeight.bold,
                      fontSize: 16,
                    ),
                  ),
                ),
              ),
              const SizedBox(width: 16),

              // Content
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    // Brand name
                    Text(
                      item.brand.name,
                      style: TextStyle(
                        fontSize: 16,
                        fontWeight: FontWeight.bold,
                        color: appColors.textPrimary,
                      ),
                    ),
                    const SizedBox(height: 4),

                    // Ranking position
                    Row(
                      children: [
                        Icon(LucideIcons.trendingUp, size: 12, color: appColors.textSecondary),
                        const SizedBox(width: 4),
                        Text(
                          'さけのわ TOP${item.ranking.rank}',
                          style: TextStyle(
                            fontSize: 11,
                            color: appColors.textSecondary,
                          ),
                        ),
                      ],
                    ),
                    const SizedBox(height: 12),

                    // Similarity score and reason
                    Container(
                      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
                      decoration: BoxDecoration(
                        color: appColors.brandAccent.withValues(alpha: 0.15),
                        borderRadius: BorderRadius.circular(8),
                      ),
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Icon(
                            LucideIcons.sparkles,
                            size: 14,
                            color: appColors.brandAccent,
                          ),
                          const SizedBox(width: 6),
                          Text(
                            '${item.similarityPercent}% ${item.reason}',
                            style: TextStyle(
                              fontSize: 12,
                              fontWeight: FontWeight.w600,
                              color: appColors.brandAccent,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),

              // Arrow icon
              Icon(
                LucideIcons.chevronRight,
                color: appColors.textSecondary.withValues(alpha: 0.4),
                size: 20,
              ),
            ],
          ),
        ),
      ),
    );
  }

  /// Show recommendation detail dialog
  void _showRecommendationDialog(
    BuildContext context,
    AppColors appColors,
    _NewRecommendationItem item,
  ) {
    showDialog(
      context: context,
      builder: (context) => Dialog(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // Header
              Row(
                children: [
                  Container(
                    padding: const EdgeInsets.all(8),
                    decoration: BoxDecoration(
                      color: appColors.brandPrimary.withValues(alpha: 0.1),
                      shape: BoxShape.circle,
                    ),
                    child: Icon(
                      LucideIcons.sparkles,
                      color: appColors.brandPrimary,
                      size: 24,
                    ),
                  ),
                  const SizedBox(width: 12),
                  Expanded(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          item.brand.name,
                          style: TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.bold,
                            color: appColors.textPrimary,
                          ),
                        ),
                        Text(
                          'さけのわ TOP${item.ranking.rank}',
                          style: TextStyle(
                            fontSize: 12,
                            color: appColors.textSecondary,
                          ),
                        ),
                      ],
                    ),
                  ),
                  IconButton(
                    icon: const Icon(LucideIcons.x),
                    onPressed: () => Navigator.of(context).pop(),
                  ),
                ],
              ),
              const SizedBox(height: 24),

              // Similarity score
              Container(
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    colors: [
                      appColors.brandPrimary.withValues(alpha: 0.1),
                      appColors.brandAccent.withValues(alpha: 0.1),
                    ],
                  ),
                  borderRadius: BorderRadius.circular(12),
                ),
                child: Row(
                  children: [
                    Icon(LucideIcons.heart, color: appColors.brandPrimary),
                    const SizedBox(width: 12),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            '${item.similarityPercent}% マッチ',
                            style: TextStyle(
                              fontSize: 18,
                              fontWeight: FontWeight.bold,
                              color: appColors.brandPrimary,
                            ),
                          ),
                          Text(
                            item.reason,
                            style: TextStyle(
                              fontSize: 13,
                              color: appColors.textSecondary,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 24),

              // Flavor chart radar display
              Text(
                'フレーバーチャート',
                style: TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.bold,
                  color: appColors.textPrimary,
                ),
              ),
              const SizedBox(height: 12),
              _buildFlavorChartDisplay(appColors, item.flavorChart),
            ],
          ),
        ),
      ),
    );
  }

  /// Build flavor chart display
  Widget _buildFlavorChartDisplay(
    AppColors appColors,
    SakenowaFlavorChart chart,
  ) {
    final flavorData = [
      ('華やか', chart.f1),
      ('芳醇', chart.f2),
      ('重厚', chart.f3),
      ('穏やか', chart.f4),
      ('軽快', chart.f5),
      ('ドライ', chart.f6),
    ];

    return Column(
      children: flavorData.map((data) {
        final label = data.$1;
        final value = data.$2;
        return Padding(
          padding: const EdgeInsets.only(bottom: 8),
          child: Row(
            children: [
              SizedBox(
                width: 60,
                child: Text(
                  label,
                  style: TextStyle(
                    fontSize: 12,
                    color: appColors.textSecondary,
                  ),
                ),
              ),
              Expanded(
                child: Stack(
                  children: [
                    Container(
                      height: 8,
                      decoration: BoxDecoration(
                        color: appColors.surfaceSubtle,
                        borderRadius: BorderRadius.circular(4),
                      ),
                    ),
                    FractionallySizedBox(
                      widthFactor: value,
                      child: Container(
                        height: 8,
                        decoration: BoxDecoration(
                          gradient: LinearGradient(
                            colors: [
                              appColors.brandPrimary,
                              appColors.brandAccent,
                            ],
                          ),
                          borderRadius: BorderRadius.circular(4),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(width: 8),
              Text(
                '${(value * 100).round()}%',
                style: TextStyle(
                  fontSize: 11,
                  color: appColors.textSecondary,
                  fontWeight: FontWeight.w600,
                ),
              ),
            ],
          ),
        );
      }).toList(),
    );
  }

  /// Calculate user's average taste profile from all items
  Map<String, double> _calculateUserAverageTaste(List userItems) {
    final tasteSums = <String, double>{
      'aroma': 0.0,
      'sweetness': 0.0,
      'acidity': 0.0,
      'bitterness': 0.0,
      'body': 0.0,
    };

    int validCount = 0;

    for (final item in userItems) {
      final tasteData = item.hiddenSpecs.activeTasteData;
      if (tasteData.isNotEmpty) {
        for (final key in tasteSums.keys) {
          tasteSums[key] = (tasteSums[key] ?? 0.0) + (tasteData[key] ?? 0.0);
        }
        validCount++;
      }
    }

    if (validCount == 0) {
      // Return neutral profile if no data
      return tasteSums.map((k, v) => MapEntry(k, 0.5));
    }

    // Calculate averages
    return tasteSums.map((k, v) => MapEntry(k, v / validCount));
  }

  /// Calculate cosine similarity between two taste vectors
  double _calculateCosineSimilarity(
    Map<String, double> taste1,
    Map<String, double> taste2,
  ) {
    final keys = taste1.keys.toSet().intersection(taste2.keys.toSet());
    if (keys.isEmpty) return 0.0;

    double dotProduct = 0.0;
    double magnitude1 = 0.0;
    double magnitude2 = 0.0;

    for (final key in keys) {
      final v1 = taste1[key] ?? 0.0;
      final v2 = taste2[key] ?? 0.0;

      dotProduct += v1 * v2;
      magnitude1 += v1 * v1;
      magnitude2 += v2 * v2;
    }

    final magnitude = math.sqrt(magnitude1) * math.sqrt(magnitude2);
    if (magnitude == 0) return 0.0;

    return (dotProduct / magnitude).clamp(0.0, 1.0);
  }

  /// Generate recommendation reason based on taste similarity
  String _generateReason(
    Map<String, double> userTaste,
    Map<String, double> targetTaste,
    double similarity,
  ) {
    // Find the two most similar axes
    final similarities = <String, double>{};
    for (final key in userTaste.keys) {
      final diff = (userTaste[key]! - (targetTaste[key] ?? 0.5)).abs();
      similarities[key] = 1.0 - diff;
    }

    final sortedAxes = similarities.entries.toList()
      ..sort((a, b) => b.value.compareTo(a.value));

    // Japanese labels
    const axisLabels = {
      'aroma': '香り',
      'sweetness': '甘み',
      'acidity': '酸味',
      'bitterness': 'キレ',
      'body': 'コク',
    };

    if (sortedAxes.isNotEmpty) {
      final topAxis = sortedAxes.first;
      final label = axisLabels[topAxis.key] ?? topAxis.key;
      return '好みの$label';
    }

    return 'おすすめ';
  }
}

/// Internal recommendation item data
class _NewRecommendationItem {
  final SakenowaRanking ranking;
  final SakenowaBrand brand;
  final SakenowaFlavorChart flavorChart;
  final double similarityScore;
  final String reason;

  _NewRecommendationItem({
    required this.ranking,
    required this.brand,
    required this.flavorChart,
    required this.similarityScore,
    required this.reason,
  });

  int get similarityPercent => (similarityScore * 100).round();
}
