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/tour_details.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/widget/home/presentation/home_drawer.dart';
import 'package:hl_lieferservice/widget/phase_stepper/phase_stepper.dart';

/// Page für die erste Phase bei Mehr-Auto-Teams: Auswählen der eigenen
/// Lieferungen aus dem gemeinsamen Tour-Pool.
///
/// Aufbau:
/// * Tab "Verfügbar" — alle Lieferungen, die noch keinem Fahrzeug
///   zugeordnet sind. Multiselect, Bulk-Bestätigung per BottomBar-Button.
/// * Tab "Vergeben"  — Lieferungen, die bereits zugeordnet sind. Tap auf
///   eigene → Freigabe-Dialog; Tap auf fremde → Umlade-Dialog.
/// * Persistente BottomBar: "Weiter zum Sortieren" — wechselt die Phase.
class DeliverySelectionPage extends StatefulWidget {
  const DeliverySelectionPage({super.key, required this.selectedCarId});

  final String selectedCarId;

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

class _DeliverySelectionPageState extends State<DeliverySelectionPage> {
  final Set<String> _selectedIds = <String>{};

  /// Sucht das Kennzeichen eines Fahrzeugs in der aktuell geladenen
  /// CarsBloc-Liste. Liefert "?" als Fallback, wenn das Auto nicht (mehr)
  /// im Account ist — z. B. nach Personalwechsel zwischen Tour-Syncs.
  String _plateFor(String? carId) {
    if (carId == null) return '?';
    final carsState = context.read<CarsBloc>().state;
    if (carsState is! CarsLoaded) return '?';
    for (final c in carsState.cars) {
      if (c.id == carId) return c.plate;
    }
    return '?';
  }

  void _confirmSelection() {
    if (_selectedIds.isEmpty) return;
    final ids = List<String>.from(_selectedIds);

    // EIN Bulk-Event statt N parallel laufender Single-Events: vermeidet
    // die Race-Condition, bei der `flutter_bloc`s default-concurrent
    // Event-Processing parallele Handler den Initial-State lesen lässt
    // und sich am Ende beim `emit` gegenseitig überschreiben.
    context.read<TourBloc>().add(
          AssignCarToDeliveries(
            deliveryIds: ids,
            carId: widget.selectedCarId,
          ),
        );

    setState(_selectedIds.clear);
  }

  void _goToSorting() {
    context.read<PhaseBloc>().add(
          PhaseSet(carId: widget.selectedCarId, phase: DeliveryPhase.sortieren),
        );
  }

  Future<void> _showReleaseDialog(Delivery delivery, TourDetails details) async {
    final customer = details.customerOf(delivery);
    final result = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Lieferung freigeben'),
        content: Text(
          '${customer?.name ?? 'Diese Lieferung'} wurde Ihrem Fahrzeug '
          'zugeordnet. Möchten Sie sie wieder freigeben?',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(ctx).pop(false),
            child: const Text('Abbrechen'),
          ),
          FilledButton(
            onPressed: () => Navigator.of(ctx).pop(true),
            child: const Text('Freigeben'),
          ),
        ],
      ),
    );

    if (result != true || !mounted) return;
    context.read<TourBloc>().add(
          AssignCarToDelivery(deliveryId: delivery.id, carId: null),
        );
  }

  Future<void> _showTakeoverDialog(
    Delivery delivery,
    TourDetails details,
  ) async {
    final customer = details.customerOf(delivery);
    final foreignPlate = _plateFor(delivery.assignedCarId);
    final ownPlate = _plateFor(widget.selectedCarId);
    final theme = Theme.of(context);

    final result = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Lieferung umladen'),
        content: RichText(
          text: TextSpan(
            style: theme.textTheme.bodyMedium,
            children: [
              TextSpan(
                text: '${customer?.name ?? 'Diese Lieferung'} ist aktuell ',
              ),
              TextSpan(
                text: foreignPlate,
                style: const TextStyle(fontWeight: FontWeight.bold),
              ),
              const TextSpan(
                text: ' zugeordnet. Möchten Sie diese Lieferung auf ',
              ),
              TextSpan(
                text: ownPlate,
                style: const TextStyle(fontWeight: FontWeight.bold),
              ),
              const TextSpan(text: ' umladen?'),
            ],
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(ctx).pop(false),
            child: const Text('Abbrechen'),
          ),
          FilledButton(
            style: FilledButton.styleFrom(
              backgroundColor: theme.colorScheme.error,
              foregroundColor: theme.colorScheme.onError,
            ),
            onPressed: () => Navigator.of(ctx).pop(true),
            child: const Text('Übernehmen'),
          ),
        ],
      ),
    );

    if (result != true || !mounted) return;
    context.read<TourBloc>().add(
          AssignCarToDelivery(
            deliveryId: delivery.id,
            carId: widget.selectedCarId,
          ),
        );
  }

  // ─── Widgets ─────────────────────────────────────────────────────────

  Widget _plateBadge(BuildContext context, String plate, {bool own = false}) {
    final theme = Theme.of(context);
    final bg = own
        ? theme.colorScheme.primary
        : theme.colorScheme.surfaceContainerHighest;
    final fg = own
        ? theme.colorScheme.onPrimary
        : theme.colorScheme.onSurfaceVariant;
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
      decoration: BoxDecoration(
        color: bg,
        borderRadius: BorderRadius.circular(6),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.local_shipping_outlined, size: 12, color: fg),
          const SizedBox(width: 4),
          Text(
            plate,
            style: TextStyle(fontSize: 11, fontWeight: FontWeight.bold, color: fg),
          ),
        ],
      ),
    );
  }

  Widget _emptyState({
    required IconData icon,
    required String title,
    String? subtitle,
  }) {
    final theme = Theme.of(context);
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(32),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(icon, size: 64, color: theme.colorScheme.outline),
            const SizedBox(height: 12),
            Text(
              title,
              style: theme.textTheme.titleMedium,
              textAlign: TextAlign.center,
            ),
            if (subtitle != null) ...[
              const SizedBox(height: 6),
              Text(
                subtitle,
                style: theme.textTheme.bodySmall,
                textAlign: TextAlign.center,
              ),
            ],
          ],
        ),
      ),
    );
  }

  Widget _availableTab(List<Delivery> available, TourDetails details) {
    if (available.isEmpty) {
      return _emptyState(
        icon: Icons.inbox_outlined,
        title: 'Alle Lieferungen sind verteilt.',
        subtitle: 'Im Tab "Vergeben" können Sie eigene Lieferungen '
            'freigeben oder fremde übernehmen.',
      );
    }

    return ListView.builder(
      padding: const EdgeInsets.symmetric(vertical: 4),
      itemCount: available.length,
      itemBuilder: (context, index) {
        final delivery = available[index];
        final customer = details.customerOf(delivery);
        final isSelected = _selectedIds.contains(delivery.id);
        return CheckboxListTile(
          key: ValueKey('available-${delivery.id}'),
          value: isSelected,
          onChanged: (checked) {
            // Während ein Bulk-Zuweisung läuft, blockiert der
            // OperationViewEnforcer die Eingabe global; ein separates
            // `_isAssigning`-Lock ist hier nicht mehr nötig.
            setState(() {
              if (checked == true) {
                _selectedIds.add(delivery.id);
              } else {
                _selectedIds.remove(delivery.id);
              }
            });
          },
          title: Text(
            customer?.name ?? '⟨Unbekannter Kunde⟩',
            style: const TextStyle(fontWeight: FontWeight.w600),
          ),
          subtitle: Text(
            delivery.deliveryAddressSnapshot.oneLine,
            style: const TextStyle(fontSize: 12),
          ),
          controlAffinity: ListTileControlAffinity.leading,
        );
      },
    );
  }

  Widget _assignedTab(List<Delivery> assigned, TourDetails details) {
    if (assigned.isEmpty) {
      return _emptyState(
        icon: Icons.local_shipping_outlined,
        title: 'Noch keine Lieferungen verteilt.',
      );
    }

    final theme = Theme.of(context);

    return ListView.builder(
      padding: const EdgeInsets.symmetric(vertical: 4),
      itemCount: assigned.length,
      itemBuilder: (context, index) {
        final delivery = assigned[index];
        final isOwn = delivery.assignedCarId == widget.selectedCarId;
        final plate = _plateFor(delivery.assignedCarId);
        final customer = details.customerOf(delivery);

        return Material(
          color: isOwn
              ? theme.colorScheme.primaryContainer.withValues(alpha: 0.35)
              : null,
          child: ListTile(
            key: ValueKey('assigned-${delivery.id}'),
            onTap: () {
              if (isOwn) {
                _showReleaseDialog(delivery, details);
              } else {
                _showTakeoverDialog(delivery, details);
              }
            },
            leading: Icon(
              isOwn ? Icons.check_circle : Icons.person_outline,
              color: isOwn
                  ? theme.colorScheme.primary
                  : theme.colorScheme.onSurfaceVariant,
            ),
            title: Text(
              customer?.name ?? '⟨Unbekannter Kunde⟩',
              style: TextStyle(
                fontWeight: FontWeight.w600,
                color: isOwn ? theme.colorScheme.primary : null,
              ),
            ),
            subtitle: Text(
              delivery.deliveryAddressSnapshot.oneLine,
              style: const TextStyle(fontSize: 12),
            ),
            trailing: _plateBadge(context, plate, own: isOwn),
          ),
        );
      },
    );
  }

  Widget _buildBottomBar() {
    final hasSelection = _selectedIds.isNotEmpty;

    // Disabled-State und Spinner während des Bulk-Zuweisens übernimmt
    // global der `OperationViewEnforcer` (StartOperation/FinishOperation
    // aus dem TourBloc) — daher hier keine lokale Lock-Variable mehr.
    return SafeArea(
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            if (hasSelection)
              SizedBox(
                width: double.infinity,
                child: FilledButton.icon(
                  onPressed: _confirmSelection,
                  icon: const Icon(Icons.check),
                  label: Text(
                    'Auswahl bestätigen (${_selectedIds.length})',
                  ),
                ),
              ),
            if (hasSelection) const SizedBox(height: 8),
            SizedBox(
              width: double.infinity,
              child: OutlinedButton.icon(
                onPressed: _goToSorting,
                icon: const Icon(Icons.arrow_forward),
                label: const Text('Weiter zum Sortieren'),
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TourBloc, TourState>(
      builder: (context, state) {
        if (state is TourLoadFailed) {
          return const DeliveryLoadingFailedPage();
        }
        if (state is TourEmpty) {
          return Scaffold(
            drawer: const HomeAppDrawer(),
            appBar: AppBar(title: const Text('Lieferungen auswählen')),
            body: const Center(
              child: Padding(
                padding: EdgeInsets.all(24),
                child: Text(
                  'Für heute ist keine Tour zugewiesen.',
                  style: TextStyle(fontSize: 16),
                  textAlign: TextAlign.center,
                ),
              ),
            ),
          );
        }
        if (state is! TourLoaded) {
          // Drawer auch hier — Fahrer soll im Lade-Hang ausloggen können.
          return Scaffold(
            drawer: const HomeAppDrawer(),
            appBar: AppBar(title: const Text('Lieferungen auswählen')),
            body: const Center(child: CircularProgressIndicator()),
          );
        }

        final details = state.details;
        final available = details.deliveries
            .where((d) => d.assignedCarId == null)
            .toList();
        final assigned = details.deliveries
            .where((d) => d.assignedCarId != null)
            .toList();

        _selectedIds.removeWhere(
          (id) => !available.any((d) => d.id == id),
        );

        return DefaultTabController(
          length: 2,
          child: Scaffold(
            drawer: const HomeAppDrawer(),
            appBar: PreferredSize(
              preferredSize: const Size.fromHeight(140 + kTextTabBarHeight),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  PhaseStepper(
                    currentPhase: DeliveryPhase.auswaehlen,
                    carId: widget.selectedCarId,
                  ),
                  Material(
                    color: Theme.of(context).primaryColor,
                    child: TabBar(
                      labelColor: Theme.of(context).colorScheme.onPrimary,
                      unselectedLabelColor: Theme.of(context)
                          .colorScheme
                          .onPrimary
                          .withValues(alpha: 0.6),
                      indicatorColor: Theme.of(context).colorScheme.onPrimary,
                      tabs: [
                        Tab(text: 'Verfügbar (${available.length})'),
                        Tab(text: 'Vergeben (${assigned.length})'),
                      ],
                    ),
                  ),
                ],
              ),
            ),
            body: TabBarView(
              children: [
                _availableTab(available, details),
                _assignedTab(assigned, details),
              ],
            ),
            bottomNavigationBar: _buildBottomBar(),
          ),
        );
      },
    );
  }
}
