import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.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/delivery/bloc/tour_bloc.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/model/loading_group.dart';
import 'package:hl_lieferservice/feature/loading/presentation/loading_customer_page.dart';
import 'package:hl_lieferservice/feature/loading/util/loading_order.dart';
import 'package:hl_lieferservice/model/delivery.dart';
import 'package:hl_lieferservice/model/tour.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 in Beladereihen-
/// folge mit Fortschritts-Status. KEIN Scanner — der Scanner-Fokus bleibt
/// auf der [LoadingCustomerPage]. Tap auf einen Kunden öffnet seine
/// Vollbild-Ansicht mit dem entsprechenden Index.
class LoadingOverviewPage extends StatelessWidget {
  const LoadingOverviewPage({super.key});

  String? _lookupCarPlate(int? carId, Tour tour) {
    if (carId == null) return null;
    return tour.driver.cars.firstWhereOrNull((c) => c.id == carId)?.plate;
  }

  List<LoadingGroup> _buildGroups(TourLoaded state, String carIdStr) {
    final orderedIds = LoadingOrder.computeForCar(
      state: state,
      carIdStr: carIdStr,
    );
    final byId = {for (final d in state.tour.deliveries) d.id: d};
    final groups = <LoadingGroup>[];
    for (final id in orderedIds) {
      final delivery = byId[id];
      if (delivery == null) continue;
      if (delivery.state == DeliveryState.finished) continue;
      final scannable =
          delivery.articles.where((a) => a.scannable).toList(growable: false);
      if (scannable.isEmpty && delivery.state != DeliveryState.canceled) {
        continue;
      }
      groups.add(LoadingGroup(
        delivery: delivery,
        articles: scannable,
        carPlate: _lookupCarPlate(delivery.carId, state.tour),
      ));
    }
    return groups;
  }

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

        return BlocBuilder<TourBloc, TourState>(
          builder: (context, tourState) {
            if (tourState is TourLoadingFailed) {
              return const DeliveryLoadingFailedPage();
            }
            if (tourState is! TourLoaded) {
              return const Scaffold(
                body: Center(child: CircularProgressIndicator()),
              );
            }
            final groups = _buildGroups(tourState, carIdStr);

            return Scaffold(
              drawer: const HomeAppDrawer(),
              appBar: PreferredSize(
                preferredSize: const Size.fromHeight(140),
                child: PhaseStepper(
                  currentPhase: DeliveryPhase.beladen,
                  carId: carIdStr,
                ),
              ),
              body: SafeArea(
                top: false,
                child: groups.isEmpty
                    ? const _EmptyOverview()
                    : _OverviewList(groups: groups),
              ),
            );
          },
        );
      },
    );
  }
}

class _OverviewList extends StatelessWidget {
  const _OverviewList({required this.groups});

  final List<LoadingGroup> groups;

  @override
  Widget build(BuildContext context) {
    final totalActive = groups
        .where((g) => g.delivery.state != DeliveryState.canceled)
        .length;
    final doneActive = groups
        .where((g) =>
            g.delivery.state != DeliveryState.canceled && g.isComplete)
        .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: 6),
              ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: LinearProgressIndicator(
                  value: totalActive == 0 ? 0.0 : doneActive / totalActive,
                  minHeight: 6,
                  backgroundColor: Theme.of(context)
                      .colorScheme
                      .surfaceContainerHighest,
                  valueColor: AlwaysStoppedAnimation<Color>(
                    doneActive == totalActive && totalActive > 0
                        ? Colors.green
                        : Theme.of(context).primaryColor,
                  ),
                ),
              ),
            ],
          ),
        ),
        const Divider(height: 1),
        Expanded(
          child: ListView.builder(
            padding: const EdgeInsets.only(top: 8, bottom: 16),
            itemCount: groups.length,
            itemBuilder: (context, index) {
              final g = groups[index];
              return _OverviewTile(
                position: index + 1,
                group: g,
                onTap: () {
                  // Push (kein pushReplacement): die Übersicht ist seit dem
                  // Routing-Umbau in home.dart die Wurzel der Beladen-Phase.
                  // Vom Vollbild kehrt der Fahrer per pop zurück auf diese
                  // Übersicht — der Stack bleibt damit flach.
                  Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (_) => LoadingCustomerPage(initialIndex: index),
                    ),
                  );
                },
              );
            },
          ),
        ),
      ],
    );
  }
}

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

  final int position;
  final LoadingGroup group;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final canceled = group.delivery.state == DeliveryState.canceled;
    final isComplete = group.isComplete;
    final isPartial = group.isPartial;
    final hasExternalWarehouse = group.hasExternalWarehouseArticles;

    // cardColor und borderColor sind nicht final, weil das Außenlager-
    // Highlight sie weiter unten ggf. überschreibt.
    Color cardColor;
    Color borderColor;
    final Color titleColor;
    final String statusText;
    final IconData statusIcon;

    if (canceled) {
      cardColor = Colors.grey.withValues(alpha: 0.08);
      borderColor = Colors.grey.withValues(alpha: 0.35);
      titleColor = Colors.grey.shade700;
      statusText = "Abgebrochen";
      statusIcon = Icons.cancel_outlined;
    } else if (isComplete && hasExternalWarehouse) {
      // Standardlager ist fertig, aber es liegen noch Artikel in einem
      // anderen Lager — die Lieferung ist also NICHT komplett beladen.
      // Wir machen das im Status-Text explizit, damit der Fahrer nicht
      // fälschlich davon ausgeht, dass nichts mehr offen ist.
      cardColor = Colors.deepOrange.withValues(alpha: 0.10);
      borderColor = Colors.deepOrange.withValues(alpha: 0.45);
      titleColor = Colors.deepOrange.shade800;
      statusText = "Standardlager fertig — Außenlager offen";
      statusIcon = Icons.warehouse_outlined;
    } else if (isComplete) {
      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 (isPartial) {
      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;
    }

    // Außenlager-Hervorhebung: lebt unabhängig vom Scan-Status. Eine
    // abgebrochene Lieferung bleibt grau, ansonsten überschreibt das
    // Außenlager-Highlight die Standard-Farben durch ein klar erkennbares
    // Orange — der Fahrer muss früh genug wissen, dass er ein anderes
    // Lager anfahren wird. Der Sonderzweig "isComplete && hasExternal-
    // Warehouse" oben hat das Highlight schon gesetzt, hier greift es
    // für die noch nicht fertigen Fälle.
    if (!canceled && hasExternalWarehouse && !isComplete) {
      cardColor = Colors.deepOrange.withValues(alpha: 0.10);
      borderColor = Colors.deepOrange.withValues(alpha: 0.65);
    }

    final progressLabel = canceled
        ? "—"
        : "${group.completeArticles}/${group.totalArticles} Artikel";

    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:
                      canceled ? Colors.grey : theme.colorScheme.primary,
                  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(
                        group.delivery.customer.name,
                        style: TextStyle(
                          fontSize: 15,
                          fontWeight: FontWeight.w600,
                          color: titleColor,
                          decoration: canceled
                              ? TextDecoration.lineThrough
                              : TextDecoration.none,
                        ),
                      ),
                      const SizedBox(height: 2),
                      Text(
                        group.delivery.customer.address.toString(),
                        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, damit lange Status-Texte wie
                          // "Standardlager fertig — Außenlager offen"
                          // umbrechen statt zu überlaufen.
                          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 (!canceled && hasExternalWarehouse) ...[
                        const SizedBox(height: 6),
                        _ExternalWarehouseBadge(
                          labels: group.externalWarehouseLabels,
                        ),
                      ],
                    ],
                  ),
                ),
                const Icon(Icons.chevron_right),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

/// Hinweis-Badge unter dem Status-Row einer Lieferung mit Artikeln aus
/// einem oder mehreren Außenlagern. Listet die betroffenen Lager-Namen
/// auf, damit der Fahrer beim Beladen weiß, wohin er zusätzlich muss.
class _ExternalWarehouseBadge extends StatelessWidget {
  const _ExternalWarehouseBadge({required this.labels});

  final List<String> labels;

  @override
  Widget build(BuildContext context) {
    final text = labels.isEmpty
        ? "Außenlager"
        : "Außenlager: ${labels.join(", ")}";

    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
      decoration: BoxDecoration(
        color: Colors.deepOrange.withValues(alpha: 0.15),
        borderRadius: BorderRadius.circular(6),
        border: Border.all(color: Colors.deepOrange.withValues(alpha: 0.6)),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.warehouse_outlined,
              size: 14, color: Colors.deepOrange.shade700),
          const SizedBox(width: 4),
          Flexible(
            child: Text(
              text,
              style: TextStyle(
                fontSize: 11,
                fontWeight: FontWeight.w600,
                color: Colors.deepOrange.shade800,
              ),
              maxLines: 2,
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ],
      ),
    );
  }
}

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