import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hl_lieferservice/domain/entity/delivery.dart';
import 'package:hl_lieferservice/domain/entity/delivery_item.dart';
import 'package:hl_lieferservice/domain/entity/tour_details.dart';
import 'package:hl_lieferservice/feature/car_selection/bloc/bloc.dart';
import 'package:hl_lieferservice/feature/car_selection/bloc/state.dart';
import 'package:hl_lieferservice/feature/cars/bloc/cars_bloc.dart';
import 'package:hl_lieferservice/feature/cars/bloc/cars_state.dart';
import 'package:hl_lieferservice/feature/delivery/bloc/phase_bloc.dart';
import 'package:hl_lieferservice/feature/delivery/bloc/phase_event.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/model/delivery_phase.dart';
import 'package:hl_lieferservice/feature/delivery/overview/presentation/delivery_fail_page.dart';
import 'package:hl_lieferservice/feature/loading/presentation/loading_customer_page.dart';
import 'package:hl_lieferservice/widget/home/presentation/home_drawer.dart';
import 'package:hl_lieferservice/widget/phase_stepper/phase_stepper.dart';

/// Übersichts-Ansicht für die Beladen-Phase: alle Kunden mit ihren
/// Artikeln und Soll/Ist-Mengen.
///
/// Scans werden in der `LoadingCustomerPage` (Vollbild pro Kunde)
/// ausgelöst; diese Übersicht ist reines Status-Display und Navigation.
/// Der Button „Auslieferungs-Phase starten" unten erlaubt dem Fahrer,
/// jederzeit in die nächste Phase zu wechseln — die App erzwingt
/// bewusst keine 100%-Auslieferung (z. B. wenn ein Artikel fehlt und
/// der Fahrer das später hold/cancel-en will).
class LoadingOverviewPage extends StatelessWidget {
  const LoadingOverviewPage({super.key});

  String? _plateFor(BuildContext context, String? carId) {
    if (carId == null) return null;
    final state = context.read<CarsBloc>().state;
    if (state is! CarsLoaded) return null;
    for (final c in state.cars) {
      if (c.id == carId) return c.plate;
    }
    return null;
  }

  /// Beladereihenfolge = umgekehrte Sortier-Reihenfolge: wer zuletzt
  /// ausgeliefert wird, wird zuerst beladen (kommt unten in den LKW).
  List<Delivery> _ownDeliveriesInLoadingOrder(
    TourDetails details,
    String carId,
    bool multiCarTeam,
  ) {
    final relevant = multiCarTeam
        ? details.deliveriesSorted
            .where((d) => d.assignedCarId == carId)
            .toList()
        : details.deliveriesSorted;
    return relevant.reversed.toList();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<CarSelectBloc, CarSelectState>(
      builder: (context, carState) {
        final carId =
            carState is CarSelectComplete ? carState.selectedCar.id : '';

        return BlocBuilder<TourBloc, TourState>(
          builder: (context, tourState) {
            if (tourState is TourLoadFailed) {
              return const DeliveryLoadingFailedPage();
            }
            if (tourState is TourEmpty) {
              return Scaffold(
                drawer: const HomeAppDrawer(),
                appBar: AppBar(title: const Text('Beladung')),
                body: const _EmptyOverview(),
              );
            }
            if (tourState is! TourLoaded) {
              // Drawer auch im Ladezustand — analog zum TourEmpty-Branch,
              // damit der Fahrer beim Hängen nicht ohne Logout dasitzt.
              return Scaffold(
                drawer: const HomeAppDrawer(),
                appBar: AppBar(title: const Text('Beladung')),
                body: const Center(child: CircularProgressIndicator()),
              );
            }

            final carsState = context.read<CarsBloc>().state;
            final multiCarTeam =
                carsState is CarsLoaded && carsState.cars.length >= 2;
            final ordered = _ownDeliveriesInLoadingOrder(
              tourState.details,
              carId,
              multiCarTeam,
            );

            // Gate für „Auslieferungs-Phase starten": jede aktive Lieferung
            // muss im Standardlager fertig beladen sein. Pausierte/abgebrochene
            // zählen nicht; offene Filial-Items dürfen bleiben (werden unterwegs
            // geholt — siehe Status-Logik). Keine aktive Lieferung ⇒ kein Block.
            final canStart = ordered
                .where((d) => d.state == DeliveryState.active)
                .every(tourState.details.standardWarehouseLoadingDone);

            return Scaffold(
              drawer: const HomeAppDrawer(),
              appBar: PreferredSize(
                preferredSize: const Size.fromHeight(140),
                child: PhaseStepper(
                  currentPhase: DeliveryPhase.beladen,
                  carId: carId,
                ),
              ),
              body: SafeArea(
                top: false,
                child: ordered.isEmpty
                    ? const _EmptyOverview()
                    : _OverviewList(
                        deliveries: ordered,
                        details: tourState.details,
                        plateResolver: (id) => _plateFor(context, id),
                      ),
              ),
              bottomNavigationBar: _BottomBar(carId: carId, canStart: canStart),
            );
          },
        );
      },
    );
  }
}

class _OverviewList extends StatelessWidget {
  const _OverviewList({
    required this.deliveries,
    required this.details,
    required this.plateResolver,
  });

  final List<Delivery> deliveries;
  final TourDetails details;
  final String? Function(String?) plateResolver;

  /// Klassifiziert eine Lieferung in einen UX-Bucket. Bucket bestimmt,
  /// in welcher Sektion das Tile in der Übersicht landet.
  ///
  /// Lifecycle-Zustände (`held` / `canceled`) gewinnen vor der
  /// Standardlager-/Filial-Logik: eine pausierte oder abgebrochene
  /// Lieferung soll nicht versehentlich als „nächste Lieferung" oder
  /// „offen" auftauchen, auch wenn ihr Standardlager-Counter Items
  /// hätte.
  _OverviewBucket _bucketOf(Delivery delivery) {
    if (delivery.state == DeliveryState.canceled) {
      return _OverviewBucket.canceled;
    }
    if (delivery.state == DeliveryState.held) {
      return _OverviewBucket.paused;
    }
    final standardDone = details.standardWarehouseLoadingDone(delivery);
    final hasExternal = details.hasExternalWarehouseItems(delivery);
    if (standardDone && hasExternal) return _OverviewBucket.later;
    if (standardDone) return _OverviewBucket.done;
    return _OverviewBucket.open;
  }

  @override
  Widget build(BuildContext context) {
    // Standardlager-Items pro Lieferung — Basis für den Fortschritts-
    // Counter („X / Y Artikel" am Kunden). Filial-Items zählen hier
    // nicht; sie werden separat geladen und sollen den Fortschritt im
    // Hauptlager nicht verwässern.
    final standardItemsPerDelivery = <String, List<DeliveryItem>>{};
    for (final d in deliveries) {
      standardItemsPerDelivery[d.id] = d.items.where((it) {
        if (it.isRemoved) return false;
        if (!details.isArticleScannable(it.articleId)) return false;
        final w = details.warehouseOf(it.warehouseId);
        return w?.isStandard ?? false;
      }).toList();
    }

    // Lieferungen in drei Buckets sortieren. Innerhalb der Buckets
    // bleibt die Belade-Reihenfolge erhalten (Original-Index), damit der
    // Fahrer „Kunde Nr. 3 in der Reihenfolge" jederzeit identifizieren
    // kann — auch wenn die Karte gerade in „Später abholen" einsortiert
    // ist.
    final open = <_OverviewEntry>[];
    final later = <_OverviewEntry>[];
    final paused = <_OverviewEntry>[];
    final done = <_OverviewEntry>[];
    final canceled = <_OverviewEntry>[];
    for (int i = 0; i < deliveries.length; i++) {
      final d = deliveries[i];
      final entry = _OverviewEntry(
        originalIndex: i,
        delivery: d,
        standardItems: standardItemsPerDelivery[d.id] ?? const [],
      );
      switch (_bucketOf(d)) {
        case _OverviewBucket.open:
          open.add(entry);
        case _OverviewBucket.later:
          later.add(entry);
        case _OverviewBucket.paused:
          paused.add(entry);
        case _OverviewBucket.done:
          done.add(entry);
        case _OverviewBucket.canceled:
          canceled.add(entry);
      }
    }

    // „Nächste Lieferung" zieht den ersten Offen-Eintrag heraus und
    // präsentiert ihn in einer eigenen Sektion ganz oben — der Fahrer
    // sieht damit immer sofort, was als nächstes anliegt, statt aus
    // einer Liste die Position-Nr. 1 selbst rauszusuchen. Sobald die
    // Lieferung beladen ist, rutscht sie in „Später abholen" oder
    // „Fertig" und der Eintrag auf Position 2 wird zur neuen
    // „Nächsten" — automatisch, da diese Logik bei jedem Build neu
    // läuft.
    final _OverviewEntry? nextUp = open.isEmpty ? null : open.removeAt(0);

    final totalActive = deliveries
        .where((d) => d.state != DeliveryState.canceled)
        .length;
    // „Fertig beladen" = Standardlager fertig. Filial-Items
    // blockieren den Übergang in die Auslieferungs-Phase nicht.
    final doneActive = deliveries
        .where((d) =>
            d.state != DeliveryState.canceled &&
            details.standardWarehouseLoadingDone(d))
        .length;

    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 12, 16, 8),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    'Beladereihenfolge',
                    style: Theme.of(context).textTheme.titleMedium,
                  ),
                  Text(
                    '$doneActive / $totalActive Kunden',
                    style: Theme.of(context).textTheme.titleSmall?.copyWith(
                          fontWeight: FontWeight.bold,
                        ),
                  ),
                ],
              ),
              const SizedBox(height: 4),
              // Macht den Bezugsrahmen der Phase explizit: Es wird im
              // Standardlager beladen. Filial-Artikel sind die Ausnahme
              // und werden separat geholt — sonst entsteht der Eindruck,
              // man müsse für jede Lieferung mehrere Lager ansteuern.
              Row(
                children: [
                  Icon(
                    Icons.inventory_2_outlined,
                    size: 14,
                    color: Theme.of(context).colorScheme.onSurfaceVariant,
                  ),
                  const SizedBox(width: 4),
                  Expanded(
                    child: Text(
                      'Beladung im Standardlager · Filial-Artikel werden separat geholt',
                      style: Theme.of(context).textTheme.bodySmall?.copyWith(
                            color:
                                Theme.of(context).colorScheme.onSurfaceVariant,
                          ),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 8),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: LinearProgressIndicator(
                  value: totalActive == 0 ? 0.0 : doneActive / totalActive,
                  minHeight: 6,
                  backgroundColor: Theme.of(context)
                      .colorScheme
                      .surfaceContainerHighest,
                ),
              ),
            ],
          ),
        ),
        const Divider(height: 1),
        Expanded(
          child: ListView(
            padding: const EdgeInsets.only(top: 4, bottom: 16),
            children: [
              if (nextUp != null)
                _BucketSection(
                  title: 'Nächste Lieferung',
                  count: 1,
                  color: Theme.of(context).colorScheme.primary,
                  icon: Icons.local_shipping_outlined,
                  entries: [nextUp],
                  details: details,
                ),
              if (open.isNotEmpty)
                _BucketSection(
                  title: 'Offen',
                  count: open.length,
                  color: Theme.of(context)
                      .colorScheme
                      .primary
                      .withValues(alpha: 0.55),
                  entries: open,
                  details: details,
                ),
              if (later.isNotEmpty)
                _BucketSection(
                  title: 'Später abholen',
                  count: later.length,
                  color: Colors.amber.shade800,
                  entries: later,
                  details: details,
                ),
              if (paused.isNotEmpty)
                _BucketSection(
                  title: 'Pausiert',
                  count: paused.length,
                  color: Colors.orange.shade800,
                  icon: Icons.pause_circle_outline,
                  entries: paused,
                  details: details,
                ),
              if (done.isNotEmpty)
                _BucketSection(
                  title: 'Fertig',
                  count: done.length,
                  color: Colors.green.shade700,
                  entries: done,
                  details: details,
                ),
              if (canceled.isNotEmpty)
                _BucketSection(
                  title: 'Abgebrochen',
                  count: canceled.length,
                  color: Colors.red.shade700,
                  icon: Icons.cancel_outlined,
                  entries: canceled,
                  details: details,
                ),
            ],
          ),
        ),
      ],
    );
  }
}

class _OverviewTile extends StatelessWidget {
  const _OverviewTile({
    required this.position,
    required this.delivery,
    required this.standardItems,
    required this.details,
    required this.onTap,
  });

  final int position;
  final Delivery delivery;

  /// Scanbare, nicht-entfernte Items aus dem Standardlager. Basis für
  /// den Beladen-Fortschritt — Filial-Items werden separat geladen
  /// und zählen hier nicht mit.
  final List<DeliveryItem> standardItems;
  final TourDetails details;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final canceled = delivery.state == DeliveryState.canceled;
    final held = delivery.state == DeliveryState.held;
    final standardDone = details.standardWarehouseLoadingDone(delivery);
    final hasExternal = details.hasExternalWarehouseItems(delivery);
    final externalLabels = details.externalWarehouseLabels(delivery);
    final scannedStandardCount =
        standardItems.where((it) => it.isDone).length;
    final scannedAnyStandard =
        standardItems.any((it) => it.scanProgress.scannedQuantity > 0);
    final customer = details.customerOf(delivery);

    Color cardColor;
    Color borderColor;
    Color titleColor;
    String statusText;
    IconData statusIcon;

    // Lifecycle-States gewinnen vor der Beladen-Logik: pausiert /
    // abgebrochen sollen visuell sofort als solche erkennbar sein —
    // egal wie weit der Standardlager-Counter war.
    if (canceled) {
      cardColor = Colors.red.withValues(alpha: 0.06);
      borderColor = Colors.red.withValues(alpha: 0.35);
      titleColor = Colors.red.shade700;
      statusText = 'Abgebrochen';
      statusIcon = Icons.cancel_outlined;
    } else if (held) {
      cardColor = Colors.orange.withValues(alpha: 0.07);
      borderColor = Colors.orange.withValues(alpha: 0.45);
      titleColor = Colors.orange.shade800;
      statusText = 'Pausiert';
      statusIcon = Icons.pause_circle_outline;
    } else if (standardDone && hasExternal) {
      // Sonderfall, fachlich wichtig: Standardlager ist durch, aber im
      // Filiale wartet noch was. Der Fahrer kann technisch in die
      // Auslieferungs-Phase, muss aber wissen, dass er zwischendurch
      // ein zweites Lager ansteuert.
      cardColor = Colors.amber.withValues(alpha: 0.18);
      borderColor = Colors.amber.withValues(alpha: 0.55);
      titleColor = Colors.amber.shade800;
      statusText = 'Standardlager fertig — Filiale offen';
      statusIcon = Icons.warehouse_outlined;
    } else if (standardDone) {
      cardColor = Colors.green.withValues(alpha: 0.07);
      borderColor = Colors.green.withValues(alpha: 0.35);
      titleColor = Colors.green.shade700;
      statusText = 'Fertig beladen';
      statusIcon = Icons.check_circle_outline;
    } else if (scannedAnyStandard) {
      cardColor = Colors.orange.withValues(alpha: 0.07);
      borderColor = Colors.orange.withValues(alpha: 0.35);
      titleColor = Colors.orange.shade800;
      statusText = 'Beladung läuft';
      statusIcon = Icons.pending_outlined;
    } else {
      cardColor = theme.colorScheme.surfaceContainerLow;
      borderColor = Colors.transparent;
      titleColor = theme.colorScheme.onSurface;
      statusText = 'Offen';
      statusIcon = Icons.radio_button_unchecked;
    }

    // Bewusst KEIN Filial-Card-Highlight, solange das Standardlager
    // noch offen ist: eine Lieferung mit Standard- UND Filial-Items
    // soll sich nicht von einer reinen Standardlager-Lieferung
    // unterscheiden — der Fahrer belädt zuerst das Standardlager, und eine
    // orange Karte würde fälschlich einen Sonderzustand suggerieren
    // (irreführend besonders in der „Nächste Lieferung"-Sektion). Den
    // Hinweis aufs Filiale trägt allein das `_ExternalWarehouseBadge`
    // weiter unten. Der echte Sonderfall „Standardlager fertig — Filiale
    // offen" wird oben in der Status-Kette eigenständig amber gefärbt.

    // Fortschritts-Label rechts in der Status-Zeile.
    //
    // „X / Y Artikel" bezieht sich bewusst nur auf das Standardlager (siehe
    // `standardItems`). Hat eine Lieferung dort GAR KEINE Position, ergäbe das
    // ein irreführendes „0 / 0 Artikel" — die Card sähe leer aus, obwohl die
    // Ware nur aus einer Filiale kommt (später abholen) oder es sich um eine
    // reine Dienstleistung handelt. In diesen Fällen zeigen wir statt des
    // Zählers einen sprechenden Hinweis. So wirkt keine Card mehr „verloren".
    final String progressLabel;
    if (canceled || held) {
      progressLabel = '—';
    } else if (standardItems.isNotEmpty) {
      progressLabel = '$scannedStandardCount / ${standardItems.length} Artikel';
    } else if (hasExternal) {
      // Keine Standardlager-Ware, aber Filial-Items → wird separat geholt.
      // Das Filial-Badge unten trägt die Details; hier nur der Kurz-Hinweis.
      progressLabel = 'Nur Filiale';
    } else if (details.hasServiceItems(delivery)) {
      // Weder Standardlager- noch Filial-Ware, aber eine nicht-scanbare
      // Position → reine Dienstleistung. Rechtfertigt trotzdem die Anfahrt.
      progressLabel = 'Nur Dienstleistung';
    } else {
      // Defensive: keinerlei relevante Positionen — sollte praktisch nicht
      // vorkommen. Kein „0 / 0", sondern neutraler Strich.
      progressLabel = '—';
    }

    // Avatar-Hintergrund spiegelt den Lifecycle-State wider, damit die
    // Nummer-Bubble nicht weiterhin primary leuchtet, obwohl die
    // Lieferung pausiert/abgebrochen ist.
    final Color avatarColor;
    if (canceled) {
      avatarColor = Colors.red.shade700;
    } else if (held) {
      avatarColor = Colors.orange.shade800;
    } else {
      avatarColor = theme.colorScheme.primary;
    }

    final reason = delivery.stateReason;
    final showReason = (canceled || held) && reason != null && reason.isNotEmpty;

    return Opacity(
      opacity: canceled ? 0.65 : 1.0,
      child: Card(
        margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
        elevation: 0,
        color: cardColor,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12),
          side: BorderSide(color: borderColor),
        ),
        child: InkWell(
          onTap: onTap,
          borderRadius: BorderRadius.circular(12),
          child: Padding(
            padding: const EdgeInsets.all(12),
            child: Row(
              children: [
                CircleAvatar(
                  backgroundColor: avatarColor,
                  foregroundColor: theme.colorScheme.onPrimary,
                  radius: 18,
                  child: Text(
                    '$position',
                    style: const TextStyle(fontWeight: FontWeight.bold),
                  ),
                ),
                const SizedBox(width: 12),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        customer?.name ?? '⟨Unbekannter Kunde⟩',
                        style: TextStyle(
                          fontSize: 15,
                          fontWeight: FontWeight.w600,
                          color: titleColor,
                          decoration: canceled
                              ? TextDecoration.lineThrough
                              : TextDecoration.none,
                        ),
                      ),
                      const SizedBox(height: 2),
                      Text(
                        delivery.deliveryAddressSnapshot.oneLine,
                        style: TextStyle(
                          fontSize: 12,
                          color: theme.colorScheme.onSurfaceVariant,
                        ),
                      ),
                      const SizedBox(height: 4),
                      Row(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Padding(
                            padding: const EdgeInsets.only(top: 2),
                            child: Icon(statusIcon,
                                size: 14, color: titleColor),
                          ),
                          const SizedBox(width: 4),
                          Expanded(
                            child: Text(
                              statusText,
                              style: TextStyle(
                                fontSize: 12,
                                fontWeight: FontWeight.w500,
                                color: titleColor,
                              ),
                              softWrap: true,
                            ),
                          ),
                          const SizedBox(width: 10),
                          Text(
                            progressLabel,
                            style: TextStyle(
                              fontSize: 12,
                              color: theme.colorScheme.onSurfaceVariant,
                            ),
                          ),
                        ],
                      ),
                      if (showReason)
                        Padding(
                          padding: const EdgeInsets.only(left: 18, top: 2),
                          child: Text(
                            'Grund: $reason',
                            style: TextStyle(
                              fontSize: 11,
                              color: titleColor,
                            ),
                          ),
                        ),
                      // Filial-Badge nur sichtbar, wenn die Lieferung
                      // im aktiven Workflow ist. Pausiert / abgebrochen
                      // soll keine zusätzliche Filial-Aufmerksamkeit
                      // ziehen — die Aktion ist gerade unterbrochen oder
                      // beendet.
                      if (!canceled && !held && hasExternal) ...[
                        const SizedBox(height: 6),
                        _ExternalWarehouseBadge(labels: externalLabels),
                      ],
                    ],
                  ),
                ),
                const Icon(Icons.chevron_right),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _BottomBar extends StatelessWidget {
  const _BottomBar({required this.carId, required this.canStart});
  final String carId;

  /// Nur wenn alle aktiven Lieferungen im Standardlager fertig beladen sind,
  /// darf der Fahrer in die Auslieferungs-Phase wechseln.
  final bool canStart;

  @override
  Widget build(BuildContext context) {
    if (carId.isEmpty) return const SizedBox.shrink();
    final theme = Theme.of(context);
    return SafeArea(
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            if (!canStart)
              Padding(
                padding: const EdgeInsets.only(bottom: 8),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Icon(
                      Icons.info_outline,
                      size: 16,
                      color: theme.colorScheme.onSurfaceVariant,
                    ),
                    const SizedBox(width: 6),
                    Flexible(
                      child: Text(
                        'Erst alle Artikel des Standardlagers beladen',
                        style: TextStyle(
                          fontSize: 12,
                          color: theme.colorScheme.onSurfaceVariant,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            SizedBox(
              width: double.infinity,
              child: OutlinedButton.icon(
                onPressed: canStart
                    ? () {
                        context.read<PhaseBloc>().add(
                              PhaseSet(
                                carId: carId,
                                phase: DeliveryPhase.ausliefern,
                              ),
                            );
                      }
                    : null,
                icon: const Icon(Icons.arrow_forward),
                label: const Text('Auslieferungs-Phase starten'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

/// UX-Bucket der Übersicht. Bestimmt, in welche Sektion eine Lieferung
/// einsortiert wird:
/// * `open`     — Standardlager nicht fertig (= jetzt zu beladen)
/// * `later`    — Standardlager fertig, aber Filial-Items offen
/// * `paused`   — Lieferung explizit pausiert (`held`)
/// * `done`     — komplett fertig (Standardlager fertig & kein Filiale)
/// * `canceled` — endgültig abgebrochen
enum _OverviewBucket { open, later, paused, done, canceled }

/// Bündelt eine Lieferung mit ihrer Beladereihenfolge-Position für die
/// Übersicht — der `originalIndex` bleibt über die Sektions-Umsortierung
/// hinweg sichtbar im Tile-Avatar.
class _OverviewEntry {
  const _OverviewEntry({
    required this.originalIndex,
    required this.delivery,
    required this.standardItems,
  });

  final int originalIndex;
  final Delivery delivery;
  final List<DeliveryItem> standardItems;
}

/// Sektion in der Übersicht mit eigenem Header + zugehörigen Tiles.
/// Header zeigt Titel, farbigen Pill mit Anzahl und nimmt die Section-
/// Farbe als Akzent — Fahrer erkennt auf einen Blick, „was kommt jetzt".
class _BucketSection extends StatelessWidget {
  const _BucketSection({
    required this.title,
    required this.count,
    required this.color,
    required this.entries,
    required this.details,
    this.icon,
  });

  final String title;
  final int count;
  final Color color;
  final List<_OverviewEntry> entries;
  final TourDetails details;

  /// Optionales Icon vor dem Titel — wird aktuell nur für „Nächste
  /// Lieferung" verwendet, damit diese Sektion auf einen Blick als
  /// „aktiv jetzt" erkennbar ist. Bei den restlichen Sektionen reichen
  /// Farb-Balken + Pill als visueller Anker.
  final IconData? icon;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 16, 16, 4),
          child: Row(
            children: [
              Container(
                width: 4,
                height: 18,
                decoration: BoxDecoration(
                  color: color,
                  borderRadius: BorderRadius.circular(2),
                ),
              ),
              const SizedBox(width: 8),
              if (icon != null) ...[
                Icon(icon, size: 16, color: color),
                const SizedBox(width: 6),
              ],
              Text(
                title,
                style: TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.bold,
                  color: color,
                  letterSpacing: 0.4,
                ),
              ),
              const SizedBox(width: 8),
              Container(
                padding: const EdgeInsets.symmetric(
                    horizontal: 8, vertical: 1),
                decoration: BoxDecoration(
                  color: color.withValues(alpha: 0.15),
                  borderRadius: BorderRadius.circular(12),
                ),
                child: Text(
                  '$count',
                  style: TextStyle(
                    fontSize: 12,
                    fontWeight: FontWeight.w600,
                    color: color,
                  ),
                ),
              ),
            ],
          ),
        ),
        for (final entry in entries)
          _OverviewTile(
            position: entry.originalIndex + 1,
            delivery: entry.delivery,
            standardItems: entry.standardItems,
            details: details,
            onTap: () {
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (_) => LoadingCustomerPage(
                    initialIndex: entry.originalIndex,
                  ),
                ),
              );
            },
          ),
      ],
    );
  }
}

/// Hinweis-Badge unterhalb der Status-Zeile einer Lieferung mit Artikeln
/// aus einem oder mehreren Filialen.
///
/// Formuliert bewusst „Enthält auch … zum späteren Abholen": Die Lieferung
/// wird JETZT normal (im Standardlager) beladen — das Filial-Item ist
/// nur ein zusätzlicher Bestandteil. Das „auch" signalisiert den Zusatz,
/// und „zum späteren Abholen" hängt den Zeitbezug klar an den ARTIKEL, nicht
/// an die Lieferung (die sonst fälschlich als nach-hinten-geschoben wirkt).
class _ExternalWarehouseBadge extends StatelessWidget {
  const _ExternalWarehouseBadge({required this.labels});

  final List<String> labels;

  @override
  Widget build(BuildContext context) {
    final lagerText = labels.isEmpty
        ? 'Artikel zum späteren Abholen aus der Filiale'
        : 'Artikel zum späteren Abholen aus Filiale: ${labels.join(", ")}';

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 5),
      decoration: BoxDecoration(
        color: Colors.amber.withValues(alpha: 0.22),
        borderRadius: BorderRadius.circular(6),
        border: Border.all(color: Colors.amber.withValues(alpha: 0.7)),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(
            Icons.warehouse_outlined,
            size: 14,
            color: Colors.amber.shade800,
          ),
          const SizedBox(width: 4),
          Flexible(
            child: RichText(
              maxLines: 2,
              overflow: TextOverflow.ellipsis,
              text: TextSpan(
                style: TextStyle(
                  fontSize: 11,
                  fontWeight: FontWeight.w600,
                  color: Colors.amber.shade800,
                ),
                children: [
                  const TextSpan(
                    text: 'Enthält auch ',
                    style: TextStyle(fontWeight: FontWeight.w800),
                  ),
                  TextSpan(text: lagerText),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class _EmptyOverview extends StatelessWidget {
  const _EmptyOverview();

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.inbox_outlined, size: 64, color: scheme.onSurfaceVariant),
          const SizedBox(height: 12),
          Text(
            'Keine Lieferungen zum Beladen',
            style: Theme.of(context).textTheme.titleMedium,
          ),
          const SizedBox(height: 4),
          Text(
            'Für heute ist aktuell keine Tour verfügbar.',
            style: Theme.of(context)
                .textTheme
                .bodySmall
                ?.copyWith(color: scheme.onSurfaceVariant),
            textAlign: TextAlign.center,
          ),
          const SizedBox(height: 20),
          // Erneut die heutige Tour vom Backend laden. `LoadTour` blendet
          // währenddessen den Seiten-Ladeindikator ein (TourLoading-Zweig) und
          // landet danach wieder hier (TourEmpty) oder in der Tour-Ansicht.
          FilledButton.tonalIcon(
            onPressed: () => context.read<TourBloc>().add(const LoadTour()),
            icon: const Icon(Icons.refresh),
            label: const Text('Neu laden'),
          ),
        ],
      ),
    );
  }
}
