import { Button, Col, Form, Input, message, Row, Select, Table, Tag } from 'antd';
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
import { forwardRef, useImperativeHandle, useState } from 'react';
import { filterObjAttr } from '~/utils';
import EditableCell from '~/components/EditableCell';

type EditableTableProps = Parameters<typeof Table>[0];
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
interface selfProps {
  tableData: any;
  updateTableData: (tableData: any) => void;
  defaultColumns: (ColumnTypes[number] & {
    editable?: boolean;
    dataIndex?: string;
    inputType?: string;
    radioOption?: { name: string; id: number }[];
    rules?: any;
    maxLength?: number;
    children?: any;
    placeholder?: string;
  })[];
  updateDefaultColumns: (
    columns: (ColumnTypes[number] & {
      editable?: boolean;
      dataIndex?: string;
      inputType?: string;
      radioOption?: { name: string; id: number }[];
      rules?: any;
      maxLength?: number;
      children?: any;
      placeholder?: string;
    })[],
  ) => void;
  uploadSuccess?: (record: any, fileList: any) => void; //可编辑表单存在上传图片的时候
  ref: any;
}

//规格表单数据类型
type specificationFormListType = {
  optionList: { label: string; value: string }[];
  id: number;
  name: string;
  addSpecificationValueShow: boolean;
  specificationValueList: { name: string; id: number; specificationName: string }[];
};

const CommonSkuInfo = forwardRef<any, selfProps>(
  ({ tableData, updateTableData, defaultColumns, updateDefaultColumns, uploadSuccess }, ref) => {
    //规格项表单
    const [form] = Form.useForm<{ [x: string]: string }>();
    //可编辑表格表单
    const [skuValueForm] = Form.useForm<{ [x: string]: string }>();

    //规格表单数组
    const [specificationFormList, setSpecificationFormList] = useState<specificationFormListType[]>(
      [
        {
          id: Math.random(),
          name: `specName`,
          optionList: [],
          specificationValueList: [],
          addSpecificationValueShow: false,
        },
      ],
    );

    useImperativeHandle(ref, () => ({
      getSpecificationForm: () => form,
      getSpecificationValueForm: () => skuValueForm,
      getSpecificationFormList: () => specificationFormList,
      updateSpecificationFormList: (value: specificationFormListType[]) =>
        setSpecificationFormList(value),
    }));

    //新增规格项目
    const addSpecificationClick = () => {
      setSpecificationFormList([
        ...specificationFormList,
        {
          id: Math.random(),
          name: `specName${specificationFormList.length + 1}`,
          optionList: [],
          specificationValueList: [],
          addSpecificationValueShow: false,
        },
      ]);
    };
    // 删除规格项目
    const deleteSpecificationClick = (index: number) => {
      form.setFieldValue(specificationFormList[index].name, undefined);
      specificationFormList.splice(index, 1);
      combineSpecificationValue();
      setSpecificationFormList([...specificationFormList]);
    };
    //规格项名称输入完成
    const specificationPressEnter = (e: any, index: number) => {
      specificationFormList[index].optionList = e.target.value
        ? [{ label: e.target.value, value: e.target.value }]
        : [];
      form.setFieldValue(specificationFormList[index].name, e.target.value);
      setSpecificationFormList([...specificationFormList]);
    };
    //规格值添加
    const addSpecificationValueClick = (index: number) => {
      specificationFormList[index].addSpecificationValueShow = true;
      setSpecificationFormList([...specificationFormList]);
    };
    //存在
    const specificationValuePressEnter = (e: any, index: number) => {
      const isExist = specificationFormList[index].specificationValueList.some(
        (v) => v.name === e.target.value,
      );
      if (isExist) {
        return message.warning('该规格值已存在');
      }
      specificationFormList[index].specificationValueList.push({
        id: Math.random(),
        name: e.target.value,
        specificationName: specificationFormList[index].optionList[0].value,
      });
      combineSpecificationValue();
      setSpecificationFormList(specificationFormList);
      specificationValueCancel(index);
    };
    //规格值添加-取消
    const specificationValueCancel = (index: number) => {
      specificationFormList[index].addSpecificationValueShow = false;
      setSpecificationFormList([...specificationFormList]);
    };
    //规格值-删除
    const specificationValueDelete = (i: number, j: number) => {
      specificationFormList[i].specificationValueList.splice(j, 1);
      combineSpecificationValue();
      setSpecificationFormList([...specificationFormList]);
    };
    //组合数据
    const combineSpecificationValue = () => {
      let combineSpecificationList: any = [];
      let tableDataList: any = [];
      //过滤规格值为空的
      const filterSpecificationFormList = specificationFormList.filter(
        (v) => v.specificationValueList.length,
      );
      if (filterSpecificationFormList.length > 1) {
        const combineList = filterSpecificationFormList.reduce((pre: any, cur, currentIndex) => {
          //  首次组合两个数据
          if (currentIndex === 0 && filterSpecificationFormList.length > 1) {
            combineSpecificationList = combineEvent(
              cur.specificationValueList,
              filterSpecificationFormList[currentIndex + 1].specificationValueList,
            );
            //二维数组拆分为对象
            combineSpecificationList = getCombineObj(combineSpecificationList);
            //  两个数据以上的组合
          } else if (
            currentIndex < filterSpecificationFormList.length - 1 &&
            filterSpecificationFormList[currentIndex + 1].specificationValueList.length
          ) {
            //  上一次的组合作为下一次组合的参数
            combineSpecificationList = combineEvent(
              combineSpecificationList,
              filterSpecificationFormList[currentIndex + 1].specificationValueList,
            );
            //二维数组拆分为对象
            combineSpecificationList = getCombineObj(combineSpecificationList);
          }
          pre = combineSpecificationList;
          return pre;
        }, []);
        tableDataList = combineList.reduce((pre: any, cur: any) => {
          const tabCovertObj = cur.reduce((a: any, b: any, currentIndex: number) => {
            a['name' + (currentIndex + 1)] = b.name;
            a['specificationName' + (currentIndex + 1)] = b.specificationName;
            return a;
          }, {});
          //判断表格中是否已存在该条（缓存）
          const tableItemObj = tableData.find((i: any) =>
            Object.getOwnPropertyNames(tabCovertObj).every((key) => i[key] === tabCovertObj[key]),
          );
          pre.push({
            ...tabCovertObj,
            id: tableItemObj ? tableItemObj.id : Math.random(), //存在则用之前的id，不存在新建id
            fileList: tableItemObj ? tableItemObj.fileList : [],
          });
          return pre;
        }, []);
      } else if (filterSpecificationFormList.length === 1) {
        //当存在一个规格项时
        tableDataList = filterSpecificationFormList[0].specificationValueList.map((v) => {
          const obj = Object.create(null);
          obj['name1'] = v.name;
          obj['specificationName1'] = v.specificationName;
          //判断表格中是否已存在该条（缓存）
          const tableItemObj = tableData.find((i: any) =>
            Object.getOwnPropertyNames(obj).every((key) => i[key] === obj[key]),
          );
          obj['id'] = Math.random();
          return tableItemObj ? tableItemObj : obj; //存在则用之前的一条，不存在新建一条
        });
      }
      if (tableDataList.length) {
        setTableFormDefault(tableDataList);
        mergeTableRow(filterSpecificationFormList);
      }
      updateTableData([...tableDataList]);
    };
    //组合数据拆分为对象
    const getCombineObj = (combineSpecificationList: any) => {
      return combineSpecificationList.reduce((pre: any, cur: any) => {
        pre.push(
          cur.reduce((a: any, b: any) => {
            if (Array.isArray(b)) {
              a.push(...b);
            } else {
              a.push({ ...b });
            }
            return a;
          }, []),
        );
        return pre;
      }, []);
    };

    //两数组排列组合（通用）
    const combineEvent = (list1: any, list2: any) => {
      return list1.reduce((pre: any, cur: any) => pre.concat(list2.map((v: any) => [cur, v])), []);
    };
    //表头拆分及合并列
    const mergeTableRow = (filterSpecificationFormList: specificationFormListType[]) => {
      const columns = filterSpecificationFormList.map((v, index) => ({
        title: v.optionList[0].value,
        dataIndex: 'name' + (index + 1),
        align: 'center',
        onCell: (_: any, i: number) => {
          //合并列
          if (index < filterSpecificationFormList.length - 1) {
            const count: number = filterSpecificationFormList
              .slice(index + 1, filterSpecificationFormList.length)
              .reduce((pre: number, cur) => {
                return pre * cur.specificationValueList.length;
              }, 1);
            return {
              rowSpan: count !== 1 ? ((i + 1) % count === 1 ? count : 0) : 1,
            };
          } else {
            return {
              rowSpan: 1,
            };
          }
        },
      }));
      defaultColumns[0].children = columns;
      updateDefaultColumns([...defaultColumns]);
    };
    //排列组合规格值表单默认数据
    const setTableFormDefault = (tableDataList: any) => {
      const tableFormDefault = tableDataList.reduce((pre: any, cur: any) => {
        return {
          ...pre,
          ...Object.getOwnPropertyNames(filterObjAttr(cur, ['id'])).reduce((a: any, b) => {
            a[b + cur.id] = cur[b];
            return a;
          }, {}),
        };
      }, {});
      skuValueForm.setFieldsValue(tableFormDefault);
    };
    const covertColumns = () => {
      return 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,
            placeholder: col.placeholder,
            maxLength: col.maxLength,
          }),
        };
      });
    };

    return (
      <div className='common-sku-info'>
        <Form wrapperCol={{ span: 5 }} labelCol={{ span: 1 }} form={form}>
          {specificationFormList.map((v, index) => (
            <div key={v.id}>
              {/*  规格项*/}
              <Row>
                <Col span={7}>
                  <Form.Item
                    label={'规格项' + (index + 1)}
                    wrapperCol={{ span: 18 }}
                    labelCol={{ span: 5 }}
                    name={v.name}
                    rules={[{ required: true, message: `请输入规格项${index + 1}` }]}
                  >
                    <Select
                      placeholder='请输入规格项，按回车键完成'
                      dropdownRender={(menu) => (
                        <>
                          {v.optionList.length ? menu : ''}
                          <Input
                            onPressEnter={(e) => specificationPressEnter(e, index)}
                            maxLength={30}
                          />
                        </>
                      )}
                      options={v.optionList}
                    />
                  </Form.Item>
                </Col>
                {index ? (
                  <Col span={2}>
                    <Button
                      danger
                      icon={<DeleteOutlined />}
                      onClick={() => deleteSpecificationClick(index)}
                    >
                      删除
                    </Button>
                  </Col>
                ) : (
                  ''
                )}
              </Row>
              {/*规格值显示*/}
              {v.specificationValueList.length ? (
                <Row style={{ marginBottom: '10px' }}>
                  <Col span={2}></Col>
                  <Col span={4}>
                    <div>
                      {v.specificationValueList.map((v, i) => (
                        <Tag key={v.id} closable onClose={() => specificationValueDelete(index, i)}>
                          {v.name}
                        </Tag>
                      ))}
                    </div>
                  </Col>
                </Row>
              ) : (
                ''
              )}

              {/*规格值操作*/}
              {v.optionList.length ? (
                <Row>
                  <Col span={2}></Col>
                  <Col span={4} style={{ marginBottom: '10px' }}>
                    {v.addSpecificationValueShow ? (
                      <Input
                        placeholder='请输入规格值，按回车键完成'
                        onPressEnter={(e) => specificationValuePressEnter(e, index)}
                        maxLength={30}
                      />
                    ) : (
                      <Button
                        type='link'
                        danger
                        icon={<PlusOutlined />}
                        onClick={() => addSpecificationValueClick(index)}
                      >
                        添加规格值
                      </Button>
                    )}
                  </Col>
                  {v.addSpecificationValueShow ? (
                    <Col>
                      <Button
                        type='primary'
                        style={{ marginLeft: '10px' }}
                        onClick={() => specificationValueCancel(index)}
                      >
                        取消
                      </Button>
                    </Col>
                  ) : (
                    ''
                  )}
                </Row>
              ) : (
                ''
              )}
            </div>
          ))}
          <Row>
            <Col span={2}></Col>
            <Col>
              <Button type='primary' icon={<PlusOutlined />} onClick={addSpecificationClick}>
                添加规格
              </Button>
            </Col>
          </Row>
        </Form>
        {tableData.length ? (
          <Form form={skuValueForm}>
            <Table
              style={{ marginTop: '10px' }}
              rowKey='id'
              columns={covertColumns() as ColumnTypes}
              components={{
                body: {
                  cell: EditableCell,
                },
              }}
              bordered
              dataSource={tableData}
              pagination={false}
              size='small'
            />
          </Form>
        ) : (
          ''
        )}
      </div>
    );
  },
);
export default CommonSkuInfo;
