import 'dart:async';

import 'package:flutter/material.dart';

import 'package:listenmeister/main.dart';
import 'package:listenmeister/models/models.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;
  late Future<List<StoreSection>> _sectionsFuture;
  StreamSubscription? _layoutSubscription;
  StreamSubscription? _sectionsSubscription;
  List<StoreSection> _sections = [];

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

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

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

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

  void _loadSections() {
    setState(() {
      _sectionsFuture = apiService.getStoreSections(_layout.id);
    });
  }

  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 TextEditingController categoryCtl = TextEditingController();

    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Bereich hinzufügen'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextField(
              controller: nameCtl,
              decoration: const InputDecoration(labelText: 'Name'),
              autofocus: true,
            ),
            TextField(
              controller: categoryCtl,
              decoration: const InputDecoration(
                labelText: 'Kategorie (optional)',
              ),
            ),
          ],
        ),
        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(),
        category: categoryCtl.text.trim().isEmpty
            ? null
            : categoryCtl.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 TextEditingController categoryCtl = TextEditingController(
      text: section.category ?? '',
    );

    final bool? ok = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Bereich bearbeiten'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            TextField(
              controller: nameCtl,
              decoration: const InputDecoration(labelText: 'Name'),
              autofocus: true,
            ),
            TextField(
              controller: categoryCtl,
              decoration: const InputDecoration(
                labelText: 'Kategorie (optional)',
              ),
            ),
          ],
        ),
        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;

    final String categoryText = categoryCtl.text.trim();
    final String? category = categoryText.isEmpty ? null : categoryText;

    try {
      await apiService.updateStoreSection(
        section.id,
        name: nameCtl.text.trim(),
        category: category,
        clearCategory: category == null,
      );
      _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')));
      }
    }
  }

  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),
    );
  }

  @override
  Widget build(BuildContext context) {
    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: FutureBuilder<List<StoreSection>>(
        future: _sectionsFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasError) {
            return Center(child: Text('Fehler: ${snapshot.error}'));
          }

          _sections = snapshot.data ?? [];

          if (_sections.isEmpty && !_isOwner) {
            return ListView(
              padding: const EdgeInsets.all(16),
              children: [
                if (_layout.address != null && _layout.address!.isNotEmpty)
                  _buildInfoTile(
                    icon: Icons.location_on_outlined,
                    label: 'Adresse',
                    value: _layout.address,
                  ),
                if (_layout.latitude != null && _layout.longitude != null)
                  _buildInfoTile(
                    icon: Icons.map_outlined,
                    label: 'Koordinaten',
                    value:
                        '${_layout.latitude!.toStringAsFixed(6)}, ${_layout.longitude!.toStringAsFixed(6)}',
                  ),
                const SizedBox(height: 24),
                const Text(
                  'Noch keine Bereiche hinterlegt.',
                  textAlign: TextAlign.center,
                ),
              ],
            );
          }

          return ListView(
            children: [
              if (_layout.address != null && _layout.address!.isNotEmpty)
                _buildInfoTile(
                  icon: Icons.location_on_outlined,
                  label: 'Adresse',
                  value: _layout.address,
                ),
              if (_layout.latitude != null && _layout.longitude != null)
                _buildInfoTile(
                  icon: Icons.map_outlined,
                  label: 'Koordinaten',
                  value:
                      '${_layout.latitude!.toStringAsFixed(6)}, ${_layout.longitude!.toStringAsFixed(6)}',
                ),
              if (_layout.isPublic)
                const ListTile(
                  leading: Icon(Icons.public),
                  title: Text('Öffentlich sichtbar'),
                ),
              if (_sections.isNotEmpty)
                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.category_outlined),
                  title: Text(section.name),
                  subtitle:
                      section.category != null && section.category!.isNotEmpty
                      ? Text(section.category!)
                      : null,
                  trailing: _isOwner
                      ? Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            IconButton(
                              icon: const Icon(Icons.edit),
                              onPressed: () => _editSection(section),
                            ),
                            IconButton(
                              icon: const Icon(Icons.delete),
                              onPressed: () => _deleteSection(section),
                            ),
                          ],
                        )
                      : null,
                ),
              ),
              if (_sections.isEmpty && _isOwner)
                const Padding(
                  padding: EdgeInsets.all(16),
                  child: Text(
                    'Noch keine Bereiche. Tippe auf + um welche anzulegen.',
                  ),
                ),
              const SizedBox(height: 24),
            ],
          );
        },
      ),
    );
  }
}
