import type { ApiSelectProps } from '#/components/form-create/typing';

import { defineComponent, onMounted, ref, useAttrs } from 'vue';

import { useUserStore } from '..\..\..\packages\stores\src';
import { isEmpty } from '..\..\..\packages\utils\src';

import {
  Checkbox,
  CheckboxGroup,
  Radio,
  RadioGroup,
  Select,
  SelectOption,
} from 'ant-design-vue';

import { requestClient } from '#/api/request';

export function useApiSelect(option: ApiSelectProps) {
  return defineComponent({
    name: option.name,
    props: {
      // 选项标签
      labelField: {
        type: String,
        default: () => option.labelField ?? 'label',
      },
      // 选项的值
      valueField: {
        type: String,
        default: () => option.valueField ?? 'value',
      },
      // api 接口
      url: {
        type: String,
        default: () => option.url ?? '',
      },
      // 请求类型
      method: {
        type: String,
        default: 'GET',
      },
      // 选项解析函数
      parseFunc: {
        type: String,
        default: '',
      },
      // 请求参数
      data: {
        type: String,
        default: '',
      },
      // 选择器类型，下拉框 select、多选框 checkbox、单选框 radio
      selectType: {
        type: String,
        default: 'select',
      },
      // 是否多选
      multiple: {
        type: Boolean,
        default: false,
      },
      // 是否远程搜索
      remote: {
        type: Boolean,
        default: false,
      },
      // 远程搜索时携带的参数
      remoteField: {
        type: String,
        default: 'label',
      },
      // 返回值类型（用于部门选择器等）：id 返回 ID，name 返回名称
      returnType: {
        type: String,
        default: 'id',
      },
      // 是否默认选中当前用户（仅用于 UserSelect）
      defaultCurrentUser: {
        type: Boolean,
        default: false,
      },
    },
    setup(props, { emit }) {
      const attrs = useAttrs();
      const options = ref<any[]>([]); // 下拉数据
      const loading = ref(false); // 是否正在从远程获取数据
      const queryParam = ref<any>(); // 当前输入的值

      // 检查是否有有效的预设值
      function hasValidPresetValue(): boolean {
        const value = attrs.modelValue;
        if (value === undefined || value === null || value === '') {
          return false;
        }
        if (Array.isArray(value)) {
          return value.length > 0;
        }
        return true;
      }

      // 设置默认当前用户
      function setDefaultCurrentUser(): void {
        if (option.name !== 'UserSelect' || !props.defaultCurrentUser) {
          return;
        }
        if (hasValidPresetValue()) {
          return;
        }
        const userStore = useUserStore();
        const currentUserId = userStore.userInfo?.id;
        if (currentUserId) {
          const defaultValue = props.multiple ? [currentUserId] : currentUserId;
          emit('update:modelValue', defaultValue);
        }
      }

      const getOptions = async () => {
        options.value = [];
        // 接口选择器
        if (isEmpty(props.url)) {
          return;
        }

        switch (props.method) {
          case 'GET': {
            let url: string = props.url;
            if (props.remote && queryParam.value !== undefined) {
              url = url.includes('?')
                ? `${url}&${props.remoteField}=${queryParam.value}`
                : `${url}?${props.remoteField}=${queryParam.value}`;
            }
            parseOptions(await requestClient.get(url));
            break;
          }
          case 'POST': {
            const data: any = JSON.parse(props.data);
            if (props.remote) {
              data[props.remoteField] = queryParam.value;
            }
            parseOptions(await requestClient.post(props.url, data));
            break;
          }
        }
      };

      function parseOptions(data: any) {
        //  情况一：如果有自定义解析函数优先使用自定义解析
        if (!isEmpty(props.parseFunc)) {
          options.value = parseFunc()?.(data);
          return;
        }
        // 情况二：返回的直接是一个列表
        if (Array.isArray(data)) {
          parseOptions0(data);
          return;
        }
        // 情况二：返回的是分页数据,尝试读取 list
        data = data.list;
        if (!!data && Array.isArray(data)) {
          parseOptions0(data);
          return;
        }
        // 情况三：不是 yudao-vue-pro 标准返回
        console.warn(
          `接口[${props.url}] 返回结果不是 yudao-vue-pro 标准返回建议采用自定义解析函数处理`,
        );
      }

      function parseOptions0(data: any[]) {
        if (Array.isArray(data)) {
          options.value = data.map((item: any) => {
            const label = parseExpression(item, props.labelField);
            let value = parseExpression(item, props.valueField);

            // 根据 returnType 决定返回值
            // 如果设置了 returnType 为 'name'，则返回 label 作为 value
            if (props.returnType === 'name') {
              value = label;
            }

            return {
              label,
              value,
            };
          });
          return;
        }
        console.warn(`接口[${props.url}] 返回结果不是一个数组`);
      }

      function parseFunc() {
        let parse: any = null;
        if (props.parseFunc) {
          // 解析字符串函数
          // oxlint-disable-next-line typescript/no-implied-eval
          // oxlint-disable-next-line no-new-func, typescript/no-implied-eval
          parse = new Function(`return ${props.parseFunc}`)();
        }
        return parse;
      }

      function parseExpression(data: any, template: string) {
        // 检测是否使用了表达式
        if (!template.includes('${')) {
          return data[template];
        }
        // 正则表达式匹配模板字符串中的 ${...}
        const pattern = /\$\{([^}]*)\}/g;
        // 使用replace函数配合正则表达式和回调函数来进行替换
        return template.replaceAll(pattern, (_, expr) => {
          // expr 是匹配到的 ${} 内的表达式（这里是属性名），从 data 中获取对应的值
          const result = data[expr.trim()]; // 去除前后空白，以防用户输入带空格的属性名
          if (!result) {
            console.warn(
              `接口选择器选项模版[${template}][${expr.trim()}] 解析值失败结果为[${result}], 请检查属性名称是否存在于接口返回值中,存在则忽略此条！！！`,
            );
          }
          return result;
        });
      }

      const remoteMethod = async (query: any) => {
        if (!query) {
          return;
        }
        loading.value = true;
        try {
          queryParam.value = query;
          await getOptions();
        } finally {
          loading.value = false;
        }
      };

      onMounted(async () => {
        await getOptions();
        // 设置默认当前用户（仅用于 UserSelect）
        setDefaultCurrentUser();
      });

      const buildSelect = () => {
        const {
          modelValue,
          'onUpdate:modelValue': onUpdateModelValue,
          ...restAttrs
        } = attrs;

        if (props.multiple) {
          // fix：多写此步是为了解决 multiple 属性问题
          return (
            <Select
              class="w-full"
              loading={loading.value}
              mode="multiple"
              onUpdate:value={onUpdateModelValue as any}
              value={modelValue as any}
              {...restAttrs}
              // TODO @xingyu remote 对等实现, 还是说没作用
              // remote={props.remote}
              {...(props.remote && { remoteMethod })}
            >
              {options.value.map(
                (item: { label: any; value: any }, index: any) => (
                  <SelectOption key={index} value={item.value}>
                    {item.label}
                  </SelectOption>
                ),
              )}
            </Select>
          );
        }
        return (
          <Select
            class="w-full"
            loading={loading.value}
            onUpdate:value={onUpdateModelValue as any}
            value={modelValue as any}
            {...restAttrs}
            // TODO: @xingyu remote 对等实现, 还是说没作用
            // remote={props.remote}
            {...(props.remote && { remoteMethod })}
          >
            {options.value.map(
              (item: { label: any; value: any }, index: any) => (
                <SelectOption key={index} value={item.value}>
                  {item.label}
                </SelectOption>
              ),
            )}
          </Select>
        );
      };
      const buildCheckbox = () => {
        const {
          modelValue,
          'onUpdate:modelValue': onUpdateModelValue,
          ...restAttrs
        } = attrs;
        if (isEmpty(options.value)) {
          options.value = [
            { label: '选项1', value: '选项1' },
            { label: '选项2', value: '选项2' },
          ];
        }
        return (
          <CheckboxGroup
            class="w-full"
            onUpdate:value={onUpdateModelValue as any}
            value={modelValue as any}
            {...restAttrs}
          >
            {options.value.map(
              (item: { label: any; value: any }, index: any) => (
                <Checkbox key={index} value={item.value}>
                  {item.label}
                </Checkbox>
              ),
            )}
          </CheckboxGroup>
        );
      };
      const buildRadio = () => {
        const {
          modelValue,
          'onUpdate:modelValue': onUpdateModelValue,
          ...restAttrs
        } = attrs;
        if (isEmpty(options.value)) {
          options.value = [
            { label: '选项1', value: '选项1' },
            { label: '选项2', value: '选项2' },
          ];
        }
        return (
          <RadioGroup
            class="w-full"
            onUpdate:value={onUpdateModelValue as any}
            value={modelValue as any}
            {...restAttrs}
          >
            {options.value.map(
              (item: { label: any; value: any }, index: any) => (
                <Radio key={index} value={item.value}>
                  {item.label}
                </Radio>
              ),
            )}
          </RadioGroup>
        );
      };
      return () => (
        <>
          {(() => {
            switch (props.selectType) {
              case 'checkbox': {
                return buildCheckbox();
              }
              case 'radio': {
                return buildRadio();
              }
              case 'select': {
                return buildSelect();
              }
              default: {
                return buildSelect();
              }
            }
          })()}
        </>
      );
    },
  });
}
