import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:signature/signature.dart';

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

/// Daten, die der Abschluss-Flow an den Aufrufer zurückgibt: beide
/// Unterschriften als PNG plus die dokumentierten Bestätigungen des Kunden.
class SignatureResult {
  const SignatureResult({
    required this.customerSignaturePng,
    required this.driverSignaturePng,
    required this.receiptConfirmed,
    required this.notesAcknowledged,
    required this.acknowledgedNoteIds,
    required this.paymentCollected,
  });

  final Uint8List customerSignaturePng;
  final Uint8List driverSignaturePng;
  final bool receiptConfirmed;
  final bool notesAcknowledged;
  final List<String> acknowledgedNoteIds;

  /// Fahrer hat das Inkasso (Bar/EC) des offenen Betrags bestätigt. `false`,
  /// wenn kein Inkasso anfiel (offen == 0 oder „Auf Rechnung").
  final bool paymentCollected;
}

/// Mehrstufiger Unterschrift-Flow zum Abschließen einer Lieferung.
///
/// Stufe 0 (Fahrer, optional): nur wenn beim Abschluss ein offener Betrag
/// per Vor-Ort-Inkasso (Bar/EC) zu kassieren ist ([requiresCollection]).
/// Der Fahrer bestätigt, dass der Betrag erhalten/abgerechnet wurde — VOR
/// beiden Unterschriften.
/// Stufe 1 (Kunde): sieht die Anmerkungen zur Lieferung, hakt zwei
/// Bestätigungen ab (Anmerkungen-Kenntnisnahme — nur Pflicht, wenn Notizen
/// vorhanden; Empfangsbestätigung — immer Pflicht) und unterschreibt.
/// Stufe 2 (Fahrer): unterschreibt.
///
/// Erst nach beiden Unterschriften ruft die View [onSigned] mit dem
/// vollständigen [SignatureResult] auf — der Aufrufer triggert dann den
/// Backend-Abschluss und schließt die Seite.
class SignatureView extends StatefulWidget {
  const SignatureView({
    super.key,
    required this.delivery,
    required this.details,
    required this.onSigned,
    this.requiresCollection = false,
    this.openAmount = 0,
    this.paymentMethodLabel = '',
  });

  final Delivery delivery;
  final TourDetails details;
  final void Function(SignatureResult result) onSigned;

  /// Offener Betrag muss vor Ort kassiert werden (offen > 0 UND Bar/EC).
  /// Schaltet Stufe 0 (Inkasso-Bestätigung) frei.
  final bool requiresCollection;

  /// Offener Betrag in Euro (nur für die Anzeige in Stufe 0).
  final double openAmount;

  /// Anzeigename der Zahlungsmethode (z. B. „Bar", „EC-Karte").
  final String paymentMethodLabel;

  @override
  State<SignatureView> createState() => _SignatureViewState();
}

/// Stufen des Abschluss-Flows.
enum _SignStage { payment, customer, driver }

class _SignatureViewState extends State<SignatureView> {
  static const String _receiptText =
      'Ich bestätige, dass ich die Ware im ordnungsgemäßen Zustand erhalten '
      'habe und, dass die Aufstell- und Einbauarbeiten korrekt durchgeführt '
      'wurden.';
  static const String _notesText =
      'Ich nehme die oben genannten Anmerkungen zur Lieferung zur Kenntnis.';

  final SignatureController _customerController = SignatureController(
    penStrokeWidth: 3,
    penColor: Colors.black,
    exportBackgroundColor: Colors.white,
  );
  final SignatureController _driverController = SignatureController(
    penStrokeWidth: 3,
    penColor: Colors.black,
    exportBackgroundColor: Colors.white,
  );

  late final List<DeliveryNote> _notes;
  late _SignStage _stage;
  bool _paymentConfirmed = false;
  bool _receiptAccepted = false;
  bool _notesAccepted = false;
  bool _customerEmpty = true;
  bool _driverEmpty = true;

  bool get _notesEmpty => _notes.isEmpty;

  @override
  void initState() {
    super.initState();
    // Inkasso-Bestätigung (Stufe 0) nur wenn gefordert, sonst direkt zum Kunden.
    _stage =
        widget.requiresCollection ? _SignStage.payment : _SignStage.customer;
    _notes = widget.details.notesByDeliveryId[widget.delivery.id] ??
        const <DeliveryNote>[];
    _customerController.addListener(() {
      if (_customerEmpty != _customerController.isEmpty) {
        setState(() => _customerEmpty = _customerController.isEmpty);
      }
    });
    _driverController.addListener(() {
      if (_driverEmpty != _driverController.isEmpty) {
        setState(() => _driverEmpty = _driverController.isEmpty);
      }
    });
  }

  @override
  void dispose() {
    _customerController.dispose();
    _driverController.dispose();
    super.dispose();
  }

  bool get _customerStepValid =>
      _receiptAccepted && (_notesAccepted || _notesEmpty) && !_customerEmpty;

  /// Ist der Primär-Button auf der aktuellen Stufe aktiv?
  bool get _stageValid {
    switch (_stage) {
      case _SignStage.payment:
        return _paymentConfirmed;
      case _SignStage.customer:
        return _customerStepValid;
      case _SignStage.driver:
        return !_driverEmpty;
    }
  }

  Future<void> _onPrimaryPressed() async {
    switch (_stage) {
      case _SignStage.payment:
        setState(() => _stage = _SignStage.customer);
        return;
      case _SignStage.customer:
        setState(() => _stage = _SignStage.driver);
        return;
      case _SignStage.driver:
        final customerPng = await _customerController.toPngBytes();
        final driverPng = await _driverController.toPngBytes();
        if (customerPng == null || driverPng == null) return;
        widget.onSigned(
          SignatureResult(
            customerSignaturePng: customerPng,
            driverSignaturePng: driverPng,
            receiptConfirmed: _receiptAccepted,
            notesAcknowledged: _notesEmpty ? false : _notesAccepted,
            acknowledgedNoteIds:
                _notesEmpty ? const [] : _notes.map((n) => n.id).toList(),
            paymentCollected: widget.requiresCollection && _paymentConfirmed,
          ),
        );
    }
  }

  String get _paymentText {
    final amount = widget.openAmount.toStringAsFixed(2).replaceAll('.', ',');
    final via = widget.paymentMethodLabel.isEmpty
        ? ''
        : ' per ${widget.paymentMethodLabel}';
    return 'Ich bestätige, dass der offene Betrag von $amount €$via '
        'erhalten bzw. abgerechnet wurde.';
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final customer = widget.details.customerOf(widget.delivery);
    final date = DateFormat('dd.MM.yyyy').format(DateTime.now());
    final isPayment = _stage == _SignStage.payment;
    final isDriver = _stage == _SignStage.driver;

    final String title;
    switch (_stage) {
      case _SignStage.payment:
        title = 'Zahlung bestätigen';
      case _SignStage.customer:
        title = 'Unterschrift des Kunden';
      case _SignStage.driver:
        title = 'Unterschrift des Fahrers';
    }

    return Scaffold(
      appBar: AppBar(title: Text(title)),
      body: SafeArea(
        child: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            if (isPayment) ...[
              // Stufe 0 — Fahrer kassiert (Bar/EC) und bestätigt VOR den
              // Unterschriften.
              _PaymentDueCard(
                openAmount: widget.openAmount,
                methodLabel: widget.paymentMethodLabel,
              ),
              const SizedBox(height: 16),
              _ConfirmTile(
                value: _paymentConfirmed,
                enabled: true,
                label: _paymentText,
                onChanged: (v) => setState(() => _paymentConfirmed = v),
              ),
            ] else ...[
              if (!isDriver) ...[
                _NotesSection(notes: _notes),
                const SizedBox(height: 16),
                _ConfirmTile(
                  value: _notesAccepted,
                  enabled: !_notesEmpty,
                  label: _notesText,
                  onChanged: (v) => setState(() => _notesAccepted = v),
                ),
                _ConfirmTile(
                  value: _receiptAccepted,
                  enabled: true,
                  label: _receiptText,
                  onChanged: (v) => setState(() => _receiptAccepted = v),
                ),
                const SizedBox(height: 16),
              ],
              Text(
                'Lieferung an: ${customer?.name ?? '⟨Unbekannter Kunde⟩'}',
                style: theme.textTheme.titleSmall
                    ?.copyWith(fontWeight: FontWeight.w700),
              ),
              const SizedBox(height: 8),
              _SignaturePad(
                controller: isDriver ? _driverController : _customerController,
                onClear: () =>
                    (isDriver ? _driverController : _customerController)
                        .clear(),
              ),
              const SizedBox(height: 4),
              Text(
                '${customer?.address.city ?? ''}, den $date',
                style: theme.textTheme.bodySmall,
              ),
            ],
            const SizedBox(height: 24),
            FilledButton.icon(
              onPressed: _stageValid ? _onPrimaryPressed : null,
              icon: Icon(isDriver ? Icons.check : Icons.arrow_forward),
              label: Text(isDriver ? 'Abschließen' : 'Weiter'),
            ),
          ],
        ),
      ),
    );
  }
}

// ─── Inkasso-Hinweis (Stufe 0) ──────────────────────────────────────────────

class _PaymentDueCard extends StatelessWidget {
  const _PaymentDueCard({required this.openAmount, required this.methodLabel});

  final double openAmount;
  final String methodLabel;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final amount = openAmount.toStringAsFixed(2).replaceAll('.', ',');
    return Card(
      margin: EdgeInsets.zero,
      color: theme.colorScheme.primary.withValues(alpha: 0.07),
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Offener Betrag',
              style: theme.textTheme.titleMedium
                  ?.copyWith(fontWeight: FontWeight.w700),
            ),
            const SizedBox(height: 8),
            Row(
              children: [
                Icon(Icons.payments_outlined, color: theme.colorScheme.primary),
                const SizedBox(width: 10),
                Text(
                  '$amount €',
                  style: theme.textTheme.headlineSmall?.copyWith(
                    fontWeight: FontWeight.w800,
                    color: theme.colorScheme.primary,
                  ),
                ),
                const Spacer(),
                if (methodLabel.isNotEmpty)
                  Chip(
                    label: Text(methodLabel),
                    visualDensity: VisualDensity.compact,
                  ),
              ],
            ),
            const SizedBox(height: 8),
            Text(
              'Bitte den Betrag bar entgegennehmen oder über das EC-Gerät '
              'abrechnen und anschließend bestätigen.',
              style: theme.textTheme.bodySmall?.copyWith(
                color: theme.colorScheme.onSurfaceVariant,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// ─── Notizen-Block ────────────────────────────────────────────────────────

class _NotesSection extends StatelessWidget {
  const _NotesSection({required this.notes});

  final List<DeliveryNote> notes;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          'Anmerkungen zur Lieferung',
          style:
              theme.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w700),
        ),
        const SizedBox(height: 8),
        if (notes.isEmpty)
          Card(
            margin: EdgeInsets.zero,
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Text(
                'Keine Anmerkungen vorhanden.',
                style: TextStyle(
                  fontStyle: FontStyle.italic,
                  color: theme.colorScheme.onSurfaceVariant,
                ),
              ),
            ),
          )
        else
          Card(
            margin: EdgeInsets.zero,
            child: Column(
              children: [
                for (int i = 0; i < notes.length; i++) ...[
                  ListTile(
                    leading: Icon(
                      notes[i].imageAttachment != null
                          ? (notes[i].imageAttachmentDeleted
                              ? Icons.picture_as_pdf_outlined
                              : Icons.photo_outlined)
                          : Icons.event_note_outlined,
                      color: theme.colorScheme.primary,
                    ),
                    title: Text(
                      notes[i].text?.trim().isNotEmpty == true
                          ? notes[i].text!.trim()
                          : (notes[i].imageAttachmentDeleted
                              ? 'Bild im Lieferbericht enthalten'
                              : 'Foto-Anhang'),
                    ),
                  ),
                  if (i < notes.length - 1)
                    const Divider(height: 1, indent: 16, endIndent: 16),
                ],
              ],
            ),
          ),
      ],
    );
  }
}

// ─── Bestätigungs-Checkbox ──────────────────────────────────────────────────

class _ConfirmTile extends StatelessWidget {
  const _ConfirmTile({
    required this.value,
    required this.enabled,
    required this.label,
    required this.onChanged,
  });

  final bool value;
  final bool enabled;
  final String label;
  final ValueChanged<bool> onChanged;

  @override
  Widget build(BuildContext context) {
    return CheckboxListTile(
      value: value,
      onChanged: enabled ? (v) => onChanged(v ?? false) : null,
      controlAffinity: ListTileControlAffinity.leading,
      contentPadding: EdgeInsets.zero,
      title: Text(label, style: const TextStyle(fontSize: 14)),
    );
  }
}

// ─── Signatur-Pad ───────────────────────────────────────────────────────────

class _SignaturePad extends StatelessWidget {
  const _SignaturePad({required this.controller, required this.onClear});

  final SignatureController controller;
  final VoidCallback onClear;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Container(
          height: 220,
          decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(color: theme.colorScheme.outline),
            borderRadius: BorderRadius.circular(8),
          ),
          clipBehavior: Clip.antiAlias,
          child: Signature(
            controller: controller,
            backgroundColor: Colors.white,
          ),
        ),
        Align(
          alignment: Alignment.centerRight,
          child: TextButton.icon(
            onPressed: onClear,
            icon: const Icon(Icons.undo),
            label: const Text('Löschen'),
          ),
        ),
      ],
    );
  }
}
