import { Button, Form, Input, Modal, ModalProps, Radio, Select, Table } from 'antd';
import { FC, useEffect, useState } from 'react';
import EditableCell from '~/components/EditableCell';
import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
import { InterDataType, InterReqType } from '~/api/interface';
import { addMallGoodsType, skuUnitType } from '~/api/interface/goodsType';
import { filterObjAttr } from '~/utils';
import { isEmptyBol, regPriceNumber } from '~/utils/validateUtils';

type EditableTableProps = Parameters<typeof Table>[0];
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;

//商品sku规格类型
type goodsSpecType = Exclude<InterReqType<addMallGoodsType>, undefined>['goodsSpecList'][0];
//商品sku规格值类型
type goodsSpecValuesType = Exclude<
  InterReqType<addMallGoodsType>,
  undefined
>['goodsSpecList'][0]['goodsSpecValuesList'][0] & { fileList: any };
//单位返回类型
type unitType = InterDataType<skuUnitType>;

interface selfProps {
  onCancel: () => void;
  onHandleOk: (value: goodsSpecType) => void;
  skuUnitList: unitType;
  currentSku: goodsSpecType | undefined;
}

const SkuAddOrEditModal: FC<ModalProps & selfProps> = ({
  open,
  onCancel,
  onHandleOk,
  skuUnitList,
  currentSku,
}) => {
  const [goodsSpecForm] = Form.useForm<Omit<goodsSpecType, 'goodsSpecValuesList'>>();
  const [goodsSpecValuesForm] = Form.useForm<goodsSpecValuesType>();

  //销售正则价格校验
  const salePriceValidator = (_rules: any, value: number) => {
    if (!isEmptyBol(value)) {
      if (regPriceNumber(value.toString())) {
        return Promise.resolve();
      } else {
        return Promise.reject(new Error('为整数且最多保留两位小数'));
      }
    } else {
      return Promise.reject(new Error('请输入销售价'));
    }
  };
  //渠道正则价格校验
  const channelPriceValidator = (_rules: any, value: number) => {
    if (!isEmptyBol(value)) {
      if (regPriceNumber(value.toString())) {
        return Promise.resolve();
      } else {
        return Promise.reject(new Error('为整数且最多保留两位小数'));
      }
    } else {
      return Promise.resolve();
    }
  };
  //库存正则校验
  const stockPriceValidator = (_rules: any, value: number) => {
    if (!isEmptyBol(value)) {
      if (/^[+]{0,1}(\d+)$/.test(value.toString())) {
        return Promise.resolve();
      } else {
        return Promise.reject(new Error('请输入正整数'));
      }
    } else {
      return Promise.reject(new Error('请输入库存'));
    }
  };

  const [tableData, setTableData] = useState<goodsSpecValuesType[]>([
    {
      id: Math.random(),
      channelPrice: 0,
      partNo: '',
      salePrice: 0,
      showPrice: 1,
      specValueImage: '',
      specValueName: '',
      stock: 0,
      fileList: [],
    },
  ]);
  const defaultColumns: (ColumnTypes[number] & {
    editable?: boolean;
    dataIndex?: string;
    inputType?: string;
    radioOption?: { name: string; id: number }[];
    rules?: any;
    maxLength?: number;
  })[] = [
    {
      title: '序号',
      align: 'center',
      width: '5%',
      render: (_text: string, _record: any, index: number) => index + 1,
    },
    {
      title: '图片',
      align: 'center',
      editable: true,
      dataIndex: 'specValueImage',
      inputType: 'uploader',
    },
    {
      title: '选项名称',
      align: 'center',
      editable: true,
      dataIndex: 'specValueName',
      rules: [{ required: true, message: '请输入选项名称' }],
      maxLength: 30,
    },
    {
      title: '料号',
      align: 'center',
      editable: true,
      dataIndex: 'partNo',
      maxLength: 30,
    },
    {
      title: '销售价',
      align: 'center',
      editable: true,
      dataIndex: 'salePrice',
      rules: [{ required: true, validator: salePriceValidator }],
      inputType: 'number',
    },
    {
      title: '渠道价',
      editable: true,
      align: 'center',
      dataIndex: 'channelPrice',
      rules: [{ required: false, validator: channelPriceValidator }],
      inputType: 'number',
    },
    {
      title: '库存',
      editable: true,
      align: 'center',
      dataIndex: 'stock',
      rules: [{ required: true, validator: stockPriceValidator }],
      inputType: 'number',
    },
    {
      title: '是否显示',
      editable: true,
      align: 'center',
      dataIndex: 'showPrice',
      inputType: 'radio',
      width: '18%',
      radioOption: [
        { id: 1, name: '显示' },
        { id: 0, name: '不显示' },
      ],
    },
    {
      title: '操作',
      align: 'center',
      width: '10%',
      render: (_text: string, _record: any, index: number) => (
        <>
          {tableData.length - 1 === index ? (
            <Button
              type='primary'
              icon={<PlusOutlined />}
              onClick={addSkuDataRowClick}
              style={{ marginRight: '10px' }}
            ></Button>
          ) : (
            ''
          )}
          {index ? (
            <Button
              type='primary'
              icon={<MinusOutlined />}
              onClick={() => removeSkuDataRowClick(index)}
            ></Button>
          ) : (
            ''
          )}
        </>
      ),
    },
  ];
  const columns = defaultColumns.map((col) => {
    if (!col.editable) {
      return col;
    }
    return {
      ...col,
      onCell: (record: any) => ({
        record,
        dataIndex: col.dataIndex,
        title: col.title,
        editing: col.editable,
        radioOption: col.radioOption,
        inputType: col.inputType,
        uploadSuccess: col.inputType === 'uploader' ? uploadSuccess : undefined,
        rules: col.rules,
      }),
    };
  });
  const handleCancel = () => {
    clearForm();
    onCancel();
  };
  const clearForm = () => {
    goodsSpecForm.resetFields();
    goodsSpecValuesForm.resetFields();
    const list = [
      {
        id: Math.random(),
        channelPrice: 0,
        partNo: '',
        salePrice: 0,
        showPrice: 1,
        specValueImage: '',
        specValueName: '',
        stock: 0,
        fileList: [],
      },
    ];
    const obj = list.reduce((pre: any, cur: any) => {
      Object.getOwnPropertyNames(cur).forEach((key: string) => {
        if (['showPrice'].includes(key)) {
          pre[key + cur.id] = cur[key];
        }
      });
      return pre;
    }, {});
    goodsSpecValuesForm.setFieldsValue(obj);
    setTableData(list);
  };

  //新增一行规格值
  const addSkuDataRowClick = () => {
    const list = [
      ...tableData,
      {
        id: Math.random(),
        channelPrice: 0,
        partNo: '',
        salePrice: 0,
        showPrice: 1,
        specValueImage: '',
        specValueName: '',
        stock: 0,
        fileList: [],
      },
    ];
    setTableData(list);
    const obj = list.reduce((pre: any, cur: any) => {
      Object.getOwnPropertyNames(cur).forEach((key: string) => {
        if (['showPrice'].includes(key)) {
          pre[key + cur.id] = cur[key];
        }
      });
      return pre;
    }, {});
    goodsSpecValuesForm.setFieldsValue(obj);
  };
  //移除一行规格值
  const removeSkuDataRowClick = (index: number) => {
    tableData.splice(index, 1);
    setTableData([...tableData]);
  };

  //规格值上传图片返回
  const uploadSuccess = (record: goodsSpecValuesType, value: any) => {
    const tableIndex: number = tableData.findIndex((v) => v.id === record.id);
    goodsSpecValuesForm.setFieldValue('specValueImage' + record.id, value[0].url);
    if (tableIndex !== -1) {
      tableData[tableIndex].fileList = value;
      setTableData([...tableData]);
    }
  };
  //提交
  const handleOk = () => {
    Promise.all([goodsSpecForm.validateFields(), goodsSpecValuesForm.validateFields()]).then(
      (values: any) => {
        const goodsSpecValuesList: goodsSpecValuesType[] = tableData.map((v) => {
          return Object.getOwnPropertyNames(v).reduce((pre: any, cur: string) => {
            if (Object.getOwnPropertyNames(values[1]).includes(cur + v.id)) {
              pre[cur] = values[1][cur + v.id];
              pre.id = v.id;
            }
            return pre;
          }, {});
        });
        onHandleOk({ ...values[0], goodsSpecValuesList, id: currentSku?.id || Math.random() });
        clearForm();
      },
    );
  };

  useEffect(() => {
    const obj = tableData.reduce((pre: any, cur: any) => {
      Object.getOwnPropertyNames(cur).forEach((key: string) => {
        if (['showPrice'].includes(key)) {
          pre[key + cur.id] = cur[key];
        }
      });
      return pre;
    }, {});
    goodsSpecValuesForm.setFieldsValue(obj);
    if (currentSku) {
      goodsSpecForm.setFieldsValue(filterObjAttr(currentSku, ['goodsSpecValuesList']));
      setTableData(
        currentSku.goodsSpecValuesList.map((v: any) => ({
          ...v,
          fileList: v.specValueImage
            ? [
                {
                  id: Math.random(),
                  uid: Math.random(),
                  url: v.specValueImage,
                  name: 'specValueImage',
                },
              ]
            : [],
        })),
      );
      const goodsSpecValuesObj = currentSku.goodsSpecValuesList.reduce((pre: any, cur: any) => {
        Object.getOwnPropertyNames(cur)
          .filter((key: string) => key !== 'id')
          .forEach((key: string) => {
            pre[key + cur.id] = cur[key];
          });
        return pre;
      }, {});
      goodsSpecValuesForm.setFieldsValue(goodsSpecValuesObj);
    }
  }, [currentSku]);

  return (
    <Modal
      open={open}
      title={currentSku ? '编辑规格' : '添加规格'}
      width={1100}
      onCancel={handleCancel}
      onOk={handleOk}
    >
      <Form
        labelCol={{ span: 2 }}
        wrapperCol={{ span: 22 }}
        initialValues={{ chooseType: 0, must: 0, skuUnitId: skuUnitList[0]?.id || undefined }}
        form={goodsSpecForm}
      >
        <Form.Item
          label='规格名称'
          name='specName'
          rules={[{ required: true, message: '请输入规格名称' }]}
        >
          <Input placeholder='请输入规格名称' maxLength={30} />
        </Form.Item>
        <Form.Item label='规格值'>
          <Form component={false} form={goodsSpecValuesForm}>
            <Table
              rowKey='id'
              columns={columns as ColumnTypes}
              components={{
                body: {
                  cell: EditableCell,
                },
              }}
              bordered
              dataSource={tableData}
              pagination={false}
            ></Table>
          </Form>
        </Form.Item>
        <Form.Item label='选择方式' name='chooseType'>
          <Radio.Group>
            <Radio value={0}>单选</Radio>
            <Radio value={1}>多选</Radio>
          </Radio.Group>
        </Form.Item>
        <Form.Item label='是否必选' name='must'>
          <Radio.Group>
            <Radio value={0}>非必选</Radio>
            <Radio value={1}>必选</Radio>
          </Radio.Group>
        </Form.Item>
        <Form.Item
          label='规格单位'
          name='skuUnitId'
          rules={[{ required: true, message: '请选择规格单位' }]}
        >
          <Select placeholder='请选择规格单位'>
            {skuUnitList.map((v) => (
              <Select.Option value={v.id} key={v.id}>
                {v.unitName}
              </Select.Option>
            ))}
          </Select>
        </Form.Item>
      </Form>
    </Modal>
  );
};
export default SkuAddOrEditModal;
