import 'package:file_picker/file_picker.dart';
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 '../../auth/data/auth_providers.dart';
import '../data/import_providers.dart';

/// Accepted MIME types / extensions for recipe file import.
const _allowedExtensions = ['pdf', 'png', 'jpg', 'jpeg', 'webp', 'bmp'];

/// Tab for importing a recipe via file upload or URL.
///
/// On success navigates to `/recipes/create` with the parsed markdown
/// passed as GoRouter `extra`.
class RecipeImportTab extends ConsumerStatefulWidget {
  const RecipeImportTab({super.key});

  @override
  ConsumerState<RecipeImportTab> createState() => _RecipeImportTabState();
}

class _RecipeImportTabState extends ConsumerState<RecipeImportTab> {
  // Shared state
  bool _isLoading = false;
  String? _error;

  // File mode
  PlatformFile? _pickedFile;

  // URL mode
  _Method _method = _Method.file;
  final _urlCtrl = TextEditingController();

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

  // ── File picker ──────────────────────────────────────────────────────────

  Future<void> _pickFile() async {
    final result = await FilePicker.pickFiles(
      type: FileType.custom,
      allowedExtensions: _allowedExtensions,
      withData: true, // needed on Flutter web to get bytes
    );
    if (result == null || result.files.isEmpty) return;
    setState(() {
      _pickedFile = result.files.first;
      _error = null;
    });
  }

  // ── Submit ───────────────────────────────────────────────────────────────

  Future<void> _submit() async {
    setState(() {
      _isLoading = true;
      _error = null;
    });

    try {
      final token = await ref.read(authStateProvider.future);
      final repo = ref.read(importRepositoryProvider);

      final result = _method == _Method.file
          ? await repo.importFile(
              bytes: _pickedFile!.bytes!,
              filename: _pickedFile!.name,
              token: token,
            )
          : await repo.importUrl(
              url: _urlCtrl.text.trim(),
              token: token,
            );

      if (!mounted) return;
      // Explicitly typed as <String, dynamic> so the router's
      // 'is Map<String, dynamic>' runtime check succeeds.
      context.push('/recipes/create', extra: <String, dynamic>{
        'markdown': result.markdown,
        'imageUrl': result.imageUrl,
      }).then((_) => context.go('/recipes'));
    } catch (e) {
      if (!mounted) return;
      setState(() => _error = mapErrorToUserMessage(e, context));
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  bool get _canSubmit {
    if (_isLoading) return false;
    if (_method == _Method.file) return _pickedFile?.bytes != null;
    return _urlCtrl.text.trim().isNotEmpty;
  }

  // ── Build ────────────────────────────────────────────────────────────────

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

    return SingleChildScrollView(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            'Ladda upp en PDF eller bild, eller ange en receptlänk — '
            'receptet importeras och öppnas direkt i redigeringsläget.',
            style: theme.textTheme.bodyMedium
                ?.copyWith(color: theme.colorScheme.onSurfaceVariant),
          ),
          const SizedBox(height: 20),

          // ── Metodväljare ────────────────────────────────────────────────
          SegmentedButton<_Method>(
            segments: const [
              ButtonSegment(
                value: _Method.file,
                label: Text('Fil / PDF'),
                icon: Icon(Icons.upload_file_outlined),
              ),
              ButtonSegment(
                value: _Method.url,
                label: Text('Länk'),
                icon: Icon(Icons.link),
              ),
            ],
            selected: {_method},
            onSelectionChanged: (s) =>
                setState(() => _method = s.first),
          ),
          const SizedBox(height: 24),

          // ── Filläge ─────────────────────────────────────────────────────
          if (_method == _Method.file) ...[
            OutlinedButton.icon(
              onPressed: _isLoading ? null : _pickFile,
              icon: const Icon(Icons.attach_file),
              label: Text(
                _pickedFile == null
                    ? 'Välj fil (PDF, PNG, JPG, WEBP, BMP)'
                    : _pickedFile!.name,
              ),
            ),
            if (_pickedFile != null) ...[
              const SizedBox(height: 8),
              Text(
                '${(_pickedFile!.size / 1024).round()} KB',
                style: theme.textTheme.bodySmall
                    ?.copyWith(color: theme.colorScheme.outline),
              ),
            ],
          ],

          // ── URL-läge ────────────────────────────────────────────────────
          if (_method == _Method.url) ...[
            TextField(
              controller: _urlCtrl,
              keyboardType: TextInputType.url,
              autofocus: true,
              enabled: !_isLoading,
              decoration: const InputDecoration(
                labelText: 'Receptlänk',
                hintText: 'https://exempel.se/recept/...',
                prefixIcon: Icon(Icons.link),
                border: OutlineInputBorder(),
              ),
              onChanged: (_) => setState(() {}),
              onSubmitted: (_) {
                if (_canSubmit) _submit();
              },
            ),
          ],

          const SizedBox(height: 24),

          // ── Laddningsindikator ───────────────────────────────────────────
          if (_isLoading) ...[
            const LinearProgressIndicator(),
            const SizedBox(height: 8),
            Text(
              'Tolkar receptet — detta kan ta upp till en minut...',
              style: theme.textTheme.bodySmall
                  ?.copyWith(color: theme.colorScheme.onSurfaceVariant),
            ),
            const SizedBox(height: 16),
          ],

          // ── Felmeddelande ───────────────────────────────────────────────
          if (_error != null) ...[
            Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: theme.colorScheme.errorContainer,
                borderRadius: BorderRadius.circular(8),
              ),
              child: Row(
                children: [
                  Icon(Icons.error_outline,
                      color: theme.colorScheme.onErrorContainer, size: 18),
                  const SizedBox(width: 8),
                  Expanded(
                    child: Text(
                      _error!,
                      style: theme.textTheme.bodySmall?.copyWith(
                          color: theme.colorScheme.onErrorContainer),
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 16),
          ],

          // ── Knapp ───────────────────────────────────────────────────────
          FilledButton.icon(
            onPressed: _canSubmit ? _submit : null,
            icon: const Icon(Icons.auto_awesome_outlined),
            label: Text(_method == _Method.file
                ? 'Importera fil'
                : 'Importera från länk'),
          ),

          const SizedBox(height: 24),
          const Divider(),
          const SizedBox(height: 12),

          // ── Alternativ ──────────────────────────────────────────────────
          TextButton.icon(
            onPressed: () => context.push('/recipes/create'),
            icon: const Icon(Icons.edit_outlined),
            label: const Text('Skriv in recept istället'),
          ),
        ],
      ),
    );
  }
}

enum _Method { file, url }
