import 'dart:async';

import 'package:flutter/material.dart';

import 'package:listenmeister/main.dart';
import 'package:listenmeister/models/models.dart';
import 'package:listenmeister/pages/list_detail.dart';

class LayoutDetailPage extends StatefulWidget {
  final StoreLayout layout;
  const LayoutDetailPage({super.key, required this.layout});

  @override
  State<LayoutDetailPage> createState() => _LayoutDetailPageState();
}

class _LayoutDetailPageState extends State<LayoutDetailPage> {
  late StoreLayout _layout;
  StreamSubscription? _layoutSubscription;
  StreamSubscription? _sectionsSubscription;
  StreamSubscription? _listsSubscription;
  List<StoreSection> _sections = [];
  bool _sectionsLoading = true;
  String? _sectionsError;
  List<Liste> _linkedLists = [];
  bool _listsLoading = true;
  String? _listsError;

  bool get _isOwner => _layout.owner == apiService.userId;

  @override
  void initState() {
    super.initState();
    _layout = widget.layout;
    _loadSections();
    _layoutSubscription = apiService.watchStoreLayout(_layout.id).listen((_) {
      _refreshLayout();
    });
    _sectionsSubscription = apiService
        .watchStoreSections(_layout.id)
        .listen((_) => _loadSections());
    _listsSubscription = apiService
        .watchListsForLayout(_layout.id)
        .listen((_) => _loadLinkedLists());
    _loadLinkedLists();
  }

  @override
  void dispose() {
    _layoutSubscription?.cancel();
    _sectionsSubscription?.cancel();
    _listsSubscription?.cancel();
    super.dispose();
  }

  Future<void> _refreshLayout() async {
    final updated = await apiService.getStoreLayoutById(_layout.id);
    if (updated != null && mounted) {
      setState(() => _layout = updated);
    }
  }

  Future<void> _loadSections() async {
    if (!mounted) return;
    setState(() {
      _sectionsLoading = true;
      _sectionsError = null;
    });
    try {
      final sections = await apiService.getStoreSections(_layout.id);
      if (!mounted) return;
      setState(() {
        _sections = sections;
        _sectionsLoading = false;
      });
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _sectionsError = e.toString();
        _sectionsLoading = false;
      });
    }
  }

  Future<void> _loadLinkedLists() async {
    if (!mounted) return;
    setState(() {
      _listsLoading = true;
      _listsError = null;
    });
    try {
      final lists = await apiService.getListsForLayout(_layout.id);
      if (!mounted) return;
      setState(() {
        _linkedLists = lists;
        _listsLoading = false;
      });
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _listsError = e.toString();
        _listsLoading = false;
      });
    }
  }

  Future<void> _openList(Liste list) async {
    await Navigator.of(
      context,
    ).push(MaterialPageRoute(builder: (_) => ListDetailPage(list: list)));
    if (mounted) {
      _loadLinkedLists();
    }
  }

  Future<void> _editLayout() async {
    if (!_isOwner) return;

    final TextEditingController nameCtl = TextEditingController(
      text: _layout.name,
    );
    final TextEditingController addressCtl = TextEditingController(
      text: _layout.address ?? '',
    );
    final TextEditingController latCtl = TextEditingController(
      text: _layout.latitude != null
          ? _layout.latitude!.toStringAsFixed(6)
          : '',
    );
    final TextEditingController lonCtl = TextEditingController(
      text: _layout.longitude != null
          ? _layout.longitude!.toStringAsFixed(6)
          : '',
    );
    bool isPublic = _layout.isPublic;

    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (context) {
        return StatefulBuilder(
          builder: (context, setDialogState) {
            return AlertDialog(
              title: const Text('Layout bearbeiten'),
              content: SingleChildScrollView(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    TextField(
                      controller: nameCtl,
                      decoration: const InputDecoration(labelText: 'Name'),
                      autofocus: true,
                    ),
                    TextField(
                      controller: addressCtl,
                      decoration: const InputDecoration(
                        labelText: 'Adresse (optional)',
                      ),
                    ),
                    TextField(
                      controller: latCtl,
                      decoration: const InputDecoration(
                        labelText: 'Breitengrad (optional)',
                      ),
                      keyboardType: const TextInputType.numberWithOptions(
                        decimal: true,
                        signed: true,
                      ),
                    ),
                    TextField(
                      controller: lonCtl,
                      decoration: const InputDecoration(
                        labelText: 'Längengrad (optional)',
                      ),
                      keyboardType: const TextInputType.numberWithOptions(
                        decimal: true,
                        signed: true,
                      ),
                    ),
                    SwitchListTile.adaptive(
                      value: isPublic,
                      onChanged: (value) {
                        setDialogState(() => isPublic = value);
                      },
                      title: const Text('Für andere sichtbar'),
                      contentPadding: EdgeInsets.zero,
                    ),
                  ],
                ),
              ),
              actions: [
                TextButton(
                  onPressed: () => Navigator.pop(context, false),
                  child: const Text('Abbrechen'),
                ),
                TextButton(
                  onPressed: () => Navigator.pop(context, true),
                  child: const Text('Speichern'),
                ),
              ],
            );
          },
        );
      },
    );

    if (ok != true) return;

    final String name = nameCtl.text.trim();
    if (name.isEmpty) return;

    double? latitude;
    double? longitude;
    bool clearLatitude = false;
    bool clearLongitude = false;

    final String latText = latCtl.text.trim();
    final String lonText = lonCtl.text.trim();
    final String addressText = addressCtl.text.trim();

    if (latText.isNotEmpty) {
      latitude = double.tryParse(latText.replaceAll(',', '.'));
      if (latitude == null) {
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Ungültiger Breitengrad.')),
          );
        }
        return;
      }
    } else {
      clearLatitude = true;
    }

    if (lonText.isNotEmpty) {
      longitude = double.tryParse(lonText.replaceAll(',', '.'));
      if (longitude == null) {
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Ungültiger Längengrad.')),
          );
        }
        return;
      }
    } else {
      clearLongitude = true;
    }

    try {
      await apiService.updateStoreLayout(
        _layout.id,
        name: name,
        address: addressText.isEmpty ? null : addressText,
        latitude: latitude,
        longitude: longitude,
        isPublic: isPublic,
        clearLatitude: clearLatitude,
        clearLongitude: clearLongitude,
        clearAddress: addressText.isEmpty,
      );
      await _refreshLayout();
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Fehler beim Speichern: $e')));
      }
    }
  }

  Future<void> _deleteLayout() async {
    if (!_isOwner) return;
    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Layout löschen?'),
        content: Text('Möchtest du "${_layout.name}" wirklich löschen?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: const Text('Abbrechen'),
          ),
          TextButton(
            onPressed: () => Navigator.pop(context, true),
            child: const Text('Löschen'),
          ),
        ],
      ),
    );
    if (ok != true) return;

    try {
      await apiService.deleteStoreLayout(_layout.id);
      if (mounted) {
        Navigator.of(context).pop();
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Fehler beim Löschen: $e')));
      }
    }
  }

  Future<void> _addSection() async {
    if (!_isOwner) return;

    final TextEditingController nameCtl = TextEditingController();

    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Bereich hinzufügen'),
        content: TextField(
          controller: nameCtl,
          decoration: const InputDecoration(labelText: 'Name'),
          autofocus: true,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: const Text('Abbrechen'),
          ),
          TextButton(
            onPressed: () => Navigator.pop(context, true),
            child: const Text('Hinzufügen'),
          ),
        ],
      ),
    );

    if (ok != true || nameCtl.text.trim().isEmpty) return;

    final int maxPos = _sections.fold<int>(
      -1,
      (max, section) => section.position > max ? section.position : max,
    );

    try {
      await apiService.createStoreSection(
        layoutId: _layout.id,
        name: nameCtl.text.trim(),
        position: maxPos + 1,
      );
      _loadSections();
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Fehler: $e')));
      }
    }
  }

  Future<void> _editSection(StoreSection section) async {
    if (!_isOwner) return;

    final TextEditingController nameCtl = TextEditingController(
      text: section.name,
    );

    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Bereich bearbeiten'),
        content: TextField(
          controller: nameCtl,
          decoration: const InputDecoration(labelText: 'Name'),
          autofocus: true,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: const Text('Abbrechen'),
          ),
          TextButton(
            onPressed: () => Navigator.pop(context, true),
            child: const Text('Speichern'),
          ),
        ],
      ),
    );

    if (ok != true || nameCtl.text.trim().isEmpty) return;

    try {
      await apiService.updateStoreSection(
        section.id,
        name: nameCtl.text.trim(),
      );
      _loadSections();
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Fehler: $e')));
      }
    }
  }

  Future<void> _deleteSection(StoreSection section) async {
    if (!_isOwner) return;

    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Bereich löschen?'),
        content: Text('"${section.name}" entfernen?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context, false),
            child: const Text('Abbrechen'),
          ),
          TextButton(
            onPressed: () => Navigator.pop(context, true),
            child: const Text('Löschen'),
          ),
        ],
      ),
    );

    if (ok != true) return;

    final int index = _sections.indexOf(section);
    setState(() => _sections.remove(section));

    try {
      await apiService.deleteStoreSection(section.id);
    } catch (e) {
      if (mounted) {
        setState(() => _sections.insert(index, section));
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Fehler beim Löschen: $e')));
      }
    }
  }

  Future<void> _onReorder(int oldIndex, int newIndex) async {
    if (!_isOwner) return;
    if (oldIndex < 0 || oldIndex >= _sections.length) return;
    int targetIndex = newIndex;
    if (targetIndex > oldIndex) {
      targetIndex -= 1;
    }
    if (targetIndex < 0 || targetIndex >= _sections.length) {
      targetIndex = _sections.length - 1;
    }
    if (targetIndex == oldIndex) return;

    setState(() {
      final section = _sections.removeAt(oldIndex);
      _sections.insert(targetIndex, section);
    });

    final List<Future<void>> updates = [];
    for (int i = 0; i < _sections.length; i++) {
      final section = _sections[i];
      if (section.position != i) {
        section.position = i;
        updates.add(apiService.updateStoreSection(section.id, position: i));
      }
    }

    if (updates.isEmpty) return;

    try {
      await Future.wait(updates);
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Sortierung konnte nicht gespeichert werden: $e'),
        ),
      );
      _loadSections();
    }
  }

  Widget _buildInfoTile({
    required IconData icon,
    required String label,
    String? value,
  }) {
    if (value == null || value.isEmpty) {
      return const SizedBox.shrink();
    }
    return ListTile(
      leading: Icon(icon),
      title: Text(label),
      subtitle: Text(value),
    );
  }

  List<Widget> _buildLayoutInfoTiles() {
    final tiles = <Widget>[];
    if (_layout.address != null && _layout.address!.isNotEmpty) {
      tiles.add(
        _buildInfoTile(
          icon: Icons.location_on_outlined,
          label: 'Adresse',
          value: _layout.address,
        ),
      );
    }
    if (_layout.latitude != null && _layout.longitude != null) {
      tiles.add(
        _buildInfoTile(
          icon: Icons.map_outlined,
          label: 'Koordinaten',
          value:
              '${_layout.latitude!.toStringAsFixed(6)}, ${_layout.longitude!.toStringAsFixed(6)}',
        ),
      );
    }
    if (_layout.isPublic) {
      tiles.add(
        const ListTile(
          leading: Icon(Icons.public),
          title: Text('Öffentlich sichtbar'),
        ),
      );
    }
    tiles.addAll(_buildLinkedListsTiles());
    return tiles;
  }

  List<Widget> _buildLinkedListsTiles() {
    final tiles = <Widget>[];

    if (_listsLoading) {
      tiles.add(
        const ListTile(
          leading: SizedBox(
            width: 20,
            height: 20,
            child: CircularProgressIndicator(strokeWidth: 2),
          ),
          title: Text('Verknüpfte Listen'),
          subtitle: Text('Wird geladen...'),
        ),
      );
      return tiles;
    }

    if (_listsError != null) {
      tiles.add(
        ListTile(
          leading: const Icon(Icons.error_outline, color: Colors.redAccent),
          title: const Text('Verknüpfte Listen'),
          subtitle: Text('Fehler: $_listsError'),
          trailing: IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: _loadLinkedLists,
          ),
        ),
      );
      return tiles;
    }

    tiles.add(
      ListTile(
        leading: const Icon(Icons.list_alt_outlined),
        title: const Text('Verknüpfte Listen'),
        subtitle: Text(
          _linkedLists.isEmpty
              ? 'Keine Listen verknüpft.'
              : '${_linkedLists.length} Listen verknüpft.',
        ),
      ),
    );

    for (final list in _linkedLists) {
      tiles.add(
        ListTile(
          contentPadding: const EdgeInsets.only(left: 72, right: 16),
          title: Text(list.title),
          leading: const Icon(Icons.chevron_right),
          onTap: () => _openList(list),
        ),
      );
    }

    return tiles;
  }

  Widget _buildOwnerSections(List<Widget> infoTiles) {
    if (_sections.isEmpty) {
      return ListView(
        padding: const EdgeInsets.only(bottom: 24),
        children: [
          ...infoTiles,
          if (infoTiles.isNotEmpty) const Divider(height: 0),
          const Padding(
            padding: EdgeInsets.all(16),
            child: Text(
              'Noch keine Bereiche. Tippe auf + um welche anzulegen.',
            ),
          ),
        ],
      );
    }

    return ReorderableListView.builder(
      padding: const EdgeInsets.only(bottom: 24),
      buildDefaultDragHandles: false,
      header: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          ...infoTiles,
          if (infoTiles.isNotEmpty) const Divider(height: 0),
          const Padding(
            padding: EdgeInsets.fromLTRB(16, 16, 16, 4),
            child: Text(
              'Bereiche',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
          const Padding(
            padding: EdgeInsets.fromLTRB(16, 0, 16, 12),
            child: Text(
              'Zum Sortieren das Griff-Symbol gedrückt halten und ziehen.',
            ),
          ),
        ],
      ),
      itemCount: _sections.length,
      onReorder: _onReorder,
      itemBuilder: (context, index) {
        final section = _sections[index];
        return ListTile(
          key: ValueKey(section.id),
          leading: ReorderableDragStartListener(
            index: index,
            child: const Icon(Icons.drag_indicator),
          ),
          title: Text(section.name),
          trailing: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              IconButton(
                icon: const Icon(Icons.edit),
                onPressed: () => _editSection(section),
              ),
              IconButton(
                icon: const Icon(Icons.delete),
                onPressed: () => _deleteSection(section),
              ),
            ],
          ),
        );
      },
    );
  }

  Widget _buildViewerSections(List<Widget> infoTiles) {
    if (_sections.isEmpty) {
      return ListView(
        padding: const EdgeInsets.only(bottom: 24),
        children: [
          ...infoTiles,
          if (infoTiles.isNotEmpty) const Divider(height: 0),
          const Padding(
            padding: EdgeInsets.all(16),
            child: Text(
              'Noch keine Bereiche hinterlegt.',
              textAlign: TextAlign.center,
            ),
          ),
        ],
      );
    }

    return ListView(
      padding: const EdgeInsets.only(bottom: 24),
      children: [
        ...infoTiles,
        if (infoTiles.isNotEmpty) const Divider(height: 0),
        const Padding(
          padding: EdgeInsets.fromLTRB(16, 16, 16, 4),
          child: Text(
            'Bereiche',
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
        ),
        ..._sections.map(
          (section) => ListTile(
            leading: const Icon(Icons.storefront_outlined),
            title: Text(section.name),
          ),
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    final infoTiles = _buildLayoutInfoTiles();
    Widget body;

    if (_sectionsLoading) {
      body = const Center(child: CircularProgressIndicator());
    } else if (_sectionsError != null) {
      body = Center(child: Text('Fehler: $_sectionsError'));
    } else if (_isOwner) {
      body = _buildOwnerSections(infoTiles);
    } else {
      body = _buildViewerSections(infoTiles);
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(_layout.name),
        actions: [
          if (_isOwner)
            PopupMenuButton<String>(
              onSelected: (value) {
                if (value == 'edit') {
                  _editLayout();
                } else if (value == 'delete') {
                  _deleteLayout();
                }
              },
              itemBuilder: (context) => const [
                PopupMenuItem(value: 'edit', child: Text('Layout bearbeiten')),
                PopupMenuItem(value: 'delete', child: Text('Layout löschen')),
              ],
            ),
        ],
      ),
      floatingActionButton: _isOwner
          ? FloatingActionButton(
              onPressed: _addSection,
              child: const Icon(Icons.add),
            )
          : null,
      body: body,
    );
  }
}
