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/feature_flags.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';

/// Gutschriften-Editor: ±10 €, max 150 €, Begründung Pflicht.
///
/// Backend-gestützt: „Speichern" feuert `SetDeliveryCredit`, „Entfernen"
/// `RemoveDeliveryCredit` am `TourBloc` → `POST /deliveries/{id}/credit`
/// (append-only, idempotent). Der aktuelle Stand kommt aus dem Tour-Aggregat
/// (`TourDetails.creditOf`).
class DiscountEditor extends StatefulWidget {
  const DiscountEditor({
    super.key,
    required this.deliveryId,
    required this.active,
  });

  final String deliveryId;

  /// Nur bei aktiver Lieferung darf die Gutschrift geändert werden. Bei
  /// abgeschlossener/abgebrochener/pausierter Lieferung bleibt der Editor
  /// sichtbar, aber gesperrt (reine Anzeige des gespeicherten Stands).
  final bool active;

  @override
  State<DiscountEditor> createState() => _DiscountEditorState();
}

class _DiscountEditorState extends State<DiscountEditor> {
  static const int step = 10; // €-Schrittweite (nur die Stepper-Variante)
  static const int max = 150; // € Obergrenze
  static const int maxCents = max * 100;

  /// Betrag in Cent — erlaubt Dezimalbeträge (z. B. 19,99 € = 1999).
  int _amountCents = 0;
  late final TextEditingController _reasonController;
  late final TextEditingController _amountController;

  @override
  void initState() {
    super.initState();
    _reasonController = TextEditingController();

    // Einmalige Übernahme des aktuellen Server-Stands aus dem Bloc — VOR dem
    // Anhängen des Listeners, damit das Setzen des Textes kein `setState`
    // (über den Listener) während des ersten Builds auslöst.
    final state = context.read<TourBloc>().state;
    if (state is TourLoaded) {
      final current = state.details.creditOf(widget.deliveryId);
      if (current != null) {
        _amountCents = current.amountCents;
        _reasonController.text = current.reason;
      }
    }

    // Freitext-Betragsfeld (Dezimal, € mit Cent): vorbelegt; Listener parst die
    // Eingabe in `_amountCents`. Erst NACH dem Vorbelegen anhängen.
    _amountController = TextEditingController(text: _formatCents(_amountCents));
    _amountController.addListener(() {
      setState(() => _amountCents = _parseCents(_amountController.text) ?? 0);
    });

    _reasonController.addListener(() => setState(() {}));
  }

  @override
  void dispose() {
    _reasonController.dispose();
    _amountController.dispose();
    super.dispose();
  }

  /// "19,99" / "19.99" / "20" → Cent. `null` bei leer/ungültig.
  static int? _parseCents(String raw) {
    final t = raw.trim().replaceAll(',', '.');
    if (t.isEmpty) return null;
    final euros = double.tryParse(t);
    if (euros == null) return null;
    return (euros * 100).round();
  }

  /// Cent → Anzeige-String in € (mit Komma). 0 → leer.
  static String _formatCents(int cents) {
    if (cents <= 0) return '';
    if (cents % 100 == 0) return '${cents ~/ 100}';
    return (cents / 100).toStringAsFixed(2).replaceAll('.', ',');
  }

  bool get _canDecrement => widget.active && _amountCents > 0;
  bool get _canIncrement =>
      widget.active && _amountCents + step * 100 <= maxCents;
  bool get _isReasonValid => _reasonController.text.trim().isNotEmpty;

  /// Backend-Regel: >0, ≤150 €. (Beliebige Beträge inkl. Cent.)
  bool get _amountValid => _amountCents > 0 && _amountCents <= maxCents;
  bool get _canSave => widget.active && _amountValid && _isReasonValid;

  // Stepper-Variante (Feature-Flag): bewegt sich in 10-€-Schritten. Das
  // Textfeld ist dann nicht sichtbar, daher kein Controller-Sync nötig.
  void _decrement() {
    if (!_canDecrement) return;
    setState(() => _amountCents = (_amountCents - step * 100).clamp(0, maxCents));
  }

  void _increment() {
    if (!_canIncrement) return;
    setState(() => _amountCents = (_amountCents + step * 100).clamp(0, maxCents));
  }

  String _actorCarId(BuildContext context) {
    final state = context.read<CarSelectBloc>().state;
    if (state is CarSelectComplete) return state.selectedCar.id;
    return '00000000-0000-0000-0000-000000000000';
  }

  void _save() {
    context.read<TourBloc>().add(SetDeliveryCredit(
          deliveryId: widget.deliveryId,
          amountCents: _amountCents,
          reason: _reasonController.text.trim(),
          actorCarId: _actorCarId(context),
        ));
  }

  void _remove() {
    context.read<TourBloc>().add(RemoveDeliveryCredit(
          deliveryId: widget.deliveryId,
          actorCarId: _actorCarId(context),
        ));
    setState(() {
      _amountCents = 0;
      _reasonController.clear();
      _amountController.clear();
    });
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return BlocBuilder<TourBloc, TourState>(
      buildWhen: (a, b) {
        if (a is! TourLoaded || b is! TourLoaded) return true;
        return a.details.creditOf(widget.deliveryId) !=
            b.details.creditOf(widget.deliveryId);
      },
      builder: (context, state) {
        final current = state is TourLoaded
            ? state.details.creditOf(widget.deliveryId)
            : null;
        final isSaved = current != null;
        return Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Betrag',
              style: theme.textTheme.titleSmall?.copyWith(
                fontWeight: FontWeight.w700,
              ),
            ),
            const SizedBox(height: 8),
            // Default: freies Betrags-Textfeld. Hinter dem Feature-Flag
            // `discountAmountStepper` liegt die ursprüngliche +/−-Variante.
            if (FeatureFlags.discountAmountStepper)
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  IconButton.filled(
                    onPressed: _canDecrement ? _decrement : null,
                    icon: const Icon(Icons.remove),
                    style: ButtonStyle(
                      backgroundColor: WidgetStatePropertyAll(
                        _canDecrement ? Colors.red.shade400 : Colors.grey,
                      ),
                    ),
                  ),
                  const SizedBox(width: 16),
                  Column(
                    children: [
                      Text(
                        '${_amountCents ~/ 100} €',
                        style: const TextStyle(
                          fontSize: 22,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      Text(
                        'max. $max € · Schritt $step €',
                        style: TextStyle(
                          fontSize: 11,
                          color: theme.colorScheme.onSurfaceVariant,
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(width: 16),
                  IconButton.filled(
                    onPressed: _canIncrement ? _increment : null,
                    icon: const Icon(Icons.add),
                    style: ButtonStyle(
                      backgroundColor: WidgetStatePropertyAll(
                        _canIncrement ? Colors.green.shade600 : Colors.grey,
                      ),
                    ),
                  ),
                ],
              )
            else
              TextField(
                controller: _amountController,
                enabled: widget.active,
                keyboardType:
                    const TextInputType.numberWithOptions(decimal: true),
                decoration: InputDecoration(
                  border: const OutlineInputBorder(),
                  isDense: true,
                  prefixText: '€ ',
                  hintText: '0,00',
                  helperText: 'max. $max € · Cent erlaubt (z. B. 19,99)',
                  // Fehlertext nur bei nicht-leerer, ungültiger Eingabe.
                  errorText: (widget.active &&
                          _amountController.text.trim().isNotEmpty &&
                          !_amountValid)
                      ? 'Betrag muss > 0 und ≤ $max € sein'
                      : null,
                ),
              ),
            const SizedBox(height: 16),
            Text(
              'Begründung (Pflicht)',
              style: theme.textTheme.titleSmall?.copyWith(
                fontWeight: FontWeight.w700,
              ),
            ),
            const SizedBox(height: 6),
            TextField(
              controller: _reasonController,
              enabled: widget.active,
              minLines: 2,
              maxLines: 4,
              decoration: const InputDecoration(
                border: OutlineInputBorder(),
                hintText: 'z. B. Transportschaden, Verzögerung …',
              ),
            ),
            const SizedBox(height: 12),
            if (!widget.active) ...[
              _LockedHint(
                text: isSaved
                    ? 'Lieferung abgeschlossen — Gutschrift nicht mehr änderbar.'
                    : 'Gutschrift nur bei aktiver Lieferung änderbar.',
              ),
              const SizedBox(height: 12),
            ],
            if (isSaved && widget.active) ...[
              Container(
                padding: const EdgeInsets.symmetric(
                  horizontal: 8,
                  vertical: 4,
                ),
                decoration: BoxDecoration(
                  color: Colors.green.withValues(alpha: 0.15),
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Icon(
                      Icons.check_circle_outline,
                      size: 14,
                      color: Colors.green.shade700,
                    ),
                    const SizedBox(width: 4),
                    Text(
                      'Gespeichert',
                      style: TextStyle(
                        fontSize: 12,
                        color: Colors.green.shade800,
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(height: 8),
            ],
            // Buttons in einem Wrap: brechen auf schmalen Cards um, statt
            // (wie zuvor in einer Row mit Spacer) rechts überzulaufen. Volle
            // Breite, damit WrapAlignment.end rechtsbündig wirkt.
            SizedBox(
              width: double.infinity,
              child: Wrap(
                alignment: WrapAlignment.end,
                spacing: 8,
                runSpacing: 8,
                children: [
                  if (isSaved)
                    TextButton.icon(
                      onPressed: widget.active ? _remove : null,
                      icon: const Icon(Icons.delete_outline),
                      label: const Text('Entfernen'),
                    ),
                  FilledButton.icon(
                    onPressed: _canSave ? _save : null,
                    icon: const Icon(Icons.save),
                    label: Text(isSaved ? 'Aktualisieren' : 'Speichern'),
                  ),
                ],
              ),
            ),
          ],
        );
      },
    );
  }
}

/// Kleiner Hinweis-Balken, wenn eine Aktion gesperrt ist (Lieferung nicht
/// aktiv). Bewusst dezent — der Editor bleibt als Anzeige sichtbar.
class _LockedHint extends StatelessWidget {
  const _LockedHint({required this.text});
  final String text;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
      decoration: BoxDecoration(
        color: theme.colorScheme.surfaceContainerHighest,
        borderRadius: BorderRadius.circular(8),
      ),
      child: Row(
        children: [
          Icon(Icons.lock_outline,
              size: 16, color: theme.colorScheme.onSurfaceVariant),
          const SizedBox(width: 8),
          Expanded(
            child: Text(
              text,
              style: theme.textTheme.bodySmall?.copyWith(
                color: theme.colorScheme.onSurfaceVariant,
              ),
            ),
          ),
        ],
      ),
    );
  }
}
