import type { FormSchema } from '@/components/core/schema-form/';

import Api from '@/api';
import { debounce, isEmpty } from 'lodash-es';
import { MaterialsInOutEnum } from '@/enums/materialsInventoryEnum';
import { toRaw } from 'vue';
import { calcNumber } from '@/utils/common';
import { formatToDate } from '@/utils/dateUtil';
export const formSchemas = (isEdit?: boolean): FormSchema<API.MaterialsInOutEntity>[] => [
  {
    field: 'inOrOut',
    component: 'Select',
    label: '出入库',
    rules: [{ required: true, type: 'number' }],
    defaultValue: MaterialsInOutEnum.In,
    colProps: {
      span: 8,
    },
    componentProps: {
      allowClear: false,
      disabled: isEdit,
      options: [
        { label: '出库', value: MaterialsInOutEnum.Out },
        { label: '入库', value: MaterialsInOutEnum.In },
      ],
    },
  },
  {
    field: 'inventoryId',
    component: 'Select',
    label: '产品', //出口用
    rules: [{ required: true, type: 'number' }],
    vIf: ({ formModel }) => formModel.inOrOut === MaterialsInOutEnum.Out && !isEdit,
    colProps: {
      span: 24,
    },
    helpMessage:
      '出库必须选择某个价格的某个产品。因为库中的相同产品的价格，可能会不同（不同批次的产品）。另外在库存管理中会显示不同价格的相同产品。',
    componentProps: ({ formInstance, schema, formModel }) => ({
      showSearch: true,
      filterOption: false,
      disabled: isEdit,
      fieldNames: {
        label: 'label',
        value: 'value',
      },
      options: [],
      getPopupContainer: () => document.body,
      defaultActiveFirstOption: true,
      onClear: async () => {
        const newSchema = {
          field: schema.field,
          componentProps: {
            options: [] as LabelValueOptions,
          },
        };
        const options = await getInventories().finally(() => (schema.loading = false));
        newSchema.componentProps.options = options;
        formInstance?.updateSchema([newSchema]);
      },
      request: {
        watchFields: ['inOrOut'],
        options: {
          immediate: true,
        },
        callback: async ({ formModel }) => {
          if (formModel.inOrOut === MaterialsInOutEnum.Out) {
            return getInventories();
          } else {
            return Promise.resolve([] as LabelValueOptions);
          }
        },
      },
      onSelect: async (id: number) => {
        const data = await Api.materialsInventory.materialsInventoryInfo({
          id,
        });
        if (!isEmpty(data)) {
          const { project, unitPrice, quantity, product } = data as API.MaterialsInventoryEntity;
          const amount = calcNumber(unitPrice, quantity, 'multiply');
          formInstance?.setFieldsValue({
            projectId: project.id,
            productId: product.id,
            unitPrice,
            quantity,
            amount,
          });
          console.log(data, formModel);
        }
      },
      onSearch: debounce(async (keyword) => {
        schema.loading = true;
        const newSchema = {
          field: schema.field,
          componentProps: {
            options: [] as LabelValueOptions,
          },
        };
        formInstance?.updateSchema([newSchema]);
        const options = await getInventories(keyword).finally(() => (schema.loading = false));
        newSchema.componentProps.options = options;
        formInstance?.updateSchema([newSchema]);
      }, 500),
    }),
  },

  {
    field: 'productId',
    component: 'Select',
    vShow: ({ formModel }) => formModel.inOrOut === MaterialsInOutEnum.In || isEdit,
    label: '产品',
    colProps: {
      span: 16,
    },
    helpMessage: '如未找到对应产品，请先去产品管理添加产品。',
    rules: [{ required: true, type: 'number' }],
    componentProps: ({ formInstance, schema, formModel }) => ({
      showSearch: true,
      filterOption: false,
      disabled: isEdit,
      fieldNames: {
        label: 'label',
        value: 'value',
      },
      options: [],
      getPopupContainer: () => document.body,
      defaultActiveFirstOption: true,
      onClear: async () => {
        const newSchema = {
          field: schema.field,
          componentProps: {
            options: [] as LabelValueOptions,
          },
        };
        const options = await getProductOptions().finally(() => (schema.loading = false));
        newSchema.componentProps.options = options;
        formInstance?.updateSchema([newSchema]);
      },
      request: () => {
        return getProductOptions();
      },
      onSearch: debounce(async (keyword) => {
        schema.loading = true;
        const newSchema = {
          field: schema.field,
          componentProps: {
            options: [] as LabelValueOptions,
          },
        };
        formInstance?.updateSchema([newSchema]);
        const options = await getProductOptions(keyword).finally(() => (schema.loading = false));
        newSchema.componentProps.options = options;
        formInstance?.updateSchema([newSchema]);
      }, 500),
    }),
  },
  {
    field: 'projectId',
    component: 'Select',
    label: '项目',
    colProps: {
      span: 12,
    },
    vIf: ({ formModel }) =>
      formModel.inOrOut === MaterialsInOutEnum.In || isEdit || formModel.inventoryId,
    rules: [{ required: true, type: 'number' }],
    helpMessage: '如未找到对应项目，请先去项目管理添加项目。出库时选择的项目可以入库时不同',
    componentProps: ({ formInstance, schema, formModel }) => ({
      // disabled: Object.is(formModel.inOrOut, MaterialsInOutEnum.Out) || isEdit,
      showSearch: true,
      filterOption: false,
      fieldNames: {
        label: 'label',
        value: 'value',
      },
      getPopupContainer: () => document.body,
      defaultActiveFirstOption: true,
      onClear: async () => {
        const newSchema = {
          field: schema.field,
          componentProps: {
            options: [] as LabelValueOptions,
          },
        };
        const options = await getProjectOptions().finally(() => (schema.loading = false));
        newSchema.componentProps.options = options;
        formInstance?.updateSchema([newSchema]);
      },
      request: () => {
        return getProjectOptions();
      },
      onSearch: debounce(async (keyword) => {
        schema.loading = true;
        const newSchema = {
          field: schema.field,
          componentProps: {
            options: [] as LabelValueOptions,
          },
        };
        formInstance?.updateSchema([newSchema]);
        const options = await getProjectOptions(keyword).finally(() => (schema.loading = false));
        newSchema.componentProps.options = options;
        formInstance?.updateSchema([newSchema]);
      }, 500),
    }),
  },
  {
    label: '时间',
    field: 'time',
    component: 'DatePicker',
    defaultValue: formatToDate(new Date()),
    colProps: {
      span: 12,
    },
    componentProps: {
      valueFormat: 'YYYY-MM-DD',
    },
  },
  {
    label: '数量',
    helpMessage: ({ formModel }) => {
      return '出库时，选择产品后显示的数量为实时的库存剩余数量。';
    },
    field: 'quantity',
    component: 'InputNumber',
    colProps: {
      span: 12,
    },
    rules: [{ required: true, type: 'number', min: 1 }],
    componentProps: ({ formInstance, formModel }) => ({
      disabled: isEdit,
      onBlur(e) {
        const { quantity, unitPrice, amount, inOrOut } = toRaw(formModel);
        // 出库只关心数量，单价已经有了，直接算出出库金额
        if (MaterialsInOutEnum.Out === inOrOut) {
          if (unitPrice) {
            formInstance?.setFieldsValue({
              amount: calcNumber(unitPrice, quantity, 'multiply'),
            });
          }
        } else {
          // 入库一般是先输入总价和数量，然后计算单价
          if (amount) {
            formInstance?.setFieldsValue({
              unitPrice: calcNumber(amount, quantity, 'divide'),
            });
          } else if (unitPrice) {
            formInstance?.setFieldsValue({
              amount: calcNumber(unitPrice, quantity, 'multiply'),
            });
          }
        }
      },
    }),
  },
  {
    label: '单价',
    field: 'unitPrice',
    component: 'InputNumber',
    colProps: {
      span: 12,
    },
    helpMessage: ({ formModel }) => {
      return '出库时，单价不可更改，如需修改单价，请找到入库记录进行修改。';
    },
    dynamicDisabled: ({ formModel }) => {
      return formModel.inOrOut === MaterialsInOutEnum.Out;
    },
    componentProps: ({ formInstance, formModel }) => ({
      disabled: isEdit,
      onBlur(e) {
        const { quantity, unitPrice } = toRaw(formModel);
        if (quantity) {
          formInstance?.setFieldsValue({
            amount: calcNumber(unitPrice, quantity, 'multiply'),
          });
        }
      },
    }),
  },
  {
    label: '金额',
    field: 'amount',
    component: 'InputNumber',
    colProps: {
      span: 12,
    },
    helpMessage: ({ formModel }) => {
      return '出库时，金额不可更改，输入数量会自动计算。';
    },
    dynamicDisabled: ({ formModel }) => {
      return formModel.inOrOut === MaterialsInOutEnum.Out;
    },
    componentProps: ({ formInstance, formModel }) => ({
      disabled: isEdit,
      onBlur(e) {
        const { quantity, amount } = toRaw(formModel);
        if (quantity) {
          formInstance?.setFieldsValue({
            unitPrice: calcNumber(amount, quantity, 'divide'),
          });
        }
      },
    }),
  },
  {
    label: '经办人',
    field: 'agent',
    component: 'Input',
    colProps: {
      span: 12,
    },
  },
  {
    label: '领料单号',
    field: 'issuanceNumber',
    component: 'Input',
    vIf: ({ formModel }) => formModel.inOrOut === MaterialsInOutEnum.Out,
    colProps: {
      span: 12,
    },
  },

  {
    label: '备注',
    field: 'remark',
    component: 'InputTextArea',
  },
];

export const getProjectOptions = async (keyword?: string): Promise<LabelValueOptions> => {
  const { items: result } = await Api.project.projectList({ pageSize: 100, name: keyword });
  return (
    result?.map((item) => ({
      label: `${item.name}`,
      value: item.id,
    })) || []
  );
};

const getProductOptions = async (keyword?: string): Promise<LabelValueOptions> => {
  const { items: result } = await Api.product.productList({ pageSize: 100, keyword: keyword });
  return (
    result?.map((item) => ({
      label: ` ${item.name} ${item.productNumber ? `(${item.productNumber})` : ''} ${item.company?.name ? `(${item.company?.name})` : ''} `,
      value: item.id,
    })) || []
  );
};

const getInventoryNumberOptions = async (
  inventoryInOutNumber?: string,
): Promise<LabelValueOptions> => {
  const { items: result } = await Api.materialsInOut.materialsInOutList({
    inventoryInOutNumber,
    isCreateOut: true,
    pageSize: 100,
  });
  return (
    result?.map((item) => ({
      label: `${item.inventoryInOutNumber} (${item.project?.name || '-'}) (${item.product?.company?.name || '-'}) (${item.product?.name || '-'})`,
      value: item.inventoryInOutNumber,
    })) || []
  );
};
const getInventories = async (keyword?: string): Promise<LabelValueOptions> => {
  const { items: result } = await Api.materialsInventory.materialsInventoryList({
    keyword,
    isCreateInout: true,
    pageSize: 100,
  });
  return (
    result?.map((item) => ({
      label: `${item.product?.name} (￥${parseFloat(item.unitPrice)}) (${item.product?.company?.name || '-'})  (${item.project?.name || '-'}) `,
      value: item.id,
    })) || []
  );
};
