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

import '../../../core/api/api_error_mapper.dart';
import '../../../core/api/api_exception.dart';
import '../../../core/ui/async_state_views.dart';
import '../../auth/data/auth_providers.dart';
import '../data/recipe_providers.dart';
import '../domain/recipe.dart';
import '../domain/inventory_preview.dart';

class RecipeDetailScreen extends ConsumerWidget {
  final int recipeId;

  const RecipeDetailScreen({super.key, required this.recipeId});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final recipeAsync = ref.watch(recipeDetailProvider(recipeId));

    return Scaffold(
      appBar: AppBar(
        title: Text(recipeAsync.maybeWhen(data: (d) => d, orElse: () => null)?.title ?? 'Recept'),
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () => context.go('/recipes'),
          tooltip: 'Tillbaka till receptlistan',
        ),
        actions: recipeAsync.maybeWhen(data: (d) => d, orElse: () => null) == null
            ? []
            : [
                IconButton(
                  tooltip: 'Redigera',
                  icon: const Icon(Icons.edit_outlined),
                  onPressed: () =>
                      context.push('/recipes/$recipeId/edit'),
                ),
                IconButton(
                  tooltip: 'Gå till inventarie',
                  icon: const Icon(Icons.inventory_2_outlined),
                  onPressed: () => context.go('/inventory'),
                ),
                _DeleteButton(recipe: recipeAsync.value!),
              ],
      ),
      body: recipeAsync.when(
        loading: () => const LoadingStateView(label: 'Laddar recept...'),
        error: (error, _) => ErrorStateView(
          message: mapErrorToUserMessage(error, context),
          onRetry: () => ref.invalidate(recipeDetailProvider(recipeId)),
        ),
        data: (recipe) => CustomScrollView(
          physics: const BouncingScrollPhysics(),
          slivers: [
            SliverAppBar(
              expandedHeight: MediaQuery.of(context).size.height * 2 / 3,
              flexibleSpace: FlexibleSpaceBar(
                background: recipe.imageUrl != null
                  ? Image.network(
                      recipe.imageUrl!,
                      fit: BoxFit.cover,
                    )
                  : Container(color: Colors.grey[200]),
              ),
              pinned: true,
              floating: false,
            ),
            SliverToBoxAdapter(
              child: Container(
                decoration: const BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(20),
                    topRight: Radius.circular(20),
                  ),
                ),
                child: _RecipeBody(recipe: recipe),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _DeleteButton extends ConsumerWidget {
  final Recipe recipe;

  const _DeleteButton({required this.recipe});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return IconButton(
      tooltip: 'Ta bort',
      icon: const Icon(Icons.delete_outline),
      onPressed: () => _confirmDelete(context, ref),
    );
  }

  Future<void> _confirmDelete(BuildContext context, WidgetRef ref) async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (_) => AlertDialog(
        title: const Text('Ta bort recept?'),
        content: Text(
            'Vill du ta bort "${recipe.title}"? Åtgärden kan inte ångras.'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: const Text('Avbryt'),
          ),
          FilledButton(
            style: FilledButton.styleFrom(
                backgroundColor: Theme.of(context).colorScheme.error),
            onPressed: () => Navigator.pop(context, true),
            child: const Text('Ta bort'),
          ),
        ],
      ),
    );

    if (confirmed != true || !context.mounted) return;

    try {
      final token = await ref.read(authStateProvider.future);
      await ref.read(recipeRepositoryProvider).deleteRecipe(recipe.id,
          token: token);
      ref.invalidate(recipesProvider);
      if (context.mounted) context.go('/recipes');
    } on ApiException catch (e) {
      if (!context.mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(mapErrorToUserMessage(e, context))),
      );
    }
  }
}

class _RecipeBody extends StatelessWidget {
  final Recipe recipe;

  const _RecipeBody({required this.recipe});

  String _formatQty(double qty) {
    if (qty == 0) return '';
    return qty == qty.truncateToDouble()
        ? qty.toInt().toString()
        : qty.toString();
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return SingleChildScrollView(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Bilden visas endast som bakgrund i detaljvyn
          Text(recipe.title, style: theme.textTheme.headlineSmall),
          if (recipe.description != null) ...[
            const SizedBox(height: 8),
            Text(recipe.description!,
                style: theme.textTheme.bodyMedium
                    ?.copyWith(color: theme.colorScheme.onSurfaceVariant)),
          ],
          if (recipe.servings != null) ...[
            const SizedBox(height: 8),
            Row(
              children: [
                const Icon(Icons.people_outline, size: 16),
                const SizedBox(width: 4),
                Text('${recipe.servings} portioner',
                    style: theme.textTheme.bodySmall),
              ],
            ),
          ],
          if (recipe.ingredients.isNotEmpty) ...[
            const SizedBox(height: 24),
            Text('Ingredienser', style: theme.textTheme.titleMedium),
            const SizedBox(height: 8),
            ...recipe.ingredients.map((ing) {
              final qtyStr = _formatQty(ing.quantity);
              final parts = [
                if (qtyStr.isNotEmpty) qtyStr,
                if (ing.unit.isNotEmpty) ing.unit,
                ing.productName,
                if (ing.note != null) '(${ing.note})',
              ];
              return Padding(
                padding: const EdgeInsets.symmetric(vertical: 3),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text('• '),
                    Expanded(child: Text(parts.join(' '))),
                  ],
                ),
              );
            }),
          ],
          if (recipe.instructions != null &&
              recipe.instructions!.isNotEmpty) ...[
            const SizedBox(height: 24),
            Text('Tillvägagångssätt', style: theme.textTheme.titleMedium),
            const SizedBox(height: 8),
            Text(recipe.instructions!,
                style: theme.textTheme.bodyMedium
                    ?.copyWith(height: 1.6)),
          ],
          _InventoryPreviewSection(recipeId: recipe.id),
          const SizedBox(height: 40),
        ],
      ),
    );
  }
}

class _InventoryPreviewSection extends ConsumerStatefulWidget {
  final int recipeId;

  const _InventoryPreviewSection({required this.recipeId});

  @override
  ConsumerState<_InventoryPreviewSection> createState() =>
      _InventoryPreviewSectionState();
}

class _InventoryPreviewSectionState
    extends ConsumerState<_InventoryPreviewSection> {
  bool _loaded = false;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SizedBox(height: 24),
        Row(
          children: [
            Text('Vad saknas?', style: theme.textTheme.titleMedium),
            const Spacer(),
            if (!_loaded)
              FilledButton.tonalIcon(
                onPressed: () => setState(() => _loaded = true),
                icon: const Icon(Icons.search, size: 16),
                label: const Text('Kontrollera inventarie'),
              ),
            if (_loaded)
              IconButton(
                tooltip: 'Uppdatera',
                icon: const Icon(Icons.refresh),
                onPressed: () {
                  ref.invalidate(inventoryPreviewProvider(widget.recipeId));
                },
              ),
          ],
        ),
        if (_loaded) _InventoryPreviewResults(recipeId: widget.recipeId),
      ],
    );
  }
}

class _InventoryPreviewResults extends ConsumerWidget {
  final int recipeId;

  const _InventoryPreviewResults({required this.recipeId});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final previewAsync = ref.watch(inventoryPreviewProvider(recipeId));
    final theme = Theme.of(context);

    return previewAsync.when(
      loading: () => const Padding(
        padding: EdgeInsets.symmetric(vertical: 16),
        child: Center(child: CircularProgressIndicator()),
      ),
      error: (error, _) => Padding(
        padding: const EdgeInsets.only(top: 8),
        child: Text(
          mapErrorToUserMessage(error, context),
          style: TextStyle(color: theme.colorScheme.error),
        ),
      ),
      data: (preview) {
        final summary = preview.summary;
        return Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const SizedBox(height: 8),
            _SummaryChips(summary: summary),
            const SizedBox(height: 12),
            ...preview.ingredients.map(
              (ing) => _IngredientPreviewRow(ingredient: ing),
            ),
          ],
        );
      },
    );
  }
}

class _SummaryChips extends StatelessWidget {
  final PreviewSummary summary;

  const _SummaryChips({required this.summary});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final cs = theme.colorScheme;
    return Wrap(
      spacing: 8,
      runSpacing: 4,
      children: [
        if (summary.canCookExactly)
          Chip(
            avatar: Icon(Icons.check_circle,
                color: cs.onPrimary, size: 16),
            label: const Text('Kan lagas!'),
            backgroundColor: cs.primary,
            labelStyle: TextStyle(color: cs.onPrimary),
          )
        else
          Chip(
            avatar: Icon(Icons.warning_amber,
                color: cs.onErrorContainer, size: 16),
            label: Text('Saknar ${summary.missingCount} ingrediens'
                '${summary.missingCount == 1 ? '' : 'er'}'),
            backgroundColor: cs.errorContainer,
            labelStyle: TextStyle(color: cs.onErrorContainer),
          ),
        if (summary.unitMismatchCount > 0)
          Chip(
            avatar: Icon(Icons.swap_horiz,
                color: cs.onTertiaryContainer, size: 16),
            label: Text('${summary.unitMismatchCount} enhetsmismatch'),
            backgroundColor: cs.tertiaryContainer,
            labelStyle: TextStyle(color: cs.onTertiaryContainer),
          ),
      ],
    );
  }
}

class _IngredientPreviewRow extends StatelessWidget {
  final IngredientPreview ingredient;

  const _IngredientPreviewRow({required this.ingredient});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final cs = theme.colorScheme;

    final (icon, color) = switch (ingredient.status) {
      IngredientStatus.enough => (Icons.check_circle_outline, cs.primary),
      IngredientStatus.unitMismatch => (
          Icons.swap_horiz,
          cs.tertiary,
        ),
      IngredientStatus.missing => (Icons.cancel_outlined, cs.error),
    };

    String _fmt(double v) =>
        v == v.truncateToDouble() ? v.toInt().toString() : v.toString();

    final requiredStr =
        '${_fmt(ingredient.requiredQuantity)} ${ingredient.requiredUnit}'.trim();
    final availableStr =
        '${_fmt(ingredient.availableQuantity)} ${ingredient.requiredUnit}'.trim();

    final subtitle = switch (ingredient.status) {
      IngredientStatus.enough => 'Tillgängligt: $availableStr',
      IngredientStatus.missing => ingredient.availableQuantity > 0
          ? 'Saknar ${_fmt(ingredient.missingQuantity)} ${ingredient.requiredUnit} '
              '(har $availableStr)'
          : 'Saknas helt',
      IngredientStatus.unitMismatch =>
        'Annan enhet i lager – kontrollera manuellt',
    };

    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 4),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Icon(icon, color: color, size: 18),
          const SizedBox(width: 8),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '${ingredient.productName}'
                  '${ingredient.note != null ? ' (${ingredient.note})' : ''}'
                  ' – $requiredStr',
                  style: theme.textTheme.bodyMedium,
                ),
                Text(
                  subtitle,
                  style: theme.textTheme.bodySmall
                      ?.copyWith(color: color),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
