import 'package:flutter/material.dart';

/// Ergebnis des Reason-Pickers: getrimmter Grund + optionale Menge.
class ReasonPickerResult {
  const ReasonPickerResult({required this.reason, this.quantity});

  final String reason;

  /// Gewählte Menge (1…maxQuantity). `null`, wenn das Sheet **ohne**
  /// Mengen-Auswahl geöffnet wurde (`maxQuantity == null`, z. B. bei
  /// Lieferungs-Gründen wie Pausieren/Abbrechen) — dann gilt „ganze Zeile".
  final int? quantity;
}

/// Bottom-Sheet zur Auswahl einer Begründung. Zeigt eine Radio-Liste der
/// vordefinierten Gründe + den Sonderfall „Anderer Grund", der ein
/// Freitext-Feld einblendet.
///
/// Optional — wenn [maxQuantity] gesetzt und > 1 — zusätzlich eine
/// **Mengen-Auswahl** (Stepper 1…maxQuantity, Vorbelegung = maxQuantity) für
/// die Teilmengen-Löschung/-Gutschrift.
///
/// Rückgabe: [ReasonPickerResult] oder `null` bei Abbruch.
///
/// Validierung:
/// * Vordefinierter Grund → direkt OK
/// * „Anderer Grund" mit leerem Freitext → Bestätigen disabled
Future<ReasonPickerResult?> showReasonPickerSheet({
  required BuildContext context,
  required String title,
  required List<String> presets,
  String confirmLabel = 'Übernehmen',
  int? maxQuantity,
}) {
  return showModalBottomSheet<ReasonPickerResult>(
    context: context,
    isScrollControlled: true,
    showDragHandle: true,
    builder: (ctx) => _ReasonPickerSheet(
      title: title,
      presets: presets,
      confirmLabel: confirmLabel,
      maxQuantity: maxQuantity,
    ),
  );
}

class _ReasonPickerSheet extends StatefulWidget {
  const _ReasonPickerSheet({
    required this.title,
    required this.presets,
    required this.confirmLabel,
    required this.maxQuantity,
  });

  final String title;
  final List<String> presets;
  final String confirmLabel;
  final int? maxQuantity;

  @override
  State<_ReasonPickerSheet> createState() => _ReasonPickerSheetState();
}

/// Sentinel-Wert für die „Anderer Grund"-Option. Eigene Klasse, damit der
/// Vergleich nicht mit echten Reason-Strings kollidieren kann (z. B.
/// jemand definiert tatsächlich „Anderer Grund" als Standard-Reason).
const String _otherSentinel = ' other';

class _ReasonPickerSheetState extends State<_ReasonPickerSheet> {
  String? _selected;
  final _customController = TextEditingController();
  final _customFocus = FocusNode();
  late int _qty;

  @override
  void initState() {
    super.initState();
    // Vorbelegung: ganze Restmenge.
    _qty = widget.maxQuantity ?? 1;
  }

  @override
  void dispose() {
    _customController.dispose();
    _customFocus.dispose();
    super.dispose();
  }

  bool get _isOther => _selected == _otherSentinel;

  /// Mengen-Stepper nur zeigen, wenn überhaupt eine Auswahl Sinn ergibt.
  bool get _showQuantity => (widget.maxQuantity ?? 0) > 1;

  String? get _effectiveReason {
    if (_selected == null) return null;
    if (_isOther) {
      final v = _customController.text.trim();
      return v.isEmpty ? null : v;
    }
    return _selected;
  }

  void _onConfirm() {
    final reason = _effectiveReason;
    if (reason == null) return;
    Navigator.of(context).pop(
      ReasonPickerResult(
        reason: reason,
        // Ohne Mengen-Kontext (maxQuantity == null) → null = ganze Zeile.
        quantity: widget.maxQuantity == null ? null : _qty,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return SafeArea(
      child: Padding(
        padding: EdgeInsets.only(
          left: 16,
          right: 16,
          top: 8,
          // Tastatur-Höhe rein-clipping, damit das Freitext-Feld sichtbar bleibt.
          bottom: MediaQuery.of(context).viewInsets.bottom + 16,
        ),
        // Scrollbar, damit Mengen-Stepper + Gründe + Freitext bei wenig Platz
        // (offene Tastatur) nicht overflowen.
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Padding(
                padding: const EdgeInsets.only(bottom: 8),
                child: Text(
                  widget.title,
                  style: Theme.of(context).textTheme.titleMedium?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                ),
              ),
              if (_showQuantity) ...[
                Text(
                  'Wie viele entfernen? (1–${widget.maxQuantity})',
                  style: theme.textTheme.bodySmall,
                ),
                const SizedBox(height: 4),
                Row(
                  children: [
                    IconButton.filled(
                      onPressed:
                          _qty > 1 ? () => setState(() => _qty -= 1) : null,
                      icon: const Icon(Icons.remove),
                    ),
                    Expanded(
                      child: Text(
                        '$_qty',
                        textAlign: TextAlign.center,
                        style: theme.textTheme.titleLarge?.copyWith(
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                    IconButton.filled(
                      onPressed: _qty < widget.maxQuantity!
                          ? () => setState(() => _qty += 1)
                          : null,
                      icon: const Icon(Icons.add),
                    ),
                  ],
                ),
                const Divider(height: 24),
              ],
              for (final preset in widget.presets)
                RadioListTile<String>(
                  value: preset,
                  groupValue: _selected,
                  onChanged: (v) => setState(() => _selected = v),
                  title: Text(preset),
                  contentPadding: EdgeInsets.zero,
                  dense: true,
                ),
              RadioListTile<String>(
                value: _otherSentinel,
                groupValue: _selected,
                onChanged: (v) {
                  setState(() => _selected = v);
                  WidgetsBinding.instance.addPostFrameCallback((_) {
                    _customFocus.requestFocus();
                  });
                },
                title: const Text('Anderer Grund'),
                contentPadding: EdgeInsets.zero,
                dense: true,
              ),
              if (_isOther)
                Padding(
                  padding: const EdgeInsets.only(top: 8, bottom: 8),
                  child: TextField(
                    controller: _customController,
                    focusNode: _customFocus,
                    autocorrect: false,
                    decoration: const InputDecoration(
                      border: OutlineInputBorder(),
                      hintText: 'Begründung',
                    ),
                    onChanged: (_) => setState(() {}),
                    textInputAction: TextInputAction.done,
                    onSubmitted: (_) => _onConfirm(),
                  ),
                ),
              const SizedBox(height: 8),
              FilledButton(
                onPressed: _effectiveReason == null ? null : _onConfirm,
                child: Text(widget.confirmLabel),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
