import 'package:flutter/material.dart';
import 'package:hl_lieferservice/feature/loading/widget/article_row.dart';
import 'package:hl_lieferservice/model/article.dart';
import 'package:hl_lieferservice/model/component.dart';

/// Eine einzelne, im Hold-Dialog auswählbare Position. Aufrufer erhalten
/// nach Bestätigung die ausgewählten Items zurück.
///
/// Genau eines von [article] / [component] ist gesetzt — beide kombiniert
/// ergeben einen Komponenten-Eintrag (component != null mit zugehörigem
/// Parent-Artikel in [article]).
class HoldSelectionItem {
  HoldSelectionItem.article(this.article)
      : component = null,
        key = HoldKey.article(article);

  HoldSelectionItem.component(this.article, Component this.component)
      : key = HoldKey.component(article, component);

  /// Artikel — bei Komponenten der zugehörige Parent.
  final Article article;

  /// Komponente (nur gesetzt, wenn es sich um eine Stücklisten-Position
  /// handelt).
  final Component? component;

  /// Eindeutiger Schlüssel zur Hold-State-Verwaltung. Identisch mit den
  /// Keys, die [HoldKey] erzeugt — so kann ein Aufrufer ohne Umweg den
  /// internen Hold-Set füllen.
  final String key;

  String get _displayName => component?.name ?? article.name;

  String get _articleNumber =>
      component?.articleNumber ?? article.articleNumber;
}

/// Auswahl-Dialog für den Teilabbruch ("Artikel heute nicht liefern").
///
/// Liefert nach Bestätigung per `Navigator.pop` die Liste der ausgewählten
/// [HoldSelectionItem]s. Bei Abbruch ist das Ergebnis `null`. Items, die
/// im Set [alreadyHeld] enthalten sind, werden ausgegraut dargestellt und
/// sind nicht erneut wählbar.
class HoldSelectionDialog extends StatefulWidget {
  const HoldSelectionDialog({
    super.key,
    required this.customerName,
    required this.articles,
    required this.alreadyHeld,
  });

  /// Anzeigename des Kunden — wird im Dialog-Header gezeigt.
  final String customerName;

  /// Scannbare Artikel der Lieferung (also bereits vorgefiltert).
  final List<Article> articles;

  /// Set bereits gehaltener Keys — diese erscheinen ausgegraut & disabled.
  final Set<String> alreadyHeld;

  static Future<List<HoldSelectionItem>?> show(
    BuildContext context, {
    required String customerName,
    required List<Article> articles,
    required Set<String> alreadyHeld,
  }) {
    return showDialog<List<HoldSelectionItem>>(
      context: context,
      builder: (_) => HoldSelectionDialog(
        customerName: customerName,
        articles: articles,
        alreadyHeld: alreadyHeld,
      ),
    );
  }

  @override
  State<HoldSelectionDialog> createState() => _HoldSelectionDialogState();
}

class _HoldSelectionDialogState extends State<HoldSelectionDialog> {
  final Set<String> _selectedKeys = <String>{};
  late final List<HoldSelectionItem> _items;

  @override
  void initState() {
    super.initState();
    _items = _buildItems(widget.articles);
  }

  /// Erzeugt aus den Artikeln die selektierbaren Einträge. Parent-Artikel
  /// werden nicht selbst zum Eintrag — ihre Komponenten sind die wählbaren
  /// Einheiten. Für die Anzeige der Header-Zeile werden Parents über das
  /// Build-Verfahren (siehe build) separat eingestreut.
  List<HoldSelectionItem> _buildItems(List<Article> articles) {
    final result = <HoldSelectionItem>[];
    for (final a in articles) {
      if (a.isParent && a.components.isNotEmpty) {
        for (final c in a.components) {
          result.add(HoldSelectionItem.component(a, c));
        }
      } else {
        result.add(HoldSelectionItem.article(a));
      }
    }
    return result;
  }

  void _toggle(String key) {
    setState(() {
      if (_selectedKeys.contains(key)) {
        _selectedKeys.remove(key);
      } else {
        _selectedKeys.add(key);
      }
    });
  }

  void _confirm() {
    final selected =
        _items.where((i) => _selectedKeys.contains(i.key)).toList();
    Navigator.of(context).pop(selected);
  }

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

    return AlertDialog(
      title: const Text("Artikel zurückhalten"),
      content: SizedBox(
        width: double.maxFinite,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              widget.customerName,
              style: theme.textTheme.bodyMedium?.copyWith(
                color: theme.colorScheme.onSurfaceVariant,
              ),
            ),
            const SizedBox(height: 8),
            const Text(
              "Markiere die Positionen, die heute nicht ausgeliefert werden:",
              style: TextStyle(fontSize: 13),
            ),
            const SizedBox(height: 8),
            Flexible(
              child: ListView(
                shrinkWrap: true,
                children: _buildList(theme),
              ),
            ),
          ],
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: const Text("Abbrechen"),
        ),
        FilledButton(
          onPressed: _selectedKeys.isEmpty ? null : _confirm,
          child: const Text("Weiter"),
        ),
      ],
    );
  }

  /// Baut die ListView-Inhalte mit Header-Zeilen für Parent-Artikel.
  /// Parent-Header sind bewusst nicht klickbar — sie dienen nur zur
  /// Strukturierung.
  List<Widget> _buildList(ThemeData theme) {
    final widgets = <Widget>[];

    for (final a in widget.articles) {
      if (a.isParent && a.components.isNotEmpty) {
        widgets.add(
          Padding(
            padding: const EdgeInsets.only(top: 8, bottom: 2, left: 4),
            child: Row(
              children: [
                Icon(Icons.account_tree_outlined,
                    size: 16, color: theme.colorScheme.primary),
                const SizedBox(width: 6),
                Expanded(
                  child: Text(
                    a.name,
                    style: const TextStyle(
                      fontWeight: FontWeight.w600,
                      fontSize: 13,
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
        for (final c in a.components) {
          final item = _items.firstWhere(
            (i) => i.component == c && i.article == a,
          );
          widgets.add(_buildTile(item, indent: true));
        }
      } else {
        final item = _items.firstWhere(
          (i) => i.article == a && i.component == null,
        );
        widgets.add(_buildTile(item));
      }
    }

    return widgets;
  }

  Widget _buildTile(HoldSelectionItem item, {bool indent = false}) {
    final alreadyHeld = widget.alreadyHeld.contains(item.key);
    final selected = _selectedKeys.contains(item.key);

    return Padding(
      padding: EdgeInsets.only(left: indent ? 16 : 0),
      child: Opacity(
        opacity: alreadyHeld ? 0.4 : 1.0,
        child: CheckboxListTile(
          contentPadding: EdgeInsets.zero,
          dense: true,
          value: alreadyHeld ? true : selected,
          onChanged: alreadyHeld ? null : (_) => _toggle(item.key),
          title: Text(
            item._displayName,
            style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500),
          ),
          subtitle: Text(
            "Artikelnr. ${item._articleNumber}"
            "${alreadyHeld ? " · bereits zurückgehalten" : ""}",
            style: const TextStyle(fontSize: 11),
          ),
        ),
      ),
    );
  }
}
