import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:frontend_eccp_mobile/app/core/constants/constants.dart';

class AppTextField extends StatefulWidget {
  const AppTextField({
    required this.title,
    required this.hint,
    required this.password,
    required this.controller,
    required this.isValid,
    required this.informationValid,
    super.key,
    this.maxLine = 1,
    this.maxLength,
    this.showTitle = true,
    this.isEnabled = true,
    this.keyboardType,
    this.radius = AppSizes.s16,
    this.phoneText,
    this.inputFormatters,
    this.width,
    this.isRequired = false,
    this.contentPaddingVertical = AppSizes.s12,
    this.prefixIcon,
    this.showPrefixIcon = false,
    this.prefixIconColor,
    this.prefixIconSize = AppIconSizes.md,
    this.prefixIconPadding = AppSizes.s12,
    this.isDense = false,
    this.minHeight,
    this.onChanged,
    this.iconRight,
    this.bgColor = const Color(0xFFF9FAFB),
    this.hintColor = const Color(0x800A0A0A),
    this.titleColor = const Color(0xFF364153),
    this.borderColor = const Color(0xFFE5E7EB),
  });

  final String title;
  final String hint;
  final bool password;
  final TextEditingController controller;

  final int maxLine;
  final int? maxLength;
  final double contentPaddingVertical;

  final bool isEnabled;
  final bool showTitle;
  final bool isRequired;
  final bool isValid;

  final String informationValid;
  final double radius;
  final double? width;

  final String? phoneText;
  final TextInputType? keyboardType;
  final List<TextInputFormatter>? inputFormatters;

  final Color bgColor;
  final Color titleColor;
  final Color hintColor;
  final Color borderColor;

  final Widget? prefixIcon;
  final bool showPrefixIcon;
  final Color? prefixIconColor;
  final double prefixIconSize;
  final double prefixIconPadding;

  final bool isDense;
  final double? minHeight;

  final Widget? iconRight;
  final void Function(String)? onChanged;

  @override
  State<AppTextField> createState() => _AppTextFieldState();
}

class _AppTextFieldState extends State<AppTextField> {
  bool _showPass = true;
  final FocusNode _focusNode = FocusNode();
  final GlobalKey _fieldKey = GlobalKey();
  OverlayEntry? _overlayEntry;

  void _scrollIntoView() {
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      if (!mounted) return;
      await Scrollable.ensureVisible(
        context,
        alignment: 0.25,
        duration: const Duration(milliseconds: 200),
        curve: Curves.easeOut,
      );
    });
  }

  @override
  void initState() {
    super.initState();

    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        _addTapOutsideOverlay();
        _scrollIntoView();
      } else {
        _removeTapOutsideOverlay();
      }
    });
  }

  void _addTapOutsideOverlay() {
    _overlayEntry = OverlayEntry(
      builder: (_) => Positioned.fill(
        child: GestureDetector(
          behavior: HitTestBehavior.translucent,
          onTap: _focusNode.unfocus,
        ),
      ),
    );
    Overlay.of(context).insert(_overlayEntry!);
  }

  void _removeTapOutsideOverlay() {
    _overlayEntry?.remove();
    _overlayEntry = null;
  }

  @override
  void dispose() {
    _removeTapOutsideOverlay();
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      key: _fieldKey,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (widget.showTitle)
          Padding(
            padding: AppPadding.b8,
            child: Row(
              children: [
                Text(
                  widget.title,
                  style: AppTextStyles.label.copyWith(
                    color: widget.titleColor,
                    fontWeight: FontWeight.w400,
                  ),
                ),
                if (widget.isRequired)
                  Text(
                    ' *',
                    style: AppTextStyles.body.copyWith(
                      color: AppColors.primary500,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
              ],
            ),
          ),
        Container(
          width: widget.width,
          constraints: widget.minHeight != null
              ? BoxConstraints(minHeight: widget.minHeight!)
              : null,
          decoration: BoxDecoration(
            color: widget.bgColor,
            borderRadius: BorderRadius.circular(widget.radius),
            border: Border.all(
              color: widget.isValid ? widget.borderColor : AppColors.primary500,
              width: 1.2,
            ),
          ),
          child: Row(
            children: [
              if (widget.showPrefixIcon && widget.prefixIcon != null)
                Padding(
                  padding: EdgeInsets.only(
                    left: widget.prefixIconPadding,
                    right: AppSizes.s12,
                  ),
                  child: IconTheme(
                    data: IconThemeData(
                      size: widget.prefixIconSize,
                      color: widget.prefixIconColor ?? widget.hintColor,
                    ),
                    child: widget.prefixIcon!,
                  ),
                )
              else
                AppSpacing.w16,
              if (widget.phoneText != null)
                Padding(
                  padding: AppPadding.r8,
                  child: Text(
                    widget.phoneText!,
                    style: AppTextStyles.body.copyWith(
                      color: widget.hintColor,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ),
              Expanded(
                child: TextFormField(
                  controller: widget.controller,
                  obscureText: widget.password && _showPass,
                  maxLines: widget.maxLine,
                  enabled: widget.isEnabled,
                  maxLength: widget.maxLength,
                  keyboardType: widget.keyboardType,
                  inputFormatters: widget.inputFormatters,
                  style: AppTextStyles.body.copyWith(
                    fontSize: widget.isDense ? 13 : 14,
                  ),
                  decoration: InputDecoration(
                    isDense: widget.isDense,
                    hintText: widget.hint,
                    hintStyle: AppTextStyles.body.copyWith(
                      fontSize: widget.isDense ? 12 : 13,
                      color: widget.hintColor,
                    ),
                    contentPadding: EdgeInsets.symmetric(
                      vertical: widget.isDense
                          ? AppSizes.s8
                          : widget.contentPaddingVertical,
                    ),
                    border: InputBorder.none,
                    counterText: '',
                  ),
                  onChanged: widget.onChanged,
                ),
              ),
              if (widget.iconRight != null)
                Padding(
                  padding: AppPadding.r12,
                  child: widget.iconRight,
                ),
              if (widget.password)
                Padding(
                  padding: AppPadding.r12,
                  child: GestureDetector(
                    onTap: () => setState(() => _showPass = !_showPass),
                    child: Icon(
                      _showPass
                          ? Icons.visibility_off_rounded
                          : Icons.visibility_rounded,
                      size: AppIconSizes.md,
                      color: AppColors.neutral400,
                    ),
                  ),
                ),
            ],
          ),
        ),
        if (!widget.isValid)
          Padding(
            padding: const EdgeInsets.only(
              top: AppSizes.s8,
              left: AppSizes.s12,
            ),
            child: Text(
              widget.informationValid,
              style: AppTextStyles.small.copyWith(
                color: AppColors.primary500,
              ),
            ),
          ),
      ],
    );
  }
}
