/*
 * @Author: 赵伟
 * @Date: 2024-04-16 08:42:57
 * @Description: 参数输入表单组件，支持手动输入，也支持选择全局参数
 */

import { CommonTabKeys } from '@/enums';
import { CloseOutlined } from '@ant-design/icons';
import { ConfigProvider, Form, Input, Typography } from 'antd';
import { RuleObject } from 'antd/es/form';
import classNames from 'classnames';
import './index.less';

// 如果值是对象时的类型
export type ParameterInputObject = {
  value?: any; // 值
  showValue?: any; // 显示值
  fromSelect?: boolean; // 是否来自选择
  activeTab?: CommonTabKeys; // 选择镜像、数据集、模型时，保存当前激活的tab
  expandedKeys?: string[]; // 选择镜像、数据集、模型时，保存展开的keys
  checkedKeys?: string[]; // 选择镜像、数据集、模型时，保存选中的keys
  [key: string]: any;
};

// 值类型
export type ParameterInputValue = ParameterInputObject | string;

export interface ParameterInputProps {
  /** 值，可以是字符串，也可以是 ParameterInputObject 对象 */
  value?: ParameterInputValue;
  /**
   * 值变化时的回调
   * @param value 值，可以是字符串，也可以是 ParameterInputObject 对象
   */
  onChange?: (value?: ParameterInputValue) => void;
  /** 点击时的回调 */
  onClick?: () => void;
  /**  删除时的回调 */
  onRemove?: () => void;
  /** 是否可以手动输入 */
  canInput?: boolean;
  /** 是否是文本框 */
  textArea?: boolean;
  /** 占位符 */
  placeholder?: string;
  /** 是否允许清除 */
  allowClear?: boolean;
  /** 自定义类名 */
  className?: string;
  /** 自定义样式 */
  style?: React.CSSProperties;
  /** 大小 */
  size?: 'middle' | 'small' | 'large';
  /** 是否禁用 */
  disabled?: boolean;
  /** 元素 id */
  id?: string;
}

function ParameterInput({
  value,
  onChange,
  onClick,
  onRemove,
  canInput = true,
  textArea = false,
  allowClear,
  className,
  style,
  size,
  disabled = false,
  id,
  ...rest
}: ParameterInputProps) {
  const valueObj =
    typeof value === 'string' ? { value: value, fromSelect: false, showValue: value } : value;
  if (valueObj && !valueObj.showValue) {
    valueObj.showValue = valueObj.value;
  }
  const isSelect = valueObj?.fromSelect;
  const placeholder = valueObj?.placeholder || rest?.placeholder;
  const InputComponent = textArea ? Input.TextArea : Input;
  const { status } = Form.Item.useStatus();
  const { componentSize } = ConfigProvider.useConfig();
  const mySize = size || componentSize;

  // 删除
  const handleRemove = (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) => {
    e.stopPropagation();
    if (onRemove) {
      onRemove();
      return;
    }

    onChange?.({
      ...valueObj,
      value: undefined,
      showValue: undefined,
      fromSelect: false,
      activeTab: undefined,
      expandedKeys: [],
      checkedKeys: [],
    });
  };

  return (
    <>
      {(isSelect || !canInput) && !disabled ? (
        <div
          id={id}
          className={classNames(
            'parameter-input',
            { 'parameter-input--large': mySize === 'large' },
            { 'parameter-input--small': mySize === 'small' },
            { [`parameter-input--${status}`]: status },
            className,
          )}
          style={style}
          onClick={onClick}
        >
          {valueObj?.showValue ? (
            <div className="parameter-input__content">
              <Typography.Text
                className="parameter-input__content__value"
                ellipsis={{ tooltip: valueObj.showValue }}
              >
                {valueObj.showValue}
              </Typography.Text>
              <CloseOutlined
                className="parameter-input__content__close-icon"
                onClick={handleRemove}
              />
            </div>
          ) : (
            <div className="parameter-input__placeholder">{placeholder}</div>
          )}
        </div>
      ) : (
        <InputComponent
          {...rest}
          id={id}
          size={mySize}
          className={className}
          style={style}
          placeholder={placeholder}
          allowClear={allowClear}
          value={valueObj?.showValue}
          disabled={disabled}
          onChange={(e) =>
            onChange?.({
              ...valueObj,
              value: e.target.value,
              showValue: e.target.value,
              fromSelect: false,
            })
          }
        />
      )}
    </>
  );
}

export default ParameterInput;

// 必填校验
export const requiredValidator = (rule: RuleObject, value: any) => {
  const trueValue = typeof value === 'object' ? value?.value : value;
  if (!trueValue) {
    return Promise.reject(rule.message || '必填项');
  }
  return Promise.resolve();
};
