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/utils/formatters.dart';
import '../../../core/l10n/l10n.dart';
import '../../auth/data/auth_providers.dart';
import '../data/recipe_providers.dart';
import '../domain/parsed_recipe.dart';

enum _Step { input, review }

class CreateRecipeScreen extends ConsumerStatefulWidget {
  /// Optional markdown to pre-fill the input field, e.g. from import.
  final String? initialMarkdown;

  /// Optional image URL pre-filled from a quick-import result.
  final String? initialImageUrl;

  const CreateRecipeScreen({
    super.key,
    this.initialMarkdown,
    this.initialImageUrl,
  });

  @override
  ConsumerState<CreateRecipeScreen> createState() =>
      _CreateRecipeScreenState();
}

class _CreateRecipeScreenState extends ConsumerState<CreateRecipeScreen> {
  _Step _step = _Step.input;

  // Step 1 — markdown input
  late final TextEditingController _markdownCtrl;
  bool _isParsing = false;
  String? _parseError;

  @override
  void initState() {
    super.initState();
    _markdownCtrl = TextEditingController(text: widget.initialMarkdown ?? '');
  }

  // Step 2 — review state
  ParsedRecipe? _parsed;
  late TextEditingController _nameCtrl;
  late TextEditingController _servingsCtrl;
  late List<bool> _included;

  late Map<int, TextEditingController> _rawNameControllers;
  late Map<int, TextEditingController> _qtyControllers;
  late Map<int, TextEditingController> _unitControllers;
  late Map<int, TextEditingController> _noteControllers;

  bool _isSaving = false;
  String? _saveError;

  @override
  void dispose() {
    _markdownCtrl.dispose();
    if (_step == _Step.review) {
      _nameCtrl.dispose();
      _servingsCtrl.dispose();
      for (final c in _rawNameControllers.values) c.dispose();
      for (final c in _qtyControllers.values) c.dispose();
      for (final c in _unitControllers.values) c.dispose();
      for (final c in _noteControllers.values) c.dispose();
    }
    super.dispose();
  }

  void _initReviewState(ParsedRecipe parsed) {
    _nameCtrl = TextEditingController(text: parsed.name);
    _servingsCtrl = TextEditingController();
    _included = List.generate(parsed.ingredients.length, (_) => true);
    _rawNameControllers = {};
    _qtyControllers = {};
    _unitControllers = {};
    _noteControllers = {};
    for (var i = 0; i < parsed.ingredients.length; i++) {
      final ing = parsed.ingredients[i];
      _rawNameControllers[i] = TextEditingController(text: ing.rawName);
      _qtyControllers[i] = TextEditingController(
        text: ing.quantity > 0 ? formatQuantity(ing.quantity) : '',
      );
      _unitControllers[i] = TextEditingController(text: ing.unit);
      _noteControllers[i] = TextEditingController(text: ing.note ?? '');
    }
  }

  String _formatIngredientName(String value) {
    final trimmed = value.trim();
    if (trimmed.isEmpty) return trimmed;
    return '${trimmed[0].toUpperCase()}${trimmed.substring(1)}';
  }

  Future<void> _parseMarkdown() async {
    final markdown = _markdownCtrl.text.trim();
    if (markdown.isEmpty) {
      setState(() => _parseError = context.l10n.recipeCreateMarkdownHint);
      return;
    }
    setState(() {
      _isParsing = true;
      _parseError = null;
    });
    try {
      final token = await ref.read(authStateProvider.future);
      final parsed = await ref
          .read(recipeRepositoryProvider)
          .parseMarkdown(markdown, token: token);
      _initReviewState(parsed);
      setState(() {
        _parsed = parsed;
        _step = _Step.review;
        _isParsing = false;
      });
    } on ApiException catch (e) {
      if (e.type == ApiErrorType.unauthorized) {
        await ref.read(authStateProvider.notifier).logout();
        return;
      }
      setState(() {
        _parseError = mapErrorToUserMessage(e, context);
        _isParsing = false;
      });
    }
  }

  Future<void> _save() async {
    final name = _nameCtrl.text.trim();
    if (name.isEmpty) {
      setState(() => _saveError = context.l10n.recipeCreateNameRequired);
      return;
    }

    final ingredients = <Map<String, dynamic>>[];
    for (var i = 0; i < _parsed!.ingredients.length; i++) {
      if (!_included[i]) continue;
      final rawName = _formatIngredientName(_rawNameControllers[i]!.text);
      if (rawName.isEmpty) {
        continue;
      }
      final qty = double.tryParse(
            _qtyControllers[i]!.text.trim().replaceAll(',', '.'),
          ) ??
          _parsed!.ingredients[i].quantity;
      final unit = _unitControllers[i]!.text.trim();
      final note = _noteControllers[i]!.text.trim();
      final ing = _parsed!.ingredients[i];
      ingredients.add({
        'rawName': rawName,
        if ((ing.rawLine ?? '').trim().isNotEmpty) 'rawLine': ing.rawLine,
        if (qty > 0) 'quantity': qty,
        if (unit.isNotEmpty) 'unit': unit,
        if (note.isNotEmpty) 'note': note,
      });
    }

    if (ingredients.isEmpty) {
      setState(() => _saveError = 'Lägg till minst en ingrediensrad.');
      return;
    }

    setState(() {
      _isSaving = true;
      _saveError = null;
    });

    try {
      final token = await ref.read(authStateProvider.future);
      final servingsRaw = int.tryParse(_servingsCtrl.text.trim());
      final created = await ref.read(recipeRepositoryProvider).createRecipe(
        {
          'name': name,
          if (_parsed!.description != null) 'description': _parsed!.description,
          if (servingsRaw != null) 'servings': servingsRaw,
          if (_parsed!.instructions != null)
            'instructions': _parsed!.instructions,
          if (widget.initialImageUrl != null && widget.initialImageUrl!.isNotEmpty)
            'imageUrl': widget.initialImageUrl,
          'ingredients': ingredients,
        },
        token: token,
      );
      ref.invalidate(recipesProvider);
      if (mounted) context.go('/recipes/${created.id}');
    } on ApiException catch (e) {
      if (e.type == ApiErrorType.unauthorized) {
        await ref.read(authStateProvider.notifier).logout();
        return;
      }
      setState(() {
        _saveError = mapErrorToUserMessage(e, context);
        _isSaving = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title:
            Text(_step == _Step.input ? context.l10n.recipeCreateTitle : context.l10n.recipeCreateReviewIngredients),
        leading: _step == _Step.review
            ? IconButton(
                icon: const Icon(Icons.arrow_back),
                onPressed: () => setState(() {
                  _step = _Step.input;
                  _nameCtrl.dispose();
                  _servingsCtrl.dispose();
                }),
              )
            : null,
      ),
      body: _step == _Step.input ? _buildInputStep() : _buildReviewStep(),
    );
  }

  Widget _buildInputStep() {
    return Column(
      children: [
        Expanded(
          child: Padding(
            padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
            child: TextField(
              controller: _markdownCtrl,
              maxLines: null,
              expands: true,
              textAlignVertical: TextAlignVertical.top,
              decoration: InputDecoration(
                hintText: context.l10n.recipeCreateMarkdownPlaceholder,
                border: const OutlineInputBorder(),
                alignLabelWithHint: true,
              ),
            ),
          ),
        ),
        if (_parseError != null)
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: Text(
              _parseError!,
              style: TextStyle(color: Theme.of(context).colorScheme.error),
            ),
          ),
        Padding(
          padding: const EdgeInsets.all(16),
          child: SizedBox(
            width: double.infinity,
            child: FilledButton(
              onPressed: _isParsing ? null : _parseMarkdown,
              child: _isParsing
                  ? const SizedBox(
                      height: 18,
                      width: 18,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : Text(context.l10n.recipeCreateReviewIngredients),
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildReviewStep() {
    final parsed = _parsed!;
    return Column(
      children: [
        Expanded(
          child: ListView(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
            children: [
              TextField(
                controller: _nameCtrl,
                decoration: InputDecoration(labelText: context.l10n.recipeEditNameLabel),
              ),
              const SizedBox(height: 12),
              TextField(
                controller: _servingsCtrl,
                decoration: InputDecoration(
                    labelText: context.l10n.recipeEditServingsLabel),
                keyboardType: TextInputType.number,
              ),
              if (parsed.ingredients.isNotEmpty) ...[
                const SizedBox(height: 20),
                Text(context.l10n.recipeEditIngredientsLabel,
                    style: Theme.of(context).textTheme.titleMedium),
                const SizedBox(height: 4),
                Text(
                  context.l10n.recipeCreateIngredientsHint,
                  style: Theme.of(context).textTheme.bodySmall,
                ),
                const SizedBox(height: 8),
                ...List.generate(
                    parsed.ingredients.length,
                    (i) => _buildIngredientRow(i, parsed.ingredients[i])),
              ],
              const SizedBox(height: 8),
            ],
          ),
        ),
        if (_saveError != null)
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: Text(
              _saveError!,
              style: TextStyle(color: Theme.of(context).colorScheme.error),
            ),
          ),
        Padding(
          padding: const EdgeInsets.all(16),
          child: SizedBox(
            width: double.infinity,
            child: FilledButton(
              onPressed: _isSaving ? null : _save,
              child: _isSaving
                  ? const SizedBox(
                      height: 18,
                      width: 18,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : Text(context.l10n.recipeCreateSaveAction),
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildIngredientRow(int index, ParsedIngredient ing) {
    final isIncluded = _included[index];
    final suggestionText = ing.suggestions.isEmpty
        ? null
        : 'Förslag: ${ing.suggestions.take(3).map((s) => s.productName).join(', ')}';

    return Card(
      margin: const EdgeInsets.symmetric(vertical: 4),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          CheckboxListTile(
            value: isIncluded,
            onChanged: (v) => setState(() => _included[index] = v ?? false),
            title: ing.alternatives.length > 1
              ? Wrap(
                spacing: 4,
                children: ing.alternatives
                  .map((alt) => Chip(
                      label: Text(alt),
                      padding: EdgeInsets.zero,
                      materialTapTargetSize:
                        MaterialTapTargetSize.shrinkWrap,
                    ))
                  .toList(),
                )
              : Text(_formatIngredientName(ing.rawName)),
            subtitle: suggestionText == null
                ? null
                : Text(
                    suggestionText,
                    style: TextStyle(
                      color: Theme.of(context).colorScheme.onSurfaceVariant,
                      fontSize: 12,
                    ),
                  ),
          ),
          if (isIncluded)
            Padding(
              padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
              child: Column(
                children: [
                  TextField(
                    controller: _rawNameControllers[index],
                    decoration: const InputDecoration(
                      labelText: 'Ingrediens',
                      isDense: true,
                      border: OutlineInputBorder(),
                      contentPadding:
                          EdgeInsets.symmetric(horizontal: 8, vertical: 8),
                    ),
                  ),
                  const SizedBox(height: 8),
                  Row(
                    children: [
                      SizedBox(
                        width: 72,
                        child: TextField(
                          controller: _qtyControllers[index],
                          decoration: const InputDecoration(
                            labelText: 'Mängd',
                            isDense: true,
                            border: OutlineInputBorder(),
                            contentPadding:
                                EdgeInsets.symmetric(horizontal: 8, vertical: 8),
                          ),
                          keyboardType: const TextInputType.numberWithOptions(
                              decimal: true),
                        ),
                      ),
                      const SizedBox(width: 8),
                      SizedBox(
                        width: 72,
                        child: TextField(
                          controller: _unitControllers[index],
                          decoration: const InputDecoration(
                            labelText: 'Enhet',
                            isDense: true,
                            border: OutlineInputBorder(),
                            contentPadding:
                                EdgeInsets.symmetric(horizontal: 8, vertical: 8),
                          ),
                        ),
                      ),
                      const SizedBox(width: 8),
                      Expanded(
                        child: TextField(
                          controller: _noteControllers[index],
                          decoration: const InputDecoration(
                            labelText: 'Not',
                            isDense: true,
                            border: OutlineInputBorder(),
                            contentPadding:
                                EdgeInsets.symmetric(horizontal: 8, vertical: 8),
                          ),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
            ),
        ],
      ),
    );
  }
}
