import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hl_lieferservice/feature/delivery/bloc/tour_bloc.dart';
import 'package:hl_lieferservice/feature/delivery/bloc/tour_event.dart';
import 'package:hl_lieferservice/feature/delivery/bloc/tour_state.dart';
import 'package:hl_lieferservice/feature/delivery/util.dart';
import 'package:hl_lieferservice/model/delivery.dart';

/// Drag&Drop-Liste der heutigen Lieferungen eines Fahrzeugs.
///
/// Hält die aktuell sichtbare Reihenfolge in lokalem State, damit das
/// Verschieben spürbar unmittelbar wirkt — und gibt jeden Drop zusätzlich
/// als [ReorderDeliveryEvent] an den [TourBloc] weiter. Dort übernimmt
/// der [ReorderService] die lokale Persistenz. Es findet hier bewusst
/// **kein** API-Call statt; der Backend-Sync läuft erst, wenn der Fahrer
/// die Reihenfolge in der übergeordneten Page bestätigt.
class SortableDeliveryList extends StatefulWidget {
  const SortableDeliveryList({
    super.key,
    required this.selectedCarId,
    this.controller,
  });

  final int? selectedCarId;

  /// Optionaler Controller zum Zurücksetzen der Liste durch Eltern-Widgets
  /// (z. B. Button "Zurücksetzen" in der Page).
  final SortableDeliveryListController? controller;

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

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

  @override
  void initState() {
    super.initState();
    _localSortedList = _readSortedListFromBloc();
    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);
    }
  }

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

  List<String> _readSortedListFromBloc() {
    final state = context.read<TourBloc>().state;
    if (state is TourLoaded) {
      return [
        ...state.sortingInformation[widget.selectedCarId.toString()] ?? [],
      ];
    }
    return [];
  }

  /// Setzt die Liste auf die natürliche Reihenfolge zurück, in der die
  /// Lieferungen in der Tour stehen. Wird vom Controller (Button
  /// "Zurücksetzen") aufgerufen und meldet jeden notwendigen Swap als
  /// Reorder-Event, damit der lokale Persistenz-State synchron bleibt.
  ///
  /// Filterlogik (muss konsistent zu `_ensureSortingForCar` im TourBloc
  /// sein):
  /// * Ein-Auto-Teams: alle Tour-Lieferungen.
  /// * Mehr-Auto-Teams: nur Lieferungen, die dem ausgewählten Fahrzeug
  ///   nach der Auswahl bereits zugeordnet sind.
  void _resetToDefault() {
    final state = context.read<TourBloc>().state;
    if (state is! TourLoaded) return;

    final cars = state.tour.driver.cars;
    final carIdStr = widget.selectedCarId.toString();
    final List<String> defaultOrder = cars.length >= 2
        ? state.tour.deliveries
            .where((d) => d.carId?.toString() == carIdStr)
            .map((d) => d.id)
            .toList()
        : state.tour.deliveries.map((d) => d.id).toList();

    setState(() {
      _localSortedList = [...defaultOrder];
    });

    final container = {
      ...state.sortingInformation,
      carIdStr: [...defaultOrder],
    };
    context.read<TourBloc>().add(
      ReplaceSortingEvent(
        carId: carIdStr,
        newSortingInformation: container,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TourBloc, TourState>(
      builder: (context, state) {
        if (state is! TourLoaded) {
          return const Center(child: CircularProgressIndicator());
        }

        return ReorderableListView(
          buildDefaultDragHandles: true,
          onReorder: (oldIndex, newIndex) {
            setState(() {
              _localSortedList = reorderList(
                _localSortedList,
                oldIndex,
                newIndex,
              );
            });

            context.read<TourBloc>().add(
              ReorderDeliveryEvent(
                newPosition: newIndex,
                oldPosition: oldIndex,
                carId: widget.selectedCarId.toString(),
              ),
            );
          },
          children: _localSortedList.map((id) {
            final Delivery delivery = state.tour.deliveries.firstWhere(
              (delivery) => delivery.id == id,
            );
            final int pos = _localSortedList.indexOf(id) + 1;

            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(delivery.customer.name),
              subtitle: Text(
                delivery.customer.address.toString(),
                style: const TextStyle(fontSize: 11),
              ),
              trailing: const Icon(Icons.drag_handle),
            );
          }).toList(),
        );
      },
    );
  }
}

/// Schmaler Controller, mit dem Eltern-Widgets die Liste zurücksetzen
/// können, ohne den internen State direkt anzufassen.
class SortableDeliveryListController {
  _SortableDeliveryListState? _state;

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

  /// Setzt die Liste auf die Default-Reihenfolge (Tour-Reihenfolge) zurück.
  void resetToDefault() => _state?._resetToDefault();
}
