import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rasadyar_core/core.dart';

enum RTextFieldVariant { normal, noBorder, password, passwordNoBorder }

class RTextField extends StatefulWidget {
  final TextEditingController controller;
  final String? label;
  final String? hintText;
  final String? initText;
  final bool obscure;
  final bool readonly;
  final bool enabled;
  final int? maxLength;
  final int? minLines;
  final int? maxLines;
  final Widget? suffixIcon;
  final Widget? prefixIcon;
  final BoxConstraints? boxConstraints;
  final RTextFieldVariant variant;
  final bool filled;
  final Color? filledColor;
  final Color? borderColor;
  final bool showCounter;
  final bool isDense;
  final TextInputType? keyboardType;
  final TextStyle? style;
  final TextStyle? hintStyle;
  final TextStyle? labelStyle;
  final TextStyle? errorStyle;
  final EdgeInsets? padding;
  final FormFieldValidator<String>? validator;
  final void Function(String)? onChanged;
  final void Function(String)? onSubmitted;
  final VoidCallback? onTap;
  final List<TextInputFormatter>? inputFormatters;
  final Widget? suffix;
  final FocusNode? focusNode;
  final AutovalidateMode? autoValidateMode;
  final TextAlign? textAlign;
  final TextCapitalization textCapitalization;
  final Color? cursorColor;
  final bool? autocorrect;
  final bool? enableSuggestions;
  final TextInputAction? textInputAction;
  final double? height;
  final Iterable<String>? autofillHints;
  final InputBorder? focusedBorder;

  const RTextField({
    super.key,
    // 🔹 Core
    required this.controller,
    this.label,
    this.hintText,
    this.initText,
    this.onChanged,
    this.onSubmitted,
    this.onTap,
    this.height,

    // 🔸 Behavior
    this.obscure = false,
    this.readonly = false,
    this.enabled = true,
    this.maxLength,
    this.minLines,
    this.maxLines = 1,
    this.textInputAction,
    this.keyboardType,
    this.focusNode,
    this.autofillHints,

    // ⚙️ Input styling
    this.textAlign,
    this.textCapitalization = TextCapitalization.none,
    this.cursorColor,
    this.autocorrect,
    this.enableSuggestions,
    this.style,
    this.hintStyle,
    this.labelStyle,
    this.errorStyle,
    this.focusedBorder,

    // 🎨 Decorations
    this.suffixIcon,
    this.prefixIcon,
    this.suffix,
    this.boxConstraints,

    // 📐 Layout & appearance
    this.borderColor,
    this.filled = false,
    this.filledColor,
    this.padding,
    this.variant = RTextFieldVariant.normal,

    // 📋 Form validation
    this.validator,
    this.autoValidateMode,
    this.inputFormatters,
    this.showCounter = false,
    this.isDense = false,
  });

  @override
  State<RTextField> createState() => _RTextFieldState();

  bool get _isPassword => variant == RTextFieldVariant.password;

  bool get _noBorder => variant == RTextFieldVariant.noBorder;

  bool get _passwordNoBorder => variant == RTextFieldVariant.passwordNoBorder;

  InputBorder get _inputBorder => OutlineInputBorder(
    borderRadius: BorderRadius.circular(8),
    borderSide: _noBorder || _passwordNoBorder
        ? BorderSide.none
        : BorderSide(color: borderColor ?? AppColor.darkGreyLight, width: 1),
  );
}

class _RTextFieldState extends State<RTextField> {
  late bool obscure;
  late TextDirection textDirection;

  Timer? _debounceTimer;

  TextDirection _detectDirection(String text) {
    final isPersian = RegExp(r'[\u0600-\u06FF]').hasMatch(text);
    return isPersian ? TextDirection.rtl : TextDirection.ltr;
  }

  void _debouncedUpdateTextDirection() {
    if (_debounceTimer?.isActive ?? false) _debounceTimer!.cancel();

    _debounceTimer = Timer(const Duration(milliseconds: 300), () {
      final newDirection = _detectDirection(widget.controller.text);
      if (newDirection != textDirection) {
        setState(() {
          textDirection = newDirection;
        });
      }
    });
  }

  @override
  void initState() {
    super.initState();
    if (widget.initText != null) {
      widget.controller.text = widget.initText!;
    }
    obscure = widget.obscure;

    textDirection = _detectDirection(
      widget.controller.text.isNotEmpty ? widget.controller.text : widget.initText ?? 'سلام',
    );

    widget.controller.addListener(_debouncedUpdateTextDirection);
  }

  @override
  void didUpdateWidget(covariant RTextField oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.initText != null && widget.controller.text != widget.initText) {
      widget.controller.text = widget.initText!;
    }
  }

  Widget? _buildSuffixIcon() {
    if (widget._isPassword || widget._passwordNoBorder) {
      return Padding(
        padding: const EdgeInsets.symmetric(horizontal: 8),
        child: GestureDetector(
          onTap: () {
            setState(() {
              obscure = !obscure;
            });
          },
          child: Icon(
            obscure ? CupertinoIcons.eye : CupertinoIcons.eye_slash,
            color: AppColor.darkGreyDarkActive,
          ),
        ),
      );
    }
    return widget.suffixIcon;
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: widget.height,
      child: Padding(
        padding: widget.padding ?? EdgeInsets.zero,
        child: TextFormField(
          controller: widget.controller,
          focusNode: widget.focusNode,
          textAlign: widget.textAlign ?? TextAlign.start,
          readOnly: widget.readonly,
          minLines: widget.minLines,
          maxLines: widget.maxLines,
          onChanged: widget.onChanged,
          validator: widget.validator,
          inputFormatters: widget.inputFormatters,
          enabled: widget.enabled,
          obscureText: obscure,
          onTap: widget.onTap,
          onTapOutside: (_) => FocusScope.of(context).unfocus(),
          onFieldSubmitted: widget.onSubmitted,
          maxLength: widget.maxLength,
          textDirection: textDirection,
          style: widget.style,
          keyboardType: widget.keyboardType,
          autovalidateMode: widget.autoValidateMode ?? AutovalidateMode.disabled,
          cursorColor: widget.cursorColor,
          textCapitalization: widget.textCapitalization,
          autocorrect: widget.autocorrect ?? true,
          enableSuggestions: widget.enableSuggestions ?? true,
          textInputAction: widget.textInputAction,
          autofillHints: widget.autofillHints,
          decoration: InputDecoration(
            contentPadding: const EdgeInsets.symmetric(horizontal: 16),
            errorStyle: widget.errorStyle,
            errorMaxLines: 1,
            isDense: widget.isDense,
            suffix: widget.suffix,
            suffixIcon: _buildSuffixIcon(),
            suffixIconConstraints: widget.boxConstraints,
            prefixIcon: widget.prefixIcon,
            prefixIconConstraints: widget.boxConstraints,
            hintText: widget.hintText,
            labelText: widget.label,
            alignLabelWithHint: true,
            labelStyle: AppFonts.yekan14
                .copyWith(color: AppColor.lightGreyDarkActive)
                .merge(widget.labelStyle),
            filled: widget.filled || widget._noBorder || widget._passwordNoBorder,
            fillColor: widget.filledColor,
            counter: widget.showCounter ? null : const SizedBox(),
            hintStyle: widget.hintStyle,
            enabledBorder: widget._inputBorder,
            focusedBorder: widget.focusedBorder ?? widget._inputBorder,
            border: widget._inputBorder,
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _debounceTimer?.cancel();
    widget.controller.removeListener(_debouncedUpdateTextDirection);
    super.dispose();
  }
}
