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

import 'date_range_picker_dialog.dart';

/// Single UI control for filter **from** / **to** dates.
///
/// Writes [dd-MM-yyyy] to [startController] and [endController] (same as [ThemedDateField]).
/// Does not change API keys or request shape — only how the user picks dates.
class DateRangePickerField extends StatefulWidget {
  const DateRangePickerField({
    super.key,
    required this.startController,
    required this.endController,
    this.hintText,
    this.labelText,
    this.txtwidth,
    this.txtheight = 35,
    this.firstDate,
    this.lastDate,
    this.onRangeSelected,
    this.rangeValidator,
    this.showLabelAboveField = false,
    this.labelStyle,
    this.useFormField = true,
  });

  final TextEditingController startController;
  final TextEditingController endController;

  /// Shown when no range is selected.
  final String? hintText;

  /// Optional label above the field (e.g. `Date range *`).
  final String? labelText;
  final double? txtwidth;
  final double? txtheight;
  final DateTime? firstDate;
  final DateTime? lastDate;

  /// Called after user confirms a range (same moment controllers are updated).
  final void Function(DateTimeRange range)? onRangeSelected;

  /// When non-null and [useFormField] is true, wrapped in [FormField] for [FormState.validate].
  final String? Function(
    TextEditingController start,
    TextEditingController end,
  )? rangeValidator;

  final bool showLabelAboveField;
  final TextStyle? labelStyle;

  /// If false, no [FormField] — use when this widget is not under a [Form].
  final bool useFormField;

  static final DateFormat storageFormat = DateFormat('dd-MM-yyyy');
  static final DateFormat displayFormat = DateFormat('dd MMM yyyy');

  /// Matches previous end-date-only validation: if start is set, end is required and not before start.
  static String? defaultFilterValidator(
    TextEditingController start,
    TextEditingController end,
  ) {
    final s = start.text.trim();
    final e = end.text.trim();
    if (s.isNotEmpty) {
      try {
        storageFormat.parse(s);
        if (e.isEmpty) return 'End Date is required';
        final sd = storageFormat.parse(s);
        final ed = storageFormat.parse(e);
        if (ed.isBefore(sd)) {
          return 'End Date cannot be earlier than Start Date';
        }
      } catch (_) {
        return 'Invalid date';
      }
    }
    return null;
  }

  @override
  State<DateRangePickerField> createState() => _DateRangePickerFieldState();
}

class _DateRangePickerFieldState extends State<DateRangePickerField> {
  void _onTextChanged() {
    if (mounted) setState(() {});
  }

  @override
  void initState() {
    super.initState();
    widget.startController.addListener(_onTextChanged);
    widget.endController.addListener(_onTextChanged);
  }

  @override
  void dispose() {
    widget.startController.removeListener(_onTextChanged);
    widget.endController.removeListener(_onTextChanged);
    super.dispose();
  }

  String _displayText() {
    final s = widget.startController.text.trim();
    final e = widget.endController.text.trim();
    if (s.isEmpty && e.isEmpty) {
      return widget.hintText ?? 'Select date range';
    }
    if (s.isNotEmpty && e.isNotEmpty) {
      try {
        final sd = DateRangePickerField.storageFormat.parse(s);
        final ed = DateRangePickerField.storageFormat.parse(e);
        return '${DateRangePickerField.displayFormat.format(sd)} – ${DateRangePickerField.displayFormat.format(ed)}';
      } catch (_) {
        return '$s – $e';
      }
    }
    if (s.isNotEmpty) return s;
    return e;
  }

  Future<void> _pick(BuildContext context, FormFieldState<String>? field) async {
    final first = widget.firstDate ?? DateTime(2000);
    final last = widget.lastDate ?? DateTime(2100);

    DateTimeRange? initial;
    try {
      final s = widget.startController.text.trim();
      final e = widget.endController.text.trim();
      if (s.isNotEmpty && e.isNotEmpty) {
        initial = DateTimeRange(
          start: DateRangePickerField.storageFormat.parse(s),
          end: DateRangePickerField.storageFormat.parse(e),
        );
      } else if (s.isNotEmpty) {
        final d = DateRangePickerField.storageFormat.parse(s);
        initial = DateTimeRange(start: d, end: d);
      }
    } catch (_) {}

    final picked = await showCompactDateRangePicker(
      context: context,
      firstDate: first,
      lastDate: last,
      initialRange: initial,
    );

    if (picked != null) {
      widget.startController.text =
          DateRangePickerField.storageFormat.format(picked.start);
      widget.endController.text =
          DateRangePickerField.storageFormat.format(picked.end);
      field?.didChange('range');
      widget.onRangeSelected?.call(picked);
      setState(() {});
    }
  }

  static const _border = Color(0xFFE2E8F0);
  static const _error = Color(0xFFD83731);

  Widget _tappableField({
    required bool hasError,
    required VoidCallback onTap,
  }) {
    final empty = widget.startController.text.trim().isEmpty &&
        widget.endController.text.trim().isEmpty;

    return InkWell(
      onTap: onTap,
      borderRadius: BorderRadius.circular(10),
      child: Container(
        width: widget.txtwidth ?? MediaQuery.sizeOf(context).width,
        height: widget.txtheight,
        padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 15),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(10),
          border: Border.all(
            color: hasError ? _error : _border,
            width: 1,
          ),
        ),
        child: Row(
          children: [
            Expanded(
              child: Text(
                _displayText(),
                style: TextStyle(
                  fontSize: 11,
                  color: hasError
                      ? _error
                      : empty
                          ? const Color(0xFF64748B)
                          : Colors.black,
                ),
                overflow: TextOverflow.ellipsis,
              ),
            ),
            const Icon(Icons.date_range, size: 16, color: Color(0xFF5A6C7D)),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final labelStyle = widget.labelStyle ??
        const TextStyle(fontSize: 12, fontWeight: FontWeight.w600);

    Widget content({required bool hasError, FormFieldState<String>? field}) {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: [
          if (widget.showLabelAboveField && widget.labelText != null) ...[
            Text(widget.labelText!, style: labelStyle),
            const SizedBox(height: 5),
          ],
          _tappableField(
            hasError: hasError,
            onTap: () => _pick(context, field),
          ),
          if (hasError && field != null && (field.errorText ?? '').isNotEmpty)
            Padding(
              padding: const EdgeInsets.only(top: 5, left: 5),
              child: Text(
                field.errorText ?? '',
                style: const TextStyle(color: _error, fontSize: 10),
              ),
            ),
        ],
      );
    }

    if (!widget.useFormField || widget.rangeValidator == null) {
      return content(hasError: false, field: null);
    }

    return FormField<String>(
      initialValue: '',
      validator: (_) => widget.rangeValidator!(
        widget.startController,
        widget.endController,
      ),
      builder: (field) {
        final hasError = field.hasError;
        return content(hasError: hasError, field: field);
      },
    );
  }
}
