import {
  condition,
  getArrayTableCurrentRowByField,
  handleSelectDataSource,
  handleSelectRequestConfig,
} from '../../util/util';
import {
  componentMap as formComponentMap,
  CnTreeSelect,
  CnTooltip,
  formilyReact,
} from '@cainiaofe/cn-ui';
import { DisplayPosition } from '../position/display-position';
import { getJSExpressionPrototype } from '../common-style';
import isPlainObject from 'lodash/isPlainObject';
import { getSelectParamSelectSetter } from '@/common/manager/filter-item/select';
import { handleRequestParams } from '@/common/util/request';
import {
  getExprSetterSnippet,
  getRequestExecuteSetter,
  getRequestWhenFocusSetterSnippet,
  getStaticDataSourceSnippet,
} from '@/common/manager/setter-snippet';
import { useRef } from 'react';
import { formComponentRefStorage } from '@/common/util/const';
import {
  __arrayTableCurrentRow__,
  componentRefSplit,
} from '@/common/util/expr-const';

const { useField } = formilyReact;

const TreeSelect = {
  position: [
    DisplayPosition.form,
    DisplayPosition.formDialog,
    DisplayPosition.filter,
    DisplayPosition.cnArrayTable,
    DisplayPosition.cnArraySubAreaCard,
  ],
  thumbUrl:
    'https://img.alicdn.com/imgextra/i1/O1CN01ZuLYQR1b7x0jp0Lfo_!!6000000003419-2-tps-240-144.png',
  title: '树选择',
  componentName: 'TreeSelect',
  component: CnTreeSelect,
  formComponent: (props) => {
    const realRef = useRef(null);
    const { _dataSourceName } = props || {};
    const params = props?.requestConfig?.params;
    const field = useField?.();
    if (Array.isArray(params) && params?.length > 0) {
      let _params = {};
      const { getRequestParams } = props;
      if (typeof getRequestParams === 'function') {
        _params = getRequestParams();
      }
      if (typeof field?.index === 'number') {
        const temp = field.query('..').value();
        const currentRow = temp?.[field.index];
        if (isPlainObject(currentRow)) {
          _params.tableCurrentRow = currentRow;
        }
      }
      _params.getExtraParam = () => {
        return {
          [__arrayTableCurrentRow__]:
            getArrayTableCurrentRowByField(useField?.()) || {},
        };
      };
      _params.extraParamList = [
        {
          [__arrayTableCurrentRow__]:
            getArrayTableCurrentRowByField(useField?.()) || {},
        },
      ];

      props.requestConfig.formatParam = (oldParams)=>{
        if(typeof _params?.getFormInstance === 'function') {
          const temp = _params.getFormInstance()?.values

          if(isPlainObject(temp)) {
            _params.recordDataSource = temp;
          }
        }
        const realParams = handleRequestParams(params, { ..._params });
        return {...oldParams,...realParams};
      }
      delete props.requestConfig.params;
    }
    const extraProps = {
      getRequestParams: undefined,
    };
    // handleFormUrlencodedData(props?.requestConfig);
    const fieldEntire = field?.path?.entire;
    if (_dataSourceName && fieldEntire && realRef) {
      formComponentRefStorage[
        `${_dataSourceName}${componentRefSplit}${fieldEntire}`
      ] = realRef;
    }
    return (
      <formComponentMap.CnTreeSelect {...props} {...extraProps} ref={realRef} />
    );
  },
  getDefaultProps: () => {
    return {
      dataOrigin: 'request',
      multiple: false,
    };
  },
  formItemBeforeHandler: (formItem, config) => {
    const { isDesign, urlParams, formValue, state, formProps, getFormInstance } = config;
    handleSelectRequestConfig({
      componentProps: formItem?.['x-component-props'],
      isDesign,
      urlParamsDataSource: urlParams,
      recordDataSource: formValue,
      state,
      ignoreHandleParam: true,
      handleDynamicUrl: true,
    });
    if (isPlainObject(formItem?.['x-component-props']?.multipleExtraProps)) {
      const { treeCheckable, treeCheckedStrategy } =
        formItem?.['x-component-props']?.multipleExtraProps;
      if (treeCheckable === true) {
        formItem['x-component-props'].treeCheckable = true;
        if (treeCheckedStrategy) {
          formItem['x-component-props'].treeCheckedStrategy =
            treeCheckedStrategy;
        }
      }
    }
    if (formItem?.['x-component-props']) {
      formItem['x-component-props'].getRequestParams = () => {
        return {
          urlParamsDataSource: urlParams,
          recordDataSource: formValue,
          state,
          getFormInstance,
        };
      };
      formItem['x-component-props']._dataSourceName =
        formProps?._dataSourceName;
    }
    handleSelectDataSource({
      componentProps: formItem?.['x-component-props'],
      state,
    });
  },
  filterItemBeforeHandler: (filterItemProps, config) => {
    handleSelectRequestConfig(config);
    if (isPlainObject(config?.componentProps?.multipleExtraProps)) {
      const { treeCheckable, treeCheckedStrategy } =
        config?.componentProps?.multipleExtraProps;
      if (treeCheckable === true) {
        config.componentProps.treeCheckable = true;
        if (treeCheckedStrategy) {
          config.componentProps.treeCheckedStrategy = treeCheckedStrategy;
        }
      }
    }
    handleSelectDataSource(config);
  },
  // select的prototype列表
  getPrototypeList: (position) => {
    const extraServiceProps = {};
    let jsExpressionPrototype = getJSExpressionPrototype({
      type: 'formRequest',
    });
    let executeProps = {
      initialCode: `(formValues, state) => {
  return formValues.xxxx === "xxxx";
}`,
      tip: `当前函数需要返回 true/false。
formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
`,
    };
    if (DisplayPosition.cnArrayTable === position) {
      extraServiceProps.dynamicUrlTemplate = `function(state, { ${__arrayTableCurrentRow__} }) {
  // __arrayTableCurrentRow__: 可编辑表格当前行的数据。
  return '/xxx';
}`;
      executeProps = {
        initialCode: `(formValues, state, { ${__arrayTableCurrentRow__} }) => {
  return formValues.xxxx === "xxxx";
}`,
        tip: `当前函数需要返回 true/false。
formValues：当前筛选栏/表单的数据。
state：全部的数据，在左侧列表中选择使用。
__arrayTableCurrentRow__：可编辑表格当前行的数据。
`,
      };
      jsExpressionPrototype = getJSExpressionPrototype({
        type: 'arrayTableCurrentRow',
      });
    }
    const paramSelectSetter = getSelectParamSelectSetter({ position });
    let extraConfigSetter;
    const requestExecuteSetter = getRequestExecuteSetter({
      exprSetter: getExprSetterSnippet({
        position,
      }),
    });
    if (requestExecuteSetter) {
      extraConfigSetter = [requestExecuteSetter];
    }
    return [
      {
        name: 'multiple',
        title: '选择模式',
        display: 'inline',
        setter: {
          componentName: 'RadioGroupSetter',
          props: {
            options: [
              {
                title: '单选',
                value: false,
              },
              {
                title: '多选',
                value: true,
              },
            ],
          },
        },
      },
      {
        name: 'dataOrigin',
        title: '数据来源',
        display: 'inline',
        setter: {
          componentName: 'RadioGroupSetter',
          props: {
            options: [
              { title: '远程请求', value: 'request' },
              { title: '静态数据', value: 'static' },
            ],
          },
        },
      },
      {
        name: 'requestConfig',
        title: '查询服务',
        display: 'inline',
        setter: {
          componentName: 'ServiceChoiceSetter',
          props: {
            mockDataTemplate: {
              success: true,
              data: [
                {
                  label: '选项一',
                  value: 'first',
                  children: [
                    {
                      label: '子选项一',
                      value: 'sub1',
                    },
                  ],
                },
                {
                  label: '选项二',
                  value: 'second',
                },
              ],
            },
            paramTitleDom: <div className=''>请求参数配置：</div>,
            responseDom: (
              <div style={{ paddingTop: '10px' }}>
                请求返回结果的数据结构：
                <a
                  target={'_blank'}
                  href='https://yuque.antfin.com/cn-framework-committee/cn-ui-data-structure/cn-async-select#iEuF0'
                >
                  接口文档
                </a>{' '}
                <CnTooltip v2 align={'t'} trigger={<a>接口预览</a>}>
                  <div style={{ width: '200px', height: '260px' }}>
                    <img
                      style={{ width: '100%' }}
                      src='https://img.alicdn.com/imgextra/i1/O1CN01W5SNFR25Fg4QyRC53_!!6000000007497-0-tps-456-570.jpg'
                    />
                  </div>
                </CnTooltip>
              </div>
            ),
            buttonText: '选择请求API',
            params: {
              env: 'pre',
              pageSize: 999,
              // serviceType: 'HSF',
            },
            extraConfigSetter,
            paramSetter: {
              componentName: 'MixedSetter',
              props: {
                setters: [
                  paramSelectSetter,
                  {
                    componentName: 'StringSetter',
                    title: '字符串',
                  },
                  jsExpressionPrototype,
                ],
              },
            },
            resultProcessFuncTemplate: `function(res) {
  // 需要返回的如下的数据结构
  // return {
  //   success: true,
  //   data: [
  //     {
  //        label:"xx",
  //        value:"xx",
  //     }
  //   ]
  // }
 return res;
}`,
            // paramSetter:{
            //   componentName: 'ParamSelectSetter',
            //   props:{
            //     dataKey: 'config',
            //     labelKey: 'label',
            //     valueKey: 'name',
            //     groupName: '参数列表',
            //   },
            //   title:'选择参数',
            // },
            executeProps,
            ...extraServiceProps,
          },
        },
        // hidden:hidden('Select'),
        condition(prop) {
          return (
            condition(prop, 'TreeSelect', 'componentName') &&
            prop?.parent?.getPropValue?.('dataOrigin') === 'request'
          );
        },
      },
      {
        name: 'dataSource',
        title: '编辑静态数据',
        display: 'plain',
        tip: '编辑静态展示数据',
        // initialValue: [],
        setter: getStaticDataSourceSnippet(),
        condition(prop) {
          return (
            condition(prop, 'TreeSelect', 'componentName') &&
            prop?.parent?.getPropValue?.('dataOrigin') === 'static'
          );
        },
      },
      getRequestWhenFocusSetterSnippet(),
      {
        name: 'searchRemote',
        title: '当新输入时 重新发请求',
        display: 'inline',
        tip: '开启时，每次输入都会重新发请求获取数据',
        setter: {
          componentName: 'BoolSetter',
          props: {},
        },
      },
      {
        name: 'searchKey',
        title: '远程搜索时的key',
        display: 'inline',
        setter: {
          componentName: 'StringSetter',
          props: {},
        },
        condition(prop) {
          return (
            condition(prop, 'TreeSelect', 'componentName') &&
            prop?.parent?.getPropValue?.('searchRemote') === true
          );
        },
      },
      {
        name: 'isOnlyLeafNodeSelectable',
        title: '只允许选中子节点',
        display: 'inline',
        setter: {
          componentName: 'BoolSetter',
          props: {},
        },
      },
      {
        name: 'showCheckAll',
        title: '支持全选',
        display: 'inline',
        setter: {
          componentName: 'RadioGroupSetter',
          props: {
            options: [
              { title: '是', value: true },
              { title: '否', value: false },
              { title: '不设置' },
            ],
          },
        },
        condition(prop) {
          return (
            condition(prop, 'TreeSelect', 'componentName') &&
            prop?.parent?.getPropValue?.('multiple') === true
          );
        },
      },
      {
        title: '多选时的额外配置项',
        name: 'multipleExtraProps',
        display: 'accordion',
        setter: {
          componentName: 'ObjectSetter',
          props: {
            config: {
              items: [
                {
                  name: 'treeCheckable',
                  title: '使用复选框勾选数据',
                  display: 'inline',
                  setter: 'BoolSetter',
                },
                {
                  name: 'treeCheckedStrategy',
                  title: '选中后的回填策略',
                  display: 'inline',
                  setter: {
                    componentName: 'SelectSetter',
                    props: {
                      options: [
                        {
                          label: '子节点都选中时只提交父节点',
                          value: 'parent',
                        },
                        {
                          label: '父子节点都选中时只提交子节点',
                          value: 'child',
                        },
                        {
                          label: '提交所有选中的节点',
                          value: 'all',
                        },
                      ],
                    },
                  },
                  condition(prop) {
                    return (
                      prop?.parent?.getPropValue?.('treeCheckable') === true
                    );
                  },
                },
              ],
            },
          },
        },
        condition(prop) {
          return (
            condition(prop, 'TreeSelect', 'componentName') &&
            prop?.parent?.getPropValue?.('multiple') === true
          );
        },
      },
    ];
  },
};

export default TreeSelect;
