import { Divider, Empty, Card } from "antd";
import {
  FormItem,
  Input,
  Select,
  NumberPicker,
  DatePicker,
  FormGrid,
  ArrayCards,
  ArrayItems,
  Space,
  Radio,
  PreviewText,
} from "@formily/antd-v5";
import { action } from "@formily/reactive";
import locale from "antd/es/date-picker/locale/zh_CN";

import {
  FileUploadField,
  InputAmountField,
  CopyField,
  SelectItemField,
  TreeSelectField,
  CascaderField,
  VerifyCodeField,
  AgreeRuleField,
  utils,
} from "@chuntianxiaozhu/adminreactcomps";
import { loadDictCache } from "@/data/cache";
import { MonthOptions } from "@/data/options";
import { ISchema, SchemaProperties } from "@formily/react";

const { formily, dataprocess } = utils;

/**
 * 转换数据
 * @param data
 * @param currentValue
 * @param bjObj
 */
export function transData(data, currentValue, bjObj) {
  if (data instanceof Array) {
    const result = data.map((item) => {
      // 如果是历史数据则不透出
      if (item.isHistory == 1) {
        return null;
      }
      const value = item.vlaue || item.dictKey;
      // 如果与当前值相同，说明当前值不是历史数据，正常透出，后续不再补充
      if (value == currentValue) {
        bjObj.isTarget = true;
      }
      if (item.subDict) {
        // 重新构建数据
        return {
          ...item,
          subDict: transData(item.subDict, currentValue, bjObj),
        };
      } else {
        // 重新构建数据
        return {
          ...item,
          children: transData(item.children, currentValue, bjObj),
        };
      }
    });
    return result.filter((item) => item != null);
  }
}

/**
 * 找到具有当前值的value
 * @param data
 * @param currentValue
 */
export function findCurrentTree(data, currentValue) {
  const finalResult: any[] = [];
  if (data instanceof Array) {
    for (let i = 0; i < data.length; i++) {
      const item = data[i];
      const value = item.value || item.dictKey;
      // 找到就直接返回元素
      if (
        value == currentValue ||
        (currentValue instanceof Array && currentValue.indexOf(value) > -1)
      ) {
        finalResult.push({ ...item });
      } else {
        // 还如果还有子元素则继续寻找,直到找到为止
        // eslint-disable-next-line no-lonely-if
        if (item.children) {
          const result = findCurrentTree(item.children, currentValue);
          if (result && result.length) {
            finalResult.push({
              ...item,
              children: result,
            });
          }
        } else if (item.subDict) {
          const result = findCurrentTree(item.subDict, currentValue);
          if (result && result.length) {
            finalResult.push({
              ...item,
              subDict: result,
            });
          }
        }
      }
    }
  }
  return finalResult;
}

/**
 * 不完全的一课树向一颗完全的树进行数据补充
 * @param originData
 * @param fillData
 */
export function fillTreeData(originData, fillData) {
  fillData.forEach((parentItem) => {
    const key = parentItem.value || parentItem.dictKey;
    const result = originData.find(
      (item) => item.value == key || item.dictKey == key
    );
    if (result) {
      if (parentItem.children && result.children) {
        fillTreeData(result.children, parentItem.children);
      }
      if (parentItem.subDict && result.subDict) {
        fillTreeData(result.subDict, parentItem.subDict);
      }
    } else {
      originData.push({ ...parentItem });
    }
  });
}

// 异步获取字典数据源，针对有dataSource的【下拉选择、级联选择、树形】,默认转换为label,value,extend...
export const useAsyncDataSource =
  (service, params, isTrans = true, level = 0) =>
  (field) => {
    field.loading = true;
    service(params).then(
      (action as any).bound((result) => {
        // 兼容
        if (result.code && result.data) {
          result = result.data;
        }
        let data = isTrans
          ? result.map((item) => ({
              label: item.dictValue,
              value: item.dictKey,
              extend: item.extend,
              isHistory: item.isHistory,
            }))
          : result;
        if (level > 0) {
          data = dataprocess.removeDataChildren(
            data,
            { label: "dictValue", value: "dictKey", children: "subDict" },
            2
          );
        }
        const currentValue = field.value;
        const bjObj: any = {};
        const filterData = transData(data, currentValue, bjObj);
        if (!bjObj.isTarget && currentValue) {
          const currentValueTree = findCurrentTree(data, currentValue);
          fillTreeData(filterData, currentValueTree || []);
        }
        field.dataSource = formily.mergeDataSource(field, filterData);
        field.loading = false;
      })
    );
  };

export const addUrl = (deps) => (field) => {
  const depValue = field.query(deps).take()?.value;
  if (depValue) {
    const value = depValue?.map(({ url, name, originFileName }) => ({
      url,
      originFileName: name || originFileName,
    }));
    field.setValue(value);
  }
};

const LocalDatePicker = (props) => <DatePicker {...props} locale={locale} />;
LocalDatePicker.RangePicker = (props) => {
  if (DatePicker.RangePicker) {
    return <DatePicker.RangePicker {...props} locale={locale} />;
  }
  return null;
};

export const components = {
  FormItem,
  Input,
  Card,
  FileUploader: FileUploadField,
  TreeSelect: TreeSelectField,
  Cascader: CascaderField,
  Select,
  NumberPicker,
  DatePicker: LocalDatePicker,
  FormGrid,
  ArrayCards,
  ArrayItems,
  Space,
  Radio,
  Divider,
  Empty,
  PreviewText,
  CopyField,
  InputAmount: InputAmountField,
  SelectItem: SelectItemField,
  VerifyCode: VerifyCodeField,
  AgreeRule: AgreeRuleField,
};

export const scope = {
  useAsyncDataSource, // 异步获取数据源
  addUrl,
  loadDictCache,
  // 有依赖项的异步获取数据
  dependsToOptions: (dep, service, data) => (field) => {
    const [realDep, realValue] =
      dep.indexOf("#") !== -1 ? dep.split("#") : [dep];
    const depFieldValue = field.query(realDep).take()?.value;
    const value = realValue ? depFieldValue?.[realValue] : depFieldValue;
    if (value) {
      field.loading = true;
      // 因为业务线用的是tree，所以这里要取0位
      service(data || (value?.[0] ? value[0] : value)).then(
        (action as any).bound((data) => {
          field.dataSource = data;
          field.loading = false;
        })
      );
    }
  },
};

export const schemaProps = {
  components,
  scope,
};

export default schemaProps;

/**
 * 交付月份
 */
export const deliveryMonthSchema = {
  title: "月份",
  type: "string",
  "x-decorator": "FormItem",
  "x-component": "Select",
  required: true,
  "x-component-props": {
    placeholder: "请选择交付月份",
  },
  enum: MonthOptions,
};

/**
 * formGroupTitle
 * @param title 标题文案
 * @param props Divider 组件参数（可覆盖默认的）
 * 基于 Divider
 */
export const getFormGroupTitleSchema = (title: string, props: any = {}) =>
  ({
    type: "void",
    "x-component": "Divider",
    "x-component-props": {
      children: title,
      className: "formGroupTitleWrap",
      orientationMargin: 0,
      orientation: "left",
      dashed: true,
      ...props,
    },
  } as ISchema);

/**
 * formGroupContent
 */
export const getFormGroupContentSchema = (schema: ISchema) => ({
  type: "void",
  "x-component": "FormGrid",
  "x-component-props": {
    minColumns: 3,
    maxColumns: 3,
    className: "formGroupContentWrap",
  },
  properties: schema,
});

// 外层，增加默认布局组件
export const generateLayoutSchema = (
  schema: SchemaProperties<any, any, any, any, any, any, any, any>,
  min = 3,
  max = 3
): ISchema => ({
  type: "object",
  "x-component": "FormGrid",
  "x-component-props": {
    minColumns: [min],
    maxColumns: [max],
  },
  properties: schema,
});
