import 'dart:async';

import 'package:flutter/material.dart';

import 'package:listenmeister/main.dart';
import 'package:listenmeister/models/models.dart';
import 'package:listenmeister/pages/layout_detail.dart';
import 'package:listenmeister/widgets/members_dialog.dart';

class ListDetailPage extends StatefulWidget {
  final Liste list;
  const ListDetailPage({super.key, required this.list});

  @override
  State<ListDetailPage> createState() => _ListDetailPageState();
}

class _ListDetailPageState extends State<ListDetailPage> {
  late Future<List<Item>> _itemsFuture;
  StreamSubscription? _itemsSubscription;
  List<Item> _items = [];
  StoreLayout? _assignedLayout;
  bool _loadingLayout = false;
  bool _layoutUnavailable = false;
  StreamSubscription? _layoutSectionsSubscription;
  List<StoreSection> _layoutSections = [];
  bool _layoutSectionsLoading = false;
  String? _currentLayoutId;
  bool _layoutSectionsErrorShown = false;

  bool get _isOwner => widget.list.owner == apiService.userId;

  @override
  void initState() {
    super.initState();
    _itemsFuture = apiService.getItems(widget.list.id);
    _itemsSubscription = apiService.watchItems(widget.list.id).listen((_) {
      _loadItems();
    });
    _loadAssignedLayout();
  }

  @override
  void didUpdateWidget(covariant ListDetailPage oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.list.layoutId != widget.list.layoutId) {
      _loadAssignedLayout();
    }
  }

  @override
  void dispose() {
    _itemsSubscription?.cancel();
    _layoutSectionsSubscription?.cancel();
    super.dispose();
  }

  void _loadItems() {
    setState(() {
      _itemsFuture = apiService.getItems(widget.list.id);
    });
  }

  Future<void> _loadAssignedLayout() async {
    final String? layoutId = widget.list.layoutId;
    if (!mounted) return;
    setState(() {
      _loadingLayout = true;
    });
    if (layoutId == null) {
      await _updateLayoutAssignment(null, layout: null);
      if (!mounted) return;
      setState(() {
        _loadingLayout = false;
      });
      return;
    }

    StoreLayout? layout;
    try {
      layout = await apiService.getStoreLayoutById(layoutId);
    } catch (_) {
      layout = null;
    }

    if (!mounted) return;
    await _updateLayoutAssignment(layoutId, layout: layout);
    if (!mounted) return;
    setState(() {
      _loadingLayout = false;
    });
  }

  Future<void> _updateLayoutAssignment(
    String? layoutId, {
    required StoreLayout? layout,
  }) async {
    await _layoutSectionsSubscription?.cancel();
    _layoutSectionsSubscription = null;
    if (!mounted) return;

    _currentLayoutId = layoutId;
    _layoutSectionsErrorShown = false;

    setState(() {
      _assignedLayout = layoutId == null ? null : layout;
      _layoutUnavailable = layoutId != null && layout == null;
      _layoutSections = [];
      _layoutSectionsLoading = layoutId != null && layout != null;
    });

    if (layoutId == null || layout == null) {
      return;
    }

    final String watchId = layoutId;
    _layoutSectionsSubscription = apiService.watchStoreSections(watchId).listen(
      (_) {
        _fetchLayoutSections(watchId);
      },
    );

    await _fetchLayoutSections(watchId);
  }

  Future<void> _fetchLayoutSections(String layoutId) async {
    try {
      final sections = await apiService.getStoreSections(layoutId);
      if (!mounted || _currentLayoutId != layoutId) return;
      setState(() {
        _layoutSections = sections;
        _layoutSectionsLoading = false;
      });
    } catch (e) {
      if (!mounted || _currentLayoutId != layoutId) return;
      setState(() {
        _layoutSectionsLoading = false;
      });
      if (!_layoutSectionsErrorShown) {
        _layoutSectionsErrorShown = true;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Bereiche konnten nicht geladen werden: $e')),
        );
      }
    }
  }

  Future<void> _openAssignedLayout() async {
    final layout = _assignedLayout;
    if (layout == null) return;
    await Navigator.of(
      context,
    ).push(MaterialPageRoute(builder: (_) => LayoutDetailPage(layout: layout)));
    if (mounted) {
      await _loadAssignedLayout();
    }
  }

  Future<void> _chooseLayout({bool includeViewOption = false}) async {
    if (!_isOwner) return;
    setState(() => _loadingLayout = true);
    List<StoreLayout> layouts = [];
    try {
      layouts = await apiService.getStoreLayouts();
    } catch (e) {
      if (mounted) {
        setState(() => _loadingLayout = false);
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Layouts konnten nicht geladen werden: $e')),
        );
      }
      return;
    }
    if (!mounted) return;
    setState(() => _loadingLayout = false);

    const String noLayoutOption = '__no_layout__';
    final String? currentId = widget.list.layoutId;

    final String? selection = await showModalBottomSheet<String>(
      context: context,
      builder: (context) {
        return SafeArea(
          child: ListView(
            shrinkWrap: true,
            children: [
              if (includeViewOption && _assignedLayout != null)
                ListTile(
                  leading: const Icon(Icons.visibility_outlined),
                  title: const Text('Aktuelles Layout ansehen'),
                  onTap: () => Navigator.pop(context, '__view__'),
                ),
              if (includeViewOption && _assignedLayout != null)
                const Divider(height: 0),
              ListTile(
                leading: const Icon(Icons.close),
                title: const Text('Kein Layout zuordnen'),
                trailing: currentId == null
                    ? const Icon(Icons.check, size: 20)
                    : null,
                onTap: () => Navigator.pop(context, noLayoutOption),
              ),
              if (layouts.isNotEmpty) const Divider(height: 0),
              if (layouts.isEmpty)
                const Padding(
                  padding: EdgeInsets.all(16),
                  child: Text('Keine Layouts verfügbar.'),
                ),
              ...layouts.map((layout) {
                return ListTile(
                  leading: Icon(
                    layout.owner == apiService.userId
                        ? Icons.store_mall_directory
                        : Icons.share,
                  ),
                  title: Text(layout.name),
                  subtitle: layout.address != null && layout.address!.isNotEmpty
                      ? Text(layout.address!)
                      : null,
                  trailing: currentId == layout.id
                      ? const Icon(Icons.check, size: 20)
                      : null,
                  onTap: () => Navigator.pop(context, layout.id),
                );
              }),
            ],
          ),
        );
      },
    );

    if (selection == null) return;

    if (includeViewOption && selection == '__view__') {
      await _openAssignedLayout();
      return;
    }

    final String? newLayoutId = selection == noLayoutOption ? null : selection;
    if (newLayoutId == currentId) return;

    try {
      await apiService.updateList(
        widget.list.id,
        layoutId: newLayoutId,
        clearLayout: newLayoutId == null,
      );
      widget.list.layoutId = newLayoutId;
      if (!mounted) return;

      if (newLayoutId == null) {
        setState(() => _loadingLayout = true);
        await _updateLayoutAssignment(null, layout: null);
        if (!mounted) return;
        setState(() => _loadingLayout = false);
      } else {
        StoreLayout? selectedLayout;
        for (final layout in layouts) {
          if (layout.id == newLayoutId) {
            selectedLayout = layout;
            break;
          }
        }

        if (selectedLayout != null) {
          setState(() => _loadingLayout = true);
          await _updateLayoutAssignment(newLayoutId, layout: selectedLayout);
          if (!mounted) return;
          setState(() => _loadingLayout = false);
        } else {
          await _loadAssignedLayout();
        }
      }
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Layout konnte nicht gespeichert werden: $e')),
      );
      await _loadAssignedLayout();
    }
  }

  Widget _buildLayoutCard() {
    final bool hasLayout = _assignedLayout != null;
    final Widget subtitle;
    if (_loadingLayout) {
      subtitle = const Text('Lädt...');
    } else if (_layoutUnavailable && widget.list.layoutId != null) {
      subtitle = const Text('Layout nicht verfügbar');
    } else {
      subtitle = Text(
        hasLayout ? _assignedLayout!.name : 'Kein Layout zugeordnet',
      );
    }

    final List<Widget> actionButtons = [];
    if (hasLayout) {
      actionButtons.add(
        TextButton.icon(
          onPressed: _loadingLayout ? null : _openAssignedLayout,
          icon: const Icon(Icons.open_in_new, size: 18),
          label: const Text('Layout ansehen'),
        ),
      );
    }
    if (_isOwner) {
      actionButtons.add(
        ElevatedButton.icon(
          onPressed: _loadingLayout
              ? null
              : () => _chooseLayout(includeViewOption: true),
          icon: const Icon(Icons.store_mall_directory_outlined, size: 18),
          label: Text(hasLayout ? 'Layout wechseln' : 'Layout auswählen'),
        ),
      );
    }

    return Card(
      margin: const EdgeInsets.fromLTRB(12, 12, 12, 4),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          ListTile(
            leading: const Icon(Icons.store_mall_directory_outlined),
            title: const Text('Ladenlayout'),
            subtitle: subtitle,
            onTap: () {
              if (_loadingLayout) return;
              if (_isOwner) {
                _chooseLayout(includeViewOption: true);
              } else if (hasLayout) {
                _openAssignedLayout();
              }
            },
          ),
          if (actionButtons.isNotEmpty)
            Padding(
              padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
              child: Align(
                alignment: Alignment.centerRight,
                child: Wrap(spacing: 8, runSpacing: 4, children: actionButtons),
              ),
            ),
        ],
      ),
    );
  }

  String? _resolveSectionName(String? sectionId) {
    if (sectionId == null) return null;
    for (final section in _layoutSections) {
      if (section.id == sectionId) {
        return section.name;
      }
    }
    if (_assignedLayout != null && !_layoutSectionsLoading) {
      return 'Bereich nicht verfügbar';
    }
    return null;
  }

  Future<void> _showLayoutOptions() async {
    if (_loadingLayout) return;

    if (_isOwner) {
      await _chooseLayout(includeViewOption: true);
      return;
    }

    if (_assignedLayout != null) {
      await _openAssignedLayout();
    } else if (mounted) {
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(const SnackBar(content: Text('Kein Layout hinterlegt.')));
    }
  }

  Future<void> _showMembersDialog() async {
    final bool? updated = await showDialog<bool>(
      context: context,
      builder: (_) => MembersDialog(list: widget.list),
    );
    if (updated == true && mounted) {
      setState(() {});
    }
  }

  Future<void> _editItem(Item item) async {
    final TextEditingController ctl = TextEditingController(text: item.name);
    String? selectedSectionId = item.sectionId;
    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (c) => StatefulBuilder(
        builder: (context, setDialogState) {
          return AlertDialog(
            title: const Text('Eintrag bearbeiten'),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                TextField(
                  controller: ctl,
                  decoration: const InputDecoration(labelText: 'Name'),
                  autofocus: true,
                ),
                if (_assignedLayout != null)
                  Padding(
                    padding: const EdgeInsets.only(top: 12),
                    child: _layoutSectionsLoading
                        ? const ListTile(
                            contentPadding: EdgeInsets.zero,
                            leading: SizedBox(
                              width: 20,
                              height: 20,
                              child: CircularProgressIndicator(strokeWidth: 2),
                            ),
                            title: Text('Bereiche werden geladen...'),
                          )
                        : _layoutSections.isEmpty
                        ? const ListTile(
                            contentPadding: EdgeInsets.zero,
                            leading: Icon(Icons.info_outline),
                            title: Text('Keine Bereiche im Layout.'),
                          )
                        : DropdownButtonFormField<String?>(
                            initialValue: selectedSectionId,
                            items: [
                              const DropdownMenuItem<String?>(
                                value: null,
                                child: Text('Keine Abteilung'),
                              ),
                              ..._layoutSections.map(
                                (section) => DropdownMenuItem<String?>(
                                  value: section.id,
                                  child: Text(section.name),
                                ),
                              ),
                            ],
                            decoration: const InputDecoration(
                              labelText: 'Abteilung',
                            ),
                            onChanged: (value) {
                              setDialogState(() => selectedSectionId = value);
                            },
                          ),
                  ),
              ],
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(c, false),
                child: const Text('Abbrechen'),
              ),
              TextButton(
                onPressed: () => Navigator.pop(c, true),
                child: const Text('Speichern'),
              ),
            ],
          );
        },
      ),
    );
    if (ok != true || ctl.text.trim().isEmpty) return;

    final String newName = ctl.text.trim();
    final bool nameChanged = newName != item.name;
    final bool sectionChanged = selectedSectionId != item.sectionId;
    if (!nameChanged && !sectionChanged) return;

    final String oldName = item.name;
    final String? oldSection = item.sectionId;
    setState(() {
      if (nameChanged) item.name = newName;
      if (sectionChanged) item.sectionId = selectedSectionId;
    });

    try {
      await apiService.updateItem(
        item.id,
        name: nameChanged ? newName : null,
        sectionId: sectionChanged ? selectedSectionId : null,
        clearSection: sectionChanged && selectedSectionId == null,
      );
    } catch (e) {
      if (mounted) {
        setState(() {
          item.name = oldName;
          item.sectionId = oldSection;
        });
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Fehler: $e')));
      }
    }
  }

  Future<void> _updateItemSection(Item item, String? newSectionId) async {
    if (_assignedLayout == null) return;
    final String? previousSection = item.sectionId;
    if (newSectionId == previousSection) return;

    setState(() => item.sectionId = newSectionId);

    try {
      await apiService.updateItem(
        item.id,
        sectionId: newSectionId,
        clearSection: newSectionId == null,
      );
    } catch (e) {
      if (!mounted) return;
      setState(() => item.sectionId = previousSection);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Bereich konnte nicht gespeichert werden: $e')),
      );
    }
  }

  Future<void> _addItem() async {
    final TextEditingController ctl = TextEditingController();
    String? selectedSectionId;

    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (c) => StatefulBuilder(
        builder: (context, setDialogState) {
          return AlertDialog(
            title: const Text('Eintrag hinzufügen'),
            content: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                TextField(
                  controller: ctl,
                  decoration: const InputDecoration(labelText: 'Name'),
                  autofocus: true,
                ),
                if (_assignedLayout != null)
                  Padding(
                    padding: const EdgeInsets.only(top: 12),
                    child: _layoutSectionsLoading
                        ? const ListTile(
                            contentPadding: EdgeInsets.zero,
                            leading: SizedBox(
                              width: 20,
                              height: 20,
                              child: CircularProgressIndicator(strokeWidth: 2),
                            ),
                            title: Text('Bereiche werden geladen...'),
                          )
                        : _layoutSections.isEmpty
                        ? const ListTile(
                            contentPadding: EdgeInsets.zero,
                            leading: Icon(Icons.info_outline),
                            title: Text('Keine Bereiche im Layout.'),
                          )
                        : DropdownButtonFormField<String?>(
                            initialValue: selectedSectionId,
                            items: [
                              const DropdownMenuItem<String?>(
                                value: null,
                                child: Text('Keine Abteilung'),
                              ),
                              ..._layoutSections.map(
                                (section) => DropdownMenuItem<String?>(
                                  value: section.id,
                                  child: Text(section.name),
                                ),
                              ),
                            ],
                            decoration: const InputDecoration(
                              labelText: 'Abteilung',
                            ),
                            onChanged: (value) {
                              setDialogState(() => selectedSectionId = value);
                            },
                          ),
                  ),
              ],
            ),
            actions: [
              TextButton(
                onPressed: () => Navigator.pop(c, false),
                child: const Text('Abbrechen'),
              ),
              TextButton(
                onPressed: () => Navigator.pop(c, true),
                child: const Text('Hinzufügen'),
              ),
            ],
          );
        },
      ),
    );
    if (ok != true || ctl.text.trim().isEmpty) return;

    try {
      final int maxPos = _items.fold<int>(
        -1,
        (max, item) => item.position > max ? item.position : max,
      );
      await apiService.createItem(
        widget.list.id,
        ctl.text.trim(),
        maxPos + 1,
        sectionId: (_assignedLayout != null && !_layoutSectionsLoading)
            ? selectedSectionId
            : null,
      );
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Fehler: $e')));
      }
    }
  }

  Future<void> _deleteItem(Item item) async {
    final int index = _items.indexOf(item);
    setState(() => _items.remove(item));

    try {
      await apiService.deleteItem(item.id);
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('"${item.name}" gelöscht.')));
      }
    } catch (e) {
      if (!mounted) return;
      setState(() => _items.insert(index, item));
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(SnackBar(content: Text('Fehler beim Löschen: $e')));
    }
  }

  Future<void> _toggleItem(Item item) async {
    final bool oldState = item.checked;
    setState(() => item.checked = !item.checked);
    try {
      await apiService.updateItem(item.id, checked: item.checked);
    } catch (e) {
      if (!mounted) return;
      setState(() => item.checked = oldState);
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Fehler beim Aktualisieren: $e')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.list.title),
        actions: [
          IconButton(
            icon: const Icon(Icons.store_mall_directory_outlined),
            tooltip: _loadingLayout
                ? 'Lädt...'
                : _assignedLayout != null
                ? (_isOwner ? 'Layout wechseln' : 'Layout anzeigen')
                : 'Layout auswählen',
            onPressed: _loadingLayout ? null : _showLayoutOptions,
          ),
          IconButton(
            icon: const Icon(Icons.people_alt_outlined),
            tooltip: 'Mitglieder verwalten',
            onPressed: _showMembersDialog,
          ),
        ],
      ),
      body: FutureBuilder<List<Item>>(
        future: _itemsFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasError) {
            return Center(child: Text('Fehler: ${snapshot.error}'));
          }

          _items = snapshot.data ?? [];

          final layoutCard = _buildLayoutCard();

          if (_items.isEmpty) {
            return ListView(
              padding: const EdgeInsets.fromLTRB(0, 0, 0, 80),
              children: [
                layoutCard,
                const SizedBox(height: 8),
                const Padding(
                  padding: EdgeInsets.all(24),
                  child: Center(
                    child: Text('Füge deinen ersten Eintrag hinzu!'),
                  ),
                ),
              ],
            );
          }
          return ListView.builder(
            padding: const EdgeInsets.fromLTRB(0, 0, 0, 80),
            itemCount: _items.length + 1,
            itemBuilder: (context, index) {
              if (index == 0) {
                return layoutCard;
              }
              final Item item = _items[index - 1];
              final String? sectionName = _resolveSectionName(item.sectionId);
              final bool showSectionMenu = _assignedLayout != null;
              final String? currentSectionId = item.sectionId;
              return ListTile(
                leading: Checkbox(
                  value: item.checked,
                  onChanged: (_) => _toggleItem(item),
                ),
                title: Text(
                  item.name,
                  style: TextStyle(
                    decoration: item.checked
                        ? TextDecoration.lineThrough
                        : null,
                  ),
                ),
                subtitle: sectionName != null
                    ? Text('Abteilung: $sectionName')
                    : null,
                trailing: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    if (showSectionMenu)
                      PopupMenuButton<String?>(
                        tooltip: _layoutSectionsLoading
                            ? 'Bereiche werden geladen...'
                            : 'Bereich auswählen',
                        icon: const Icon(Icons.segment),
                        enabled: !_layoutSectionsLoading,
                        onSelected: (value) async {
                          if (_layoutSections.isEmpty && value == null) return;
                          await _updateItemSection(item, value);
                        },
                        itemBuilder: (context) {
                          if (_layoutSectionsLoading) {
                            return [
                              const PopupMenuItem<String?>(
                                value: null,
                                enabled: false,
                                child: Text('Bereiche werden geladen...'),
                              ),
                            ];
                          }
                          if (_layoutSections.isEmpty) {
                            return [
                              const PopupMenuItem<String?>(
                                value: null,
                                enabled: false,
                                child: Text('Keine Bereiche im Layout'),
                              ),
                            ];
                          }
                          return [
                            PopupMenuItem<String?>(
                              value: null,
                              child: Row(
                                children: [
                                  if (currentSectionId == null)
                                    const Icon(Icons.check, size: 18)
                                  else
                                    const SizedBox(width: 18),
                                  const SizedBox(width: 8),
                                  const Text('Keine Abteilung'),
                                ],
                              ),
                            ),
                            const PopupMenuDivider(),
                            ..._layoutSections.map(
                              (section) => PopupMenuItem<String?>(
                                value: section.id,
                                child: Row(
                                  children: [
                                    if (currentSectionId == section.id)
                                      const Icon(Icons.check, size: 18)
                                    else
                                      const SizedBox(width: 18),
                                    const SizedBox(width: 8),
                                    Text(section.name),
                                  ],
                                ),
                              ),
                            ),
                          ];
                        },
                      ),
                    IconButton(
                      icon: const Icon(Icons.edit),
                      onPressed: () => _editItem(item),
                    ),
                    IconButton(
                      icon: const Icon(Icons.delete),
                      onPressed: () => _deleteItem(item),
                    ),
                  ],
                ),
              );
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _addItem,
        child: const Icon(Icons.add),
      ),
    );
  }
}
