import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/utils/extension.dart';
import 'package:didvan/views/widgets/animated_visibility.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class DidvanTextField extends StatefulWidget {
  final void Function(String value)? onChanged;
  final void Function(String value)? onSubmitted;
  final bool enabled;
  final bool autoFocus;
  final TextAlign? textAlign;
  final String? title;
  final String? hintText;
  final dynamic initialValue;
  final bool obsecureText;
  final bool acceptSpace;
  final String? Function(String value)? validator;
  final TextInputType? textInputType;
  final TextInputAction? textInputAction;
  final bool disableBorders;
  final bool isSmall;
  final int? maxLine;
  final int? minLine;
  final int? maxLength;
  final bool hasHeight;
  final bool showLen;
  final String? prefixSvgPath;
  final String? suffixSvgPath;

  const DidvanTextField({
    Key? key,
    this.onChanged,
    this.enabled = true,
    this.title,
    this.hintText,
    this.initialValue,
    this.validator,
    this.textInputType,
    this.textInputAction,
    this.textAlign,
    this.obsecureText = false,
    this.autoFocus = false,
    this.onSubmitted,
    this.acceptSpace = true,
    this.disableBorders = false,
    this.isSmall = false,
    this.maxLine,
    this.minLine,
    this.maxLength,
    this.hasHeight = true,
    this.showLen = false,
    this.prefixSvgPath,
    this.suffixSvgPath,
  }) : super(key: key);

  @override
  State<DidvanTextField> createState() => _DidvanTextFieldState();
}

class _DidvanTextFieldState extends State<DidvanTextField> {
  final FocusNode _focusNode = FocusNode();
  final TextEditingController _controller = TextEditingController();

  bool _hideContent = false;
  String? _error;

  @override
  void initState() {
    if (widget.initialValue != null) {
      _controller.text = widget.initialValue;
    }
    _hideContent = widget.obsecureText;
    _focusNode.addListener(() {
      // setState(() {});
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (widget.title != null)
          Padding(
            padding: const EdgeInsets.only(right: 12),
            child: DidvanText(
              widget.title!,
              color: _titleColor(),
            ),
          ),
        if (widget.title != null) const SizedBox(height: 8),
        Container(
          height: widget.hasHeight ? 48 : null,
          padding: const EdgeInsets.symmetric(horizontal: 12).copyWith(
            left:
                (widget.obsecureText || widget.suffixSvgPath != null) ? 0 : 12,
            right: (widget.prefixSvgPath != null) ? 0 : 12,
          ),
          decoration: BoxDecoration(
            color: _fillColor(),
            borderRadius: BorderRadius.circular(16),
            border: widget.disableBorders
                ? null
                : Border.all(color: _borderColor()),
          ),
          child: ValueListenableBuilder(
              valueListenable: _controller,
              builder: (context, val, _) {
                final isEnglish = val.text.startsWithEnglish();

                return Directionality(
                    textDirection: TextDirection.rtl,
                    child: Center(
                      child: TextFormField(
                        autofocus: widget.autoFocus,
                        obscureText: _hideContent,
                        textAlign: widget.textAlign ??
                            (isEnglish ? TextAlign.left : TextAlign.right),
                        keyboardType: widget.textInputType,
                        textInputAction: widget.textInputAction,
                        focusNode: _focusNode,
                        controller: _controller,
                        onFieldSubmitted: widget.onSubmitted,
                        onChanged: _onChanged,
                        validator: _validator,
                        maxLines: _hideContent ? 1 : widget.maxLine,
                        minLines: widget.minLine,
                        maxLength: widget.maxLength,
                        obscuringCharacter: '*',
                        buildCounter: widget.showLen
                            ? null
                            : (context,
                                    {required currentLength,
                                    required isFocused,
                                    required maxLength}) =>
                                const SizedBox(),
                        style: (widget.isSmall
                                ? Theme.of(context).textTheme.bodySmall!
                                : Theme.of(context).textTheme.bodyMedium!)
                            .copyWith(
                                fontFamily:
                                    DesignConfig.fontFamily.padRight(3)),
                        decoration: InputDecoration(
                          prefixIcon: _prefixBuilder(),
                          suffixIcon: _suffixBuilder(),
                          prefixIconConstraints: const BoxConstraints(
                              minWidth: 32, minHeight: 32, maxHeight: 48),
                          suffixIconConstraints: const BoxConstraints(
                              minWidth: 32,
                              minHeight: 32,
                              maxHeight: 48,
                              maxWidth: 48),
                          enabled: widget.enabled,
                          border: InputBorder.none,
                          hintText: widget.hintText,
                          errorStyle: const TextStyle(height: 0.01),
                          hintStyle: (widget.isSmall
                                  ? Theme.of(context).textTheme.bodySmall!
                                  : Theme.of(context).textTheme.bodyMedium!)
                              .copyWith(
                                  color: Theme.of(context).colorScheme.hint),
                        ),
                      ),
                    ));
              }),
        ),
        AnimatedVisibility(
          isVisible: _error != null,
          duration: DesignConfig.lowAnimationDuration,
          child: Column(
            children: [
              const SizedBox(height: 8),
              Row(
                children: [
                  Icon(
                    DidvanIcons.lightbulb_exclamation_regular,
                    color: Theme.of(context).colorScheme.error,
                    size: 14,
                  ),
                  DidvanText(
                    _error ?? '',
                    style: Theme.of(context).textTheme.bodySmall,
                    color: Theme.of(context).colorScheme.error,
                  ),
                ],
              ),
            ],
          ),
        )
      ],
    );
  }

  Color _borderColor() {
    if (_focusNode.hasFocus) {
      return const Color.fromARGB(255, 102, 102, 102);
    } else if (_error != null) {
      return Theme.of(context).colorScheme.error;
    }
    return const Color.fromARGB(255, 223, 223, 223);
  }

  Color? _titleColor() {
    if (!widget.enabled) {
      return Theme.of(context).colorScheme.hint;
    }
    if (_error != null) {
      return Theme.of(context).colorScheme.error;
    }
    return const Color.fromARGB(255, 102, 102, 102);
  }

  Color _fillColor() {
    if (!widget.enabled) {
      return DesignConfig.isDark
          ? Theme.of(context).colorScheme.onSurface.withOpacity(0.1)
          : const Color.fromARGB(255, 245, 245, 245);
    }
    if (_focusNode.hasFocus) {
      return Theme.of(context).colorScheme.surface;
    }
    if (_error != null) {
      return Theme.of(context).colorScheme.errorContainer.withOpacity(0.1);
    }
    return Theme.of(context).colorScheme.surface;
  }

  Widget? _suffixBuilder() {
    if (widget.obsecureText) {
      return FittedBox(
        fit: BoxFit.scaleDown,
        child: GestureDetector(
          onTap: () {
            setState(() {
              _hideContent = !_hideContent;
            });
          },
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: SvgPicture.asset(
              _hideContent
                  ? 'lib/assets/icons/eye.svg'
                  : 'lib/assets/icons/eye-slash.svg',
              height: 20,
            ),
          ),
        ),
      );
    }
    if (widget.suffixSvgPath != null) {
      return Padding(
        padding: const EdgeInsets.all(5.0),
        child: SvgPicture.asset(
          widget.suffixSvgPath!,
          fit: BoxFit.contain,
        ),
      );
    }
    return null;
  }

  Widget? _prefixBuilder() {
    if (widget.prefixSvgPath != null) {
      return Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 12.0),
            child: SvgPicture.asset(
              widget.prefixSvgPath!,
              fit: BoxFit.contain,
              width: 24,
              height: 24,
            ),
          ),
          Container(
              width: 1,
              height: 24,
              color: const Color.fromARGB(255, 184, 184, 184)),
          const SizedBox(width: 8),
        ],
      );
    }
    return null;
  }

  void _onChanged(String value) {
    setState(() {
      _error = null;
    });
    widget.onChanged?.call(value);
  }

  String? _validator(String? value) {
    if (widget.validator != null) {
      final String? error = widget.validator!(value!);
      if (error != null) {
        setState(() {
          _error = error;
        });
        return '';
      } else {
        setState(() {
          _error = null;
        });
      }
    }
    return null;
  }

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