import 'package:flutter/material.dart';
import 'package:hl_lieferservice/domain/entity/delivery.dart';
import 'package:hl_lieferservice/domain/entity/tour_details.dart';

/// Drag&Drop-Liste der heutigen Lieferungen eines Fahrzeugs.
///
/// Hält die aktuell sichtbare Reihenfolge in lokalem State; ein Tour-Reload
/// von außen würde sie überschreiben — das ist Absicht, damit der Backend-
/// Stand bei Pull-to-refresh durchschlägt. Der eigentliche Backend-Sync
/// erfolgt erst, wenn der Fahrer in der übergeordneten Page bestätigt.
class SortableDeliveryList extends StatefulWidget {
  const SortableDeliveryList({
    super.key,
    required this.details,
    required this.deliveries,
    this.controller,
  });

  /// Aggregat-Snapshot — wird für Kunden-Lookup gebraucht.
  final TourDetails details;

  /// Die in der Liste anzuzeigenden Lieferungen, vorgefiltert vom Aufrufer
  /// (z. B. nur die dem ausgewählten Fahrzeug zugewiesenen).
  final List<Delivery> deliveries;

  /// Optionaler Controller zum Auslesen der aktuellen Reihenfolge und zum
  /// Zurücksetzen durch Eltern-Widgets.
  final SortableDeliveryListController? controller;

  @override
  State<StatefulWidget> createState() => _SortableDeliveryListState();
}

class _SortableDeliveryListState extends State<SortableDeliveryList> {
  late List<String> _orderedIds;

  @override
  void initState() {
    super.initState();
    _orderedIds = widget.deliveries.map((d) => d.id).toList(growable: true);
    widget.controller?._attach(this);
  }

  @override
  void didUpdateWidget(covariant SortableDeliveryList oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.controller != widget.controller) {
      oldWidget.controller?._detach(this);
      widget.controller?._attach(this);
    }
    // Wenn sich die Eingangsliste fundamental ändert (Tour-Reload, neue
    // Lieferung hinzu/weg), local-state neu synchronisieren.
    final incomingIds = widget.deliveries.map((d) => d.id).toSet();
    final localIds = _orderedIds.toSet();
    if (incomingIds.length != localIds.length ||
        !incomingIds.containsAll(localIds)) {
      setState(() {
        _orderedIds =
            widget.deliveries.map((d) => d.id).toList(growable: true);
      });
    }
  }

  @override
  void dispose() {
    widget.controller?._detach(this);
    super.dispose();
  }

  void _resetToDefault() {
    setState(() {
      _orderedIds =
          widget.deliveries.map((d) => d.id).toList(growable: true);
    });
  }

  List<String> _readCurrentOrder() => List<String>.of(_orderedIds);

  @override
  Widget build(BuildContext context) {
    final byId = {for (final d in widget.deliveries) d.id: d};

    return ReorderableListView(
      buildDefaultDragHandles: true,
      onReorder: (oldIndex, newIndex) {
        setState(() {
          if (newIndex > oldIndex) newIndex -= 1;
          final id = _orderedIds.removeAt(oldIndex);
          _orderedIds.insert(newIndex, id);
        });
      },
      children: _orderedIds.asMap().entries.map((entry) {
        final id = entry.value;
        final pos = entry.key + 1;
        final delivery = byId[id];
        if (delivery == null) {
          return ListTile(
            key: Key('reorder-item-orphan-$id'),
            title: Text('Lieferung $id nicht mehr in der Tour'),
          );
        }
        final customer = widget.details.customerOf(delivery);
        return ListTile(
          key: Key('reorder-item-${delivery.id}'),
          leading: CircleAvatar(
            backgroundColor: Theme.of(context).primaryColor,
            child: Text(
              '$pos',
              style: TextStyle(
                color: Theme.of(context).colorScheme.onSecondary,
              ),
            ),
          ),
          title: Text(customer?.name ?? '⟨Unbekannter Kunde⟩'),
          subtitle: Text(
            delivery.deliveryAddressSnapshot.oneLine,
            style: const TextStyle(fontSize: 11),
          ),
          trailing: const Icon(Icons.drag_handle),
        );
      }).toList(),
    );
  }
}

/// Schmaler Controller, mit dem Eltern-Widgets die Liste zurücksetzen
/// und die aktuelle Reihenfolge auslesen können.
class SortableDeliveryListController {
  _SortableDeliveryListState? _state;

  void _attach(_SortableDeliveryListState state) => _state = state;
  void _detach(_SortableDeliveryListState state) {
    if (_state == state) _state = null;
  }

  /// Setzt die Liste auf die vom Aufrufer übergebene Default-Reihenfolge
  /// zurück (= aktueller `widget.deliveries`-Stand).
  void resetToDefault() => _state?._resetToDefault();

  /// Aktuelle Reihenfolge der Delivery-IDs, wie sie der Fahrer sieht.
  List<String> readCurrentOrder() =>
      _state?._readCurrentOrder() ?? const <String>[];
}
