import 'dart:async';

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

import '../../../core/api/api_error_mapper.dart';
import 'admin_form_shared.dart';
import '../data/admin_repository.dart';
import '../domain/admin_product.dart';
import '../domain/receipt_alias.dart';

class AdminAliasesPanel extends ConsumerStatefulWidget {
  final bool embedded;

  const AdminAliasesPanel({super.key, this.embedded = false});

  @override
  ConsumerState<AdminAliasesPanel> createState() => _AdminAliasesPanelState();
}

class _AdminAliasesPanelState extends ConsumerState<AdminAliasesPanel> {
  bool _isLoading = true;
  bool _isSaving = false;
  String? _error;
  String _search = '';
  List<ReceiptAlias> _aliases = [];
  List<AdminProduct> _products = [];
  int? _scopeChangedAliasId;
  bool? _scopeChangedToGlobal;
  Timer? _scopeChangedTimer;

  final TextEditingController _aliasController = TextEditingController();
  int? _selectedProductId;

  @override
  void initState() {
    super.initState();
    _load();
  }

  @override
  void dispose() {
    _scopeChangedTimer?.cancel();
    _aliasController.dispose();
    super.dispose();
  }

  void _markScopeChanged(int aliasId, bool isGlobal) {
    _scopeChangedTimer?.cancel();
    setState(() {
      _scopeChangedAliasId = aliasId;
      _scopeChangedToGlobal = isGlobal;
    });
    _scopeChangedTimer = Timer(const Duration(seconds: 6), () {
      if (!mounted) return;
      setState(() {
        _scopeChangedAliasId = null;
        _scopeChangedToGlobal = null;
      });
    });
  }

  Future<void> _load() async {
    setState(() {
      _isLoading = true;
      _error = null;
    });
    try {
      final results = await Future.wait<dynamic>([
        ref.read(adminRepositoryProvider).listReceiptAliases(),
        ref.read(adminRepositoryProvider).listGlobalProducts(),
      ]);
      if (!mounted) return;
      setState(() {
        _aliases = (results[0] as List<ReceiptAlias>)
          ..sort((a, b) => a.receiptName.compareTo(b.receiptName));
        _products = (results[1] as List<AdminProduct>)
          ..sort(
            (a, b) =>
                a.displayName.toLowerCase().compareTo(b.displayName.toLowerCase()),
          );
      });
    } catch (e) {
      if (!mounted) return;
      setState(() => _error = mapErrorToUserMessage(e, context));
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  Future<void> _upsertAlias() async {
    final rawAlias = _aliasController.text.trim();
    final productId = _selectedProductId;
    if (rawAlias.isEmpty || productId == null) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Ange alias och välj produkt.')),
      );
      return;
    }

    setState(() => _isSaving = true);
    try {
      final repo = ref.read(adminRepositoryProvider);
      await repo.upsertReceiptAlias(
        receiptName: rawAlias,
        productId: productId,
        isGlobal: true,
      );

      if (!mounted) return;
      _aliasController.clear();
      setState(() {
        _selectedProductId = null;
      });
      await _load();
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Alias sparad.')),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        buildCopyableErrorSnackBar(context, mapErrorToUserMessage(e, context)),
      );
    } finally {
      if (mounted) setState(() => _isSaving = false);
    }
  }

  Future<void> _editAlias(ReceiptAlias alias) async {
    String aliasName = alias.receiptName;
    int selectedProductId = alias.productId;
    bool isGlobal = alias.isGlobal;
    final nameController = TextEditingController(text: alias.receiptName);

    final result = await showDialog<bool>(
      context: context,
      builder: (dialogContext) => StatefulBuilder(
        builder: (dialogContext, setDialogState) => AlertDialog(
          title: const Text('Redigera alias'),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: nameController,
                decoration: const InputDecoration(
                  labelText: 'Kvittonamn (alias)',
                  border: OutlineInputBorder(),
                ),
                onChanged: (value) => aliasName = value,
              ),
              const SizedBox(height: 12),
              DropdownButtonFormField<int>(
                initialValue: selectedProductId,
                decoration: const InputDecoration(
                  labelText: 'Produkt',
                  border: OutlineInputBorder(),
                ),
                items: _products
                    .map(
                      (product) => DropdownMenuItem<int>(
                        value: product.id,
                        child: Text(product.displayName),
                      ),
                    )
                    .toList(),
                onChanged: (value) {
                  if (value == null) return;
                  setDialogState(() => selectedProductId = value);
                },
              ),
              const SizedBox(height: 12),
              SwitchListTile.adaptive(
                contentPadding: EdgeInsets.zero,
                title: const Text('Globalt alias'),
                subtitle: Text(
                  alias.isGlobal
                      ? 'Aliaset är redan globalt.'
                      : 'Du kan göra privata alias globala.',
                ),
                value: isGlobal,
                onChanged: alias.isGlobal
                    ? null
                    : (value) {
                        if (!value) return;
                        setDialogState(() => isGlobal = true);
                      },
              ),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(dialogContext, false),
              child: const Text('Avbryt'),
            ),
            FilledButton(
              onPressed: () => Navigator.pop(dialogContext, true),
              child: const Text('Spara'),
            ),
          ],
        ),
      ),
    );

    nameController.dispose();
    if (result != true || !mounted) return;

    final trimmedAlias = aliasName.trim();
    final scopeChanged = isGlobal != alias.isGlobal;
    if (trimmedAlias.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Aliasnamn kan inte vara tomt.')),
      );
      return;
    }

    setState(() => _isSaving = true);
    try {
      await ref.read(adminRepositoryProvider).updateReceiptAlias(
            alias.id,
            receiptName: trimmedAlias,
            productId: selectedProductId,
            isGlobal: isGlobal,
          );
      if (!mounted) return;
      await _load();
      if (!mounted) return;
      if (scopeChanged) {
        _markScopeChanged(alias.id, isGlobal);
      }
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Alias uppdaterat.')),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        buildCopyableErrorSnackBar(context, mapErrorToUserMessage(e, context)),
      );
    } finally {
      if (mounted) setState(() => _isSaving = false);
    }
  }

  Future<void> _removeAlias(ReceiptAlias alias) async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (dialogContext) => AlertDialog(
        title: const Text('Ta bort alias'),
        content: Text('Ta bort alias "${alias.receiptName}"?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(dialogContext, false),
            child: const Text('Avbryt'),
          ),
          FilledButton(
            onPressed: () => Navigator.pop(dialogContext, true),
            child: const Text('Ta bort'),
          ),
        ],
      ),
    );

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

    try {
      await ref.read(adminRepositoryProvider).removeReceiptAlias(alias.id);
      if (!mounted) return;
      await _load();
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Alias borttaget.')),
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        buildCopyableErrorSnackBar(context, mapErrorToUserMessage(e, context)),
      );
    }
  }

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

    if (_isLoading) {
      return const Center(child: CircularProgressIndicator());
    }

    if (_error != null) {
      return buildCopyableErrorPanel(
        context: context,
        message: _error!,
        onRetry: _load,
        title: 'Kunde inte läsa alias',
      );
    }

    final filteredAliases = _aliases.where((alias) {
      final query = _search.trim().toLowerCase();
      if (query.isEmpty) return true;
      return alias.receiptName.contains(query) ||
          alias.displayProductName.toLowerCase().contains(query);
    }).toList();

    final productById = <int, AdminProduct>{
      for (final product in _products) product.id: product,
    };

    Widget buildAliasCard(ReceiptAlias alias) {
      final product = productById[alias.productId];
      final categoryPath = product?.categoryPath?.trim();
      
      return Card(
        child: ListTile(
          leading: const Icon(Icons.link_outlined),
          title: Row(
            children: [
              Expanded(child: Text(alias.receiptName, style: const TextStyle(fontWeight: FontWeight.w500))),
              if (categoryPath != null && categoryPath.isNotEmpty)
                buildCategoryPathChip(categoryPath),
            ],
          ),
          subtitle: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(
                '→ ${alias.displayProductName}',
                style: const TextStyle(fontWeight: FontWeight.w400),
              ),
              Text(
                'Produkt-ID: ${alias.productId}',
                style: TextStyle(
                  fontSize: 11,
                  color: Theme.of(context).colorScheme.outline,
                ),
              ),
              const SizedBox(height: 4),
              Chip(
                visualDensity: VisualDensity.compact,
                label: Text(alias.isGlobal ? 'Global' : 'Privat'),
              ),
              if (_scopeChangedAliasId == alias.id && _scopeChangedToGlobal != null)
                Chip(
                  visualDensity: VisualDensity.compact,
                  avatar: const Icon(Icons.sync_alt, size: 16),
                  label: Text(
                    _scopeChangedToGlobal == true
                        ? 'Bytt till Global'
                        : 'Bytt till Privat',
                  ),
                ),
            ],
          ),
          trailing: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              IconButton(
                onPressed: _isSaving ? null : () => _editAlias(alias),
                icon: const Icon(Icons.edit_outlined),
                tooltip: 'Redigera alias',
              ),
              IconButton(
                onPressed: () => _removeAlias(alias),
                icon: const Icon(Icons.delete_outline),
                tooltip: 'Ta bort alias',
                color: Theme.of(context).colorScheme.error,
              ),
            ],
          ),
        ),
      );
    }

    final content = Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Card(
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text('Alias', style: theme.textTheme.titleMedium),
                const SizedBox(height: 8),
                Text(
                  'Globala alias används som fallback i kvittoimporten. När samma kvittonamn upprepas kan rätt produkt matchas direkt.',
                  style: theme.textTheme.bodyMedium,
                ),
                const SizedBox(height: 8),
                const Wrap(
                  spacing: 8,
                  runSpacing: 8,
                  children: [
                    Chip(label: Text('Fallback')),
                    Chip(label: Text('Global')),
                    Chip(label: Text('Receipt import')),
                  ],
                ),
              ],
            ),
          ),
        ),
        const SizedBox(height: 12),
        Row(
          children: [
            Expanded(
              child: TextField(
                controller: _aliasController,
                decoration: const InputDecoration(
                  labelText: 'Kvittonamn (alias)',
                  border: OutlineInputBorder(),
                ),
              ),
            ),
            const SizedBox(width: 8),
            Expanded(
              child: DropdownButtonFormField<int>(
                key: ValueKey<int?>(_selectedProductId),
                initialValue: _selectedProductId,
                decoration: const InputDecoration(
                  labelText: 'Produkt',
                  border: OutlineInputBorder(),
                ),
                items: _products
                    .map(
                      (product) => DropdownMenuItem<int>(
                        value: product.id,
                        child: Text(product.displayName),
                      ),
                    )
                    .toList(),
                onChanged: _isSaving
                    ? null
                    : (value) => setState(() => _selectedProductId = value),
              ),
            ),
            const SizedBox(width: 8),
            FilledButton.icon(
              onPressed: _isSaving ? null : _upsertAlias,
              icon: _isSaving
                  ? const SizedBox(
                      width: 14,
                      height: 14,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : const Icon(Icons.save_outlined),
              label: const Text('Spara'),
            ),
          ],
        ),
        const SizedBox(height: 12),
        TextField(
          decoration: const InputDecoration(
            labelText: 'Sök alias',
            prefixIcon: Icon(Icons.search),
            border: OutlineInputBorder(),
          ),
          onChanged: (value) => setState(() => _search = value),
        ),
        const SizedBox(height: 12),
        if (filteredAliases.isEmpty)
          Card(
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Text(
                'Inga alias hittades.',
                style: theme.textTheme.bodyMedium,
              ),
            ),
          ),
      ],
    );

    if (!widget.embedded) {
      if (filteredAliases.isEmpty) {
        return ListView(
          padding: const EdgeInsets.all(16),
          children: [content],
        );
      }
      return ListView(
        padding: const EdgeInsets.all(16),
        children: [
          content,
          const SizedBox(height: 8),
          ...filteredAliases.map(buildAliasCard),
        ],
      );
    }

    if (filteredAliases.isEmpty) return content;

    return SingleChildScrollView(
      padding: const EdgeInsets.all(12),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          content,
          const SizedBox(height: 8),
          ...filteredAliases.map(buildAliasCard),
        ],
      ),
    );
  }
}

