/// Date Picker Input Field
///
/// Input field that opens a date picker dialog when tapped.
/// Displays dates in Vietnamese format (dd/MM/yyyy).
library;

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../../core/utils/formatters.dart';
import '../../core/utils/validators.dart';
import '../../core/constants/ui_constants.dart';

/// Date picker input field
class DatePickerField extends StatefulWidget {
  final TextEditingController? controller;
  final String? labelText;
  final String? hintText;
  final DateTime? initialDate;
  final DateTime? firstDate;
  final DateTime? lastDate;
  final ValueChanged<DateTime>? onDateSelected;
  final FormFieldValidator<String>? validator;
  final bool enabled;
  final bool required;
  final Widget? prefixIcon;
  final Widget? suffixIcon;
  final InputDecoration? decoration;

  const DatePickerField({
    super.key,
    this.controller,
    this.labelText,
    this.hintText,
    this.initialDate,
    this.firstDate,
    this.lastDate,
    this.onDateSelected,
    this.validator,
    this.enabled = true,
    this.required = true,
    this.prefixIcon,
    this.suffixIcon,
    this.decoration,
  });

  @override
  State<DatePickerField> createState() => _DatePickerFieldState();
}

class _DatePickerFieldState extends State<DatePickerField> {
  late TextEditingController _controller;
  bool _isControllerInternal = false;
  DateTime? _selectedDate;

  @override
  void initState() {
    super.initState();
    _selectedDate = widget.initialDate;

    if (widget.controller == null) {
      _controller = TextEditingController(
        text: _selectedDate != null
            ? DateFormatter.formatDate(_selectedDate!)
            : '',
      );
      _isControllerInternal = true;
    } else {
      _controller = widget.controller!;
    }
  }

  @override
  void dispose() {
    if (_isControllerInternal) {
      _controller.dispose();
    }
    super.dispose();
  }

  Future<void> _selectDate(BuildContext context) async {
    if (!widget.enabled) return;

    final DateTime? picked = await showDatePicker(
      context: context,
      initialDate: _selectedDate ?? DateTime.now(),
      firstDate: widget.firstDate ?? DateTime(1900),
      lastDate: widget.lastDate ?? DateTime(2100),
      locale: const Locale('vi', 'VN'),
      builder: (context, child) {
        return Theme(
          data: Theme.of(context).copyWith(
            colorScheme: ColorScheme.light(
              primary: Theme.of(context).primaryColor,
            ),
          ),
          child: child!,
        );
      },
    );

    if (picked != null && picked != _selectedDate) {
      setState(() {
        _selectedDate = picked;
        _controller.text = DateFormatter.formatDate(picked);
      });
      widget.onDateSelected?.call(picked);
    }
  }

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      controller: _controller,
      readOnly: true,
      enabled: widget.enabled,
      onTap: () => _selectDate(context),
      decoration:
          widget.decoration ??
          InputDecoration(
            labelText: widget.labelText ?? 'Ngày',
            hintText: widget.hintText ?? 'dd/MM/yyyy',
            prefixIcon: widget.prefixIcon ?? const FaIcon(FontAwesomeIcons.calendar, size: 20),
            suffixIcon: widget.suffixIcon,
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
            ),
            contentPadding: InputFieldSpecs.contentPadding,
          ),
      validator: widget.validator ?? (widget.required ? Validators.date : null),
    );
  }
}

/// Date range picker field
class DateRangePickerField extends StatefulWidget {
  final String? labelText;
  final String? hintText;
  final DateTimeRange? initialRange;
  final DateTime? firstDate;
  final DateTime? lastDate;
  final ValueChanged<DateTimeRange>? onRangeSelected;
  final bool enabled;
  final Widget? prefixIcon;

  const DateRangePickerField({
    super.key,
    this.labelText,
    this.hintText,
    this.initialRange,
    this.firstDate,
    this.lastDate,
    this.onRangeSelected,
    this.enabled = true,
    this.prefixIcon,
  });

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

class _DateRangePickerFieldState extends State<DateRangePickerField> {
  late TextEditingController _controller;
  DateTimeRange? _selectedRange;

  @override
  void initState() {
    super.initState();
    _selectedRange = widget.initialRange;
    _controller = TextEditingController(
      text: _selectedRange != null
          ? '${DateFormatter.formatDate(_selectedRange!.start)} - ${DateFormatter.formatDate(_selectedRange!.end)}'
          : '',
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  Future<void> _selectDateRange(BuildContext context) async {
    if (!widget.enabled) return;

    final DateTimeRange? picked = await showDateRangePicker(
      context: context,
      initialDateRange: _selectedRange,
      firstDate: widget.firstDate ?? DateTime(1900),
      lastDate: widget.lastDate ?? DateTime(2100),
      locale: const Locale('vi', 'VN'),
      builder: (context, child) {
        return Theme(
          data: Theme.of(context).copyWith(
            colorScheme: ColorScheme.light(
              primary: Theme.of(context).primaryColor,
            ),
          ),
          child: child!,
        );
      },
    );

    if (picked != null && picked != _selectedRange) {
      setState(() {
        _selectedRange = picked;
        _controller.text =
            '${DateFormatter.formatDate(picked.start)} - ${DateFormatter.formatDate(picked.end)}';
      });
      widget.onRangeSelected?.call(picked);
    }
  }

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      controller: _controller,
      readOnly: true,
      enabled: widget.enabled,
      onTap: () => _selectDateRange(context),
      decoration: InputDecoration(
        labelText: widget.labelText ?? 'Khoảng thời gian',
        hintText: widget.hintText ?? 'Chọn khoảng thời gian',
        prefixIcon: widget.prefixIcon ?? const FaIcon(FontAwesomeIcons.calendarDays, size: 20),
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
        ),
        contentPadding: InputFieldSpecs.contentPadding,
      ),
    );
  }
}

/// Date of birth picker field
class DateOfBirthField extends StatelessWidget {
  final TextEditingController? controller;
  final String? labelText;
  final String? hintText;
  final ValueChanged<DateTime>? onDateSelected;
  final FormFieldValidator<String>? validator;
  final bool enabled;
  final int minAge;

  const DateOfBirthField({
    super.key,
    this.controller,
    this.labelText,
    this.hintText,
    this.onDateSelected,
    this.validator,
    this.enabled = true,
    this.minAge = 18,
  });

  @override
  Widget build(BuildContext context) {
    final now = DateTime.now();
    final maxDate = DateTime(now.year - minAge, now.month, now.day);
    final minDate = DateTime(now.year - 100, now.month, now.day);

    return DatePickerField(
      controller: controller,
      labelText: labelText ?? 'Ngày sinh',
      hintText: hintText ?? 'dd/MM/yyyy',
      initialDate: maxDate,
      firstDate: minDate,
      lastDate: maxDate,
      onDateSelected: onDateSelected,
      validator: validator ?? (value) => Validators.age(value, minAge: minAge),
      enabled: enabled,
      prefixIcon: const FaIcon(FontAwesomeIcons.cakeCandles, size: 20),
    );
  }
}

/// Time picker field
class TimePickerField extends StatefulWidget {
  final TextEditingController? controller;
  final String? labelText;
  final String? hintText;
  final TimeOfDay? initialTime;
  final ValueChanged<TimeOfDay>? onTimeSelected;
  final bool enabled;
  final Widget? prefixIcon;

  const TimePickerField({
    super.key,
    this.controller,
    this.labelText,
    this.hintText,
    this.initialTime,
    this.onTimeSelected,
    this.enabled = true,
    this.prefixIcon,
  });

  @override
  State<TimePickerField> createState() => _TimePickerFieldState();
}

class _TimePickerFieldState extends State<TimePickerField> {
  late TextEditingController _controller;
  bool _isControllerInternal = false;
  TimeOfDay? _selectedTime;

  @override
  void initState() {
    super.initState();
    _selectedTime = widget.initialTime;

    if (widget.controller == null) {
      _controller = TextEditingController(
        text: _selectedTime != null
            ? '${_selectedTime!.hour.toString().padLeft(2, '0')}:${_selectedTime!.minute.toString().padLeft(2, '0')}'
            : '',
      );
      _isControllerInternal = true;
    } else {
      _controller = widget.controller!;
    }
  }

  @override
  void dispose() {
    if (_isControllerInternal) {
      _controller.dispose();
    }
    super.dispose();
  }

  Future<void> _selectTime(BuildContext context) async {
    if (!widget.enabled) return;

    final TimeOfDay? picked = await showTimePicker(
      context: context,
      initialTime: _selectedTime ?? TimeOfDay.now(),
      builder: (context, child) {
        return Theme(
          data: Theme.of(context).copyWith(
            colorScheme: ColorScheme.light(
              primary: Theme.of(context).primaryColor,
            ),
          ),
          child: child!,
        );
      },
    );

    if (picked != null && picked != _selectedTime) {
      setState(() {
        _selectedTime = picked;
        _controller.text =
            '${picked.hour.toString().padLeft(2, '0')}:${picked.minute.toString().padLeft(2, '0')}';
      });
      widget.onTimeSelected?.call(picked);
    }
  }

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      controller: _controller,
      readOnly: true,
      enabled: widget.enabled,
      onTap: () => _selectTime(context),
      decoration: InputDecoration(
        labelText: widget.labelText ?? 'Thời gian',
        hintText: widget.hintText ?? 'HH:mm',
        prefixIcon: widget.prefixIcon ?? const FaIcon(FontAwesomeIcons.clock, size: 20),
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
        ),
        contentPadding: InputFieldSpecs.contentPadding,
      ),
    );
  }
}
