/**
 * 通用组件共同的使用的基础组件，原先放在 adapter/form 内部，限制了使用范围，这里提取出来，方便其他地方使用
 * 可用于 vben-form、vben-modal、vben-drawer 等组件使用,
 */

import type { Component } from 'vue';

import type { BaseFormComponentType } from '@vben/common-ui';

import { defineComponent, h, ref } from 'vue';

import { useMessage } from '@jnpf/hooks';
import {
  AButton,
  BasicCaption,
  BasicHelp,
  JnpfAlert,
  JnpfBarcode,
  JnpfCascader,
  JnpfCheckbox,
  JnpfCheckboxSingle,
  JnpfColorPicker,
  JnpfCron,
  JnpfDatePicker,
  JnpfDateRange,
  JnpfDivider,
  JnpfEditor,
  JnpfEmpty,
  JnpfIconPicker,
  JnpfIframe,
  JnpfInput,
  JnpfInputNumber,
  JnpfLink,
  JnpfMarkdown,
  JnpfMarkdownViewer,
  JnpfNumberRange,
  JnpfQrcode,
  JnpfRadio,
  JnpfRate,
  JnpfSelect,
  JnpfSlider,
  JnpfSwitch,
  JnpfText,
  JnpfTextarea,
  JnpfTimePicker,
  JnpfTimeRange,
  JnpfTreeSelect,
} from '@jnpf/ui';
import { componentMap } from '@jnpf/ui/form';

import { globalShareState } from '@vben/common-ui';
import { $t } from '@vben/locales';

import { Checkbox as ACheckbox, Radio as ARadio, InputPassword, Mentions, notification, Space } from 'ant-design-vue';

import { createCollectMenu } from '#/api/system/collectMenu';
import {
  JnpfAreaSelect,
  JnpfAutoComplete,
  JnpfCalculate,
  JnpfDateCalculate,
  JnpfGroupSelect,
  JnpfI18nInput,
  JnpfLocation,
  JnpfOcr,
  JnpfOpenData,
  JnpfOrganizeSelect,
  JnpfPopupAttr,
  JnpfPopupSelect,
  JnpfPopupTableSelect,
  JnpfPosSelect,
  JnpfRelationForm,
  JnpfRelationFormAttr,
  JnpfRelationQuery,
  JnpfRoleSelect,
  JnpfSign,
  JnpfSignature,
  JnpfUploadFile,
  JnpfUploadImg,
  JnpfUploadImgSingle,
  JnpfUserSelect,
  JnpfUsersSelect,
} from '#/components/Jnpf';
import InputTable from '#/components/Jnpf/InputTable/src/InputTable.vue';
import { useAuthStore, useGeneratorStore } from '#/store';

import { initSetupVbenForm } from '../form';
import { initSetupVxeTable } from '../vxe-table';

const { createMessage } = useMessage();

const withDefaultPlaceholder = <T extends Component>(component: T, type: 'input' | 'select', componentProps: Recordable<any> = {}) => {
  return defineComponent({
    name: component.name,
    inheritAttrs: false,
    setup: (props: any, { attrs, expose, slots }) => {
      const placeholder = props?.placeholder || attrs?.placeholder || $t(`ui.placeholder.${type}`);
      // 透传组件暴露的方法
      const innerRef = ref();
      // const publicApi: Recordable<any> = {};
      expose(
        new Proxy(
          {},
          {
            get: (_target, key) => innerRef.value?.[key],
            has: (_target, key) => key in (innerRef.value || {}),
          },
        ),
      );
      // const instance = getCurrentInstance();
      // instance?.proxy?.$nextTick(() => {
      //   for (const key in innerRef.value) {
      //     if (typeof innerRef.value[key] === 'function') {
      //       publicApi[key] = innerRef.value[key];
      //     }
      //   }
      // });
      h(component, { ...componentProps, placeholder, ...props, ...attrs, ref: innerRef }, slots);
    },
  });
};

// 这里需要自行根据业务组件库进行适配，需要用到的组件都需要在这里类型说明
export type ComponentType =
  | 'Alert'
  | 'AreaSelect'
  | 'Barcode'
  | 'Button'
  | 'Calculate'
  | 'Cascader'
  | 'Checkbox'
  | 'CheckboxSingle'
  | 'ColorPicker'
  | 'Cron'
  | 'DatePicker'
  | 'DateRange'
  | 'DefaultButton'
  | 'Divider'
  | 'Editor'
  | 'GroupSelect'
  | 'GroupTitle'
  | 'I18nInput'
  | 'IconPicker'
  | 'Iframe'
  | 'Input'
  | 'InputNumber'
  | 'InputPassword'
  | 'Link'
  | 'Location'
  | 'Markdown'
  | 'MarkdownViewer'
  | 'Mentions'
  | 'NumberRange'
  | 'OpenData'
  | 'OrganizeSelect'
  | 'PopupAttr'
  | 'PopupSelect'
  | 'PopupTableSelect'
  | 'PosSelect'
  | 'PrimaryButton'
  | 'Qrcode'
  | 'Radio'
  | 'Rate'
  | 'RelationForm'
  | 'RelationFormAttr'
  | 'RoleSelect'
  | 'Select'
  | 'Sign'
  | 'Signature'
  | 'Slider'
  | 'Space'
  | 'Switch'
  | 'Text'
  | 'Textarea'
  | 'TimePicker'
  | 'TimeRange'
  | 'TreeSelect'
  | 'UploadFile'
  | 'UploadImg'
  | 'UploadImgSingle'
  | 'UserSelect'
  | 'UsersSelect'
  | BaseFormComponentType;

async function initSetupBasicForm() {
  componentMap.set('AreaSelect', JnpfAreaSelect);
  componentMap.set('AutoComplete', JnpfAutoComplete);
  componentMap.set('Calculate', JnpfCalculate);
  componentMap.set('DateCalculate', JnpfDateCalculate);
  componentMap.set('OrganizeSelect', JnpfOrganizeSelect);
  componentMap.set('PosSelect', JnpfPosSelect);
  componentMap.set('GroupSelect', JnpfGroupSelect);
  componentMap.set('RoleSelect', JnpfRoleSelect);
  componentMap.set('UserSelect', JnpfUserSelect);
  componentMap.set('UsersSelect', JnpfUsersSelect);
  componentMap.set('Sign', JnpfSign);
  componentMap.set('Signature', JnpfSignature);
  componentMap.set('UploadFile', JnpfUploadFile);
  componentMap.set('UploadImg', JnpfUploadImg);
  componentMap.set('UploadImgSingle', JnpfUploadImgSingle);
  componentMap.set('CreateUser', JnpfOpenData);
  componentMap.set('CreateTime', JnpfOpenData);
  componentMap.set('CurrOrganize', JnpfOpenData);
  componentMap.set('CurrPosition', JnpfOpenData);
  componentMap.set('RelationForm', JnpfRelationForm);
  componentMap.set('RelationFormAttr', JnpfRelationFormAttr);
  componentMap.set('PopupSelect', JnpfPopupSelect);
  componentMap.set('PopupTableSelect', JnpfPopupTableSelect);
  componentMap.set('PopupAttr', JnpfPopupAttr);
  componentMap.set('Location', JnpfLocation);
  componentMap.set('InputTable', InputTable);
  componentMap.set('RelationQuery', JnpfRelationQuery);
  componentMap.set('Ocr', JnpfOcr);
}

async function initComponentAdapter() {
  const components: Partial<Record<ComponentType, Component>> = {
    // 如果你的组件体积比较大，可以使用异步加载
    // Button: () =>
    // import('xxx').then((res) => res.Button),

    Button: AButton,
    BasicHelp,
    AutoComplete: JnpfAutoComplete,
    Checkbox: JnpfCheckbox,
    CheckboxSingle: JnpfCheckboxSingle,
    DatePicker: JnpfDatePicker,
    // 自定义默认按钮
    DefaultButton: (props, { attrs, slots }) => {
      return h(AButton, { ...props, attrs, type: 'default' }, slots);
    },
    Divider: JnpfDivider,
    Input: JnpfInput,
    InputNumber: JnpfInputNumber,
    InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
    Mentions: withDefaultPlaceholder(Mentions, 'input'),
    // 自定义主要按钮
    PrimaryButton: (props, { attrs, slots }) => {
      return h(AButton, { ...props, attrs, type: 'primary' }, slots);
    },
    Radio: JnpfRadio,
    Rate: JnpfRate,
    Select: JnpfSelect,
    Space,
    Switch: JnpfSwitch,
    Textarea: withDefaultPlaceholder(JnpfTextarea, 'input'),
    TimePicker: JnpfTimePicker,
    TreeSelect: withDefaultPlaceholder(JnpfTreeSelect, 'select'),
    UploadFile: JnpfUploadFile,
    UploadImg: JnpfUploadImg,
    UploadImgSingle: JnpfUploadImgSingle,
    Alert: JnpfAlert,
    AreaSelect: JnpfAreaSelect,
    Barcode: JnpfBarcode,
    Calculate: JnpfCalculate,
    Cascader: JnpfCascader,
    ColorPicker: JnpfColorPicker,
    Cron: JnpfCron,
    DateCalculate: JnpfDateCalculate,
    DateRange: JnpfDateRange,
    Editor: JnpfEditor,
    GroupSelect: JnpfGroupSelect,
    GroupTitle: BasicCaption,
    IconPicker: JnpfIconPicker,
    Iframe: JnpfIframe,
    Link: JnpfLink,
    Location: JnpfLocation,
    I18nInput: JnpfI18nInput,
    Markdown: JnpfMarkdown,
    MarkdownViewer: JnpfMarkdownViewer,
    NumberRange: JnpfNumberRange,
    OpenData: JnpfOpenData,
    OrganizeSelect: JnpfOrganizeSelect,
    PopupAttr: JnpfPopupAttr,
    PopupSelect: JnpfPopupSelect,
    PopupTableSelect: JnpfPopupTableSelect,
    PosSelect: JnpfPosSelect,
    Qrcode: JnpfQrcode,
    RelationForm: JnpfRelationForm,
    RelationFormAttr: JnpfRelationFormAttr,
    RoleSelect: JnpfRoleSelect,
    Sign: JnpfSign,
    Signature: JnpfSignature,
    Slider: JnpfSlider,
    Text: JnpfText,
    TimeRange: JnpfTimeRange,
    UserSelect: JnpfUserSelect,
    UsersSelect: JnpfUsersSelect,
    Empty: JnpfEmpty,
    ACheckbox,
    ARadio,
  };

  const api: any = {
    createCollectMenu,
  };

  const store: any = {
    useAuthStore,
    useGeneratorStore,
  };

  // 将组件注册到全局共享状态中
  globalShareState.setComponents(components);

  // 将api注册到全局共享状态中
  globalShareState.setApi(api);

  // 将store注册到全局共享状态中
  globalShareState.setStores(store);

  // 定义全局共享状态中的消息提示
  globalShareState.defineMessage({
    // 复制成功消息提示
    copyPreferencesSuccess: (title, content) => {
      notification.success({
        description: content,
        message: title,
        placement: 'bottomRight',
      });
    },
    createMessage,
  });

  // 初始化BasicForm
  initSetupBasicForm();
  // 初始化表单组件
  initSetupVbenForm();
  // 初始化VxeTable
  initSetupVxeTable();
}

export { initComponentAdapter };
