import classNames from '../_util/classNames';
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
import { getInputClassName } from './Input';
import PropTypes from '../_util/vue-types';
import { cloneElement } from '../_util/vnode';
import { getComponent } from '../_util/props-util';
import { defineComponent, VNode } from 'vue';
import { tuple } from '../_util/type';
export function hasPrefixSuffix(instance: any) {
  return !!(
    getComponent(instance, 'prefix') ||
    getComponent(instance, 'suffix') ||
    instance.$props.allowClear
  );
}
const ClearableInputType = ['text', 'input'];
const ClearableLabeledInput = defineComponent({
  name: 'ClearableLabeledInput',
  inheritAttrs: false,
  props: {
    prefixCls: PropTypes.string,
    inputType: PropTypes.oneOf(tuple('text', 'input')),
    value: PropTypes.any,
    defaultValue: PropTypes.any,
    allowClear: PropTypes.looseBool,
    element: PropTypes.VNodeChild,
    handleReset: PropTypes.func,
    disabled: PropTypes.looseBool,
    size: PropTypes.oneOf(tuple('small', 'large', 'default')),
    suffix: PropTypes.VNodeChild,
    prefix: PropTypes.VNodeChild,
    addonBefore: PropTypes.VNodeChild,
    addonAfter: PropTypes.VNodeChild,
    readonly: PropTypes.looseBool,
    isFocused: PropTypes.looseBool,
  },
  methods: {
    renderClearIcon(prefixCls: string) {
      const { allowClear, value, disabled, readonly, inputType, handleReset } = this.$props;
      if (!allowClear) {
        return null;
      }
      const showClearIcon =
        !disabled && !readonly && value !== undefined && value !== null && value !== '';
      const className =
        inputType === ClearableInputType[0]
          ? `${prefixCls}-textarea-clear-icon`
          : `${prefixCls}-clear-icon`;
      return (
        
      );
    },
    renderSuffix(prefixCls: string) {
      const { suffix, allowClear } = this.$props;
      if (suffix || allowClear) {
        return (
          
            {this.renderClearIcon(prefixCls)}
            {suffix}
          
        );
      }
      return null;
    },
    renderLabeledIcon(prefixCls: string, element: VNode): VNode {
      const props = this.$props;
      const { style } = this.$attrs;
      const suffix = this.renderSuffix(prefixCls);
      if (!hasPrefixSuffix(this)) {
        return cloneElement(element, {
          value: props.value,
        });
      }
      const prefix = props.prefix ? (
        {props.prefix}
      ) : null;
      const affixWrapperCls = classNames(this.$attrs?.class, `${prefixCls}-affix-wrapper`, {
        [`${prefixCls}-affix-wrapper-focused`]: props.isFocused,
        [`${prefixCls}-affix-wrapper-disabled`]: props.disabled,
        [`${prefixCls}-affix-wrapper-sm`]: props.size === 'small',
        [`${prefixCls}-affix-wrapper-lg`]: props.size === 'large',
        [`${prefixCls}-affix-wrapper-input-with-clear-btn`]:
          props.suffix && props.allowClear && this.$props.value,
      });
      return (
        
          {prefix}
          {cloneElement(element, {
            style: null,
            value: props.value,
            class: getInputClassName(prefixCls, props.size, props.disabled),
          })}
          {suffix}
        
      ) as VNode;
    },
    renderInputWithLabel(prefixCls: string, labeledElement: VNode) {
      const { addonBefore, addonAfter, size } = this.$props;
      const { style, class: className } = this.$attrs;
      // Not wrap when there is not addons
      if (!addonBefore && !addonAfter) {
        return labeledElement;
      }
      const wrapperClassName = `${prefixCls}-group`;
      const addonClassName = `${wrapperClassName}-addon`;
      const addonBeforeNode = addonBefore ? (
        {addonBefore}
      ) : null;
      const addonAfterNode = addonAfter ? {addonAfter} : null;
      const mergedWrapperClassName = classNames(`${prefixCls}-wrapper`, {
        [wrapperClassName]: addonBefore || addonAfter,
      });
      const mergedGroupClassName = classNames(className, `${prefixCls}-group-wrapper`, {
        [`${prefixCls}-group-wrapper-sm`]: size === 'small',
        [`${prefixCls}-group-wrapper-lg`]: size === 'large',
      });
      // Need another wrapper for changing display:table to display:inline-block
      // and put style prop in wrapper
      return (
        
          
            {addonBeforeNode}
            {cloneElement(labeledElement, { style: null })}
            {addonAfterNode}
          
        
      );
    },
    renderTextAreaWithClearIcon(prefixCls: string, element: VNode) {
      const { value, allowClear } = this.$props;
      const { style, class: className } = this.$attrs;
      if (!allowClear) {
        return cloneElement(element, { value });
      }
      const affixWrapperCls = classNames(
        className,
        `${prefixCls}-affix-wrapper`,
        `${prefixCls}-affix-wrapper-textarea-with-clear-btn`,
      );
      return (
        
          {cloneElement(element, {
            style: null,
            value,
          })}
          {this.renderClearIcon(prefixCls)}
        
      );
    },
    renderClearableLabeledInput() {
      const { prefixCls, inputType, element } = this.$props as any;
      if (inputType === ClearableInputType[0]) {
        return this.renderTextAreaWithClearIcon(prefixCls, element);
      }
      return this.renderInputWithLabel(prefixCls, this.renderLabeledIcon(prefixCls, element));
    },
  },
  render() {
    return this.renderClearableLabeledInput();
  },
});
export default ClearableLabeledInput;