// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import 'package:flutter/material.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
import 'package:wyatt_ui_kit/src/components/text_inputs/cubit/text_input_cubit.dart';
import 'package:wyatt_ui_kit/src/core/core.dart';
import 'package:wyatt_ui_kit/src/domain/text_input_theme_extension.dart';

class TextInputThemeResolver extends ThemeResolver<TextInputStyle,
    TextInputThemeExtension, TextInputState> {
  const TextInputThemeResolver({
    required this.customStyleFn,
  });

  @override
  final TextInputStyle? Function(
    BuildContext context, {
    TextInputState? extra,
  }) customStyleFn;

  @override
  TextInputStyle computeDefaultValue(
    BuildContext context, {
    TextInputState? extra,
  }) {
    TextStyle? labelStyle = context.textTheme.labelLarge
        ?.copyWith(color: Theme.of(context).unselectedWidgetColor);

    TextStyle? hintStyle = context.textTheme.labelLarge;
    TextStyle? prefixStyle = context.textTheme.bodyMedium;
    TextStyle? suffixStyle = context.textTheme.bodyMedium;
    TextStyle? inputStyle = context.textTheme.bodyMedium;

    Color? iconColor = context.colorScheme.inversePrimary;
    Color? prefixIconColor = Theme.of(context).unselectedWidgetColor;
    Color? suffixIconColor = Theme.of(context).unselectedWidgetColor;

    Color? borderColors = Theme.of(context).unselectedWidgetColor;

    MultiColor? backgroundColors;
    BoxShadow? boxShadow;

    final BorderRadiusGeometry radius = BorderRadius.circular(4);

    switch (extra?.controlState) {
      case ControlState.disabled:
        labelStyle =
            labelStyle?.copyWith(color: Theme.of(context).disabledColor);
        hintStyle = hintStyle?.copyWith(color: Theme.of(context).disabledColor);
        prefixStyle =
            prefixStyle?.copyWith(color: Theme.of(context).disabledColor);
        suffixStyle =
            suffixStyle?.copyWith(color: Theme.of(context).disabledColor);
        inputStyle =
            inputStyle?.copyWith(color: Theme.of(context).disabledColor);
        borderColors = Theme.of(context).disabledColor;
        prefixIconColor = Theme.of(context).disabledColor;
        suffixIconColor = Theme.of(context).disabledColor;

        break;

      case ControlState.focused:
        prefixIconColor = context.colorScheme.primary;
        suffixIconColor = context.colorScheme.primary;
        iconColor = context.colorScheme.primary;
        borderColors = context.colorScheme.primary;
        labelStyle = labelStyle?.copyWith(color: context.colorScheme.primary);
        break;
      case ControlState.hovered:
      case ControlState.tapped:
      case ControlState.normal:
      case null:
        break;
    }

    switch (extra?.statusState) {
      case StatusState.error:
        labelStyle = context.textTheme.labelLarge
            ?.copyWith(color: context.colorScheme.error);
        borderColors = context.colorScheme.error;
        break;
      case StatusState.initial:
      case StatusState.success:
      case StatusState.loading:
      case null:
        break;
    }
    return TextInputStyle(
      labelStyle: labelStyle,
      hintStyle: hintStyle,
      iconColor: iconColor,
      prefixIconColor: prefixIconColor,
      prefixStyle: prefixStyle,
      suffixStyle: suffixStyle,
      suffixIconColor: suffixIconColor,
      backgroundColors: backgroundColors,
      borderColors: borderColors,
      boxShadow: boxShadow,
      radius: radius,
      inputStyle: inputStyle,
    );
  }

  @override
  TextInputStyle? computeExtensionValueFn(
    BuildContext context,
    TextInputThemeExtension? themeExtension, {
    TextInputState? extra,
  }) {
    TextInputStyle? textInputStyle;
    switch (extra?.controlState) {
      case ControlState.focused:
        textInputStyle = themeExtension?.focusedStyle;
        break;
      case ControlState.disabled:
        textInputStyle = themeExtension?.disableStyle;
        break;
      case ControlState.normal:
        textInputStyle = themeExtension?.normalStyle;
        break;
      case ControlState.hovered:
      case ControlState.tapped:
      case null:
        break;
    }

    TextInputStyle? style;
    switch (extra?.statusState) {
      case StatusState.error:
        style = themeExtension?.errorStyle;
        break;
      case StatusState.initial:
      case StatusState.success:
      case StatusState.loading:
      case null:
        break;
    }

    return TextInputStyle.merge(textInputStyle, style);
  }
}
