import {
  DeleteOutlined,
  PlusSquareOutlined,
  UploadOutlined,
} from '@ant-design/icons';
import {
  ModalForm,
  ProForm,
  ProFormDependency,
  ProFormDigit,
  ProFormRadio,
  ProFormSelect,
  ProFormText,
  ProFormSwitch,
} from '@ant-design/pro-components';
import { Button, Col, Drawer, Row, Space, message } from 'antd';
import React, { useEffect, useState, PropsWithChildren } from 'react';
import Icon, { IconImg } from '../../../components/Icon';
import Truly from '../../../components/Truly';
import Upload from '../../../components/Upload';
import { OPTIONS } from '../../../constants';
import FileImageSelect from '../../../pages/File/Select';
import {
  FileController,
  MenuController,
  CommonController,
  types,
} from '../../../services';
import {
  clearSvgColor,
  decodeHtml,
  encodeHtml,
  getPureSvgText,
  getSvgText,
  isSvg,
} from '../../../utils/html';

interface EditFormProps {
  title: string;
  type: 'add' | 'update' | 'add-child';
  initialValues?: MenuController.MenuFields;
  initailParentValues?: MenuController.MenuFields;
  appId?: MenuController.MenuFields['menuId'];
  appList: types.SelectOptionFields[];
  onOk?: () => void;
  tableList?: MenuController.MenuFields[];
}

const EditForm: React.FC<PropsWithChildren<EditFormProps>> = ({
  title,
  type,
  initialValues,
  initailParentValues,
  appId,
  tableList,
  appList,
  onOk,
  children,
}) => {
  const [form] = ProForm.useForm();
  const [openFile, setOpenFile] = useState(false);
  const [open, setOpen] = useState(false);
  const [buttonList, setButtonList] = useState<types.SelectOptionFields[]>([]);
  const [menuTypes, setMenuTypes] = useState<OPTIONS.OptionFields[]>([]);

  const [icon, setIcon] = useState('');
  useEffect(() => {
    setIcon(decodeHtml(initialValues?.icon || ''));
  }, [initialValues]);

  const onUpload = async (files: any) => {
    const [file] = files || [];
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      message.error('图片最大不超过2MB!');
      throw new Error('error');
    }
    const forms = new FormData();
    forms.append('type', '0');
    forms.append('picType', '1');
    forms.append('file', file);
    forms.append('isSvg', '2');
    const ret = await FileController.uploadApi(forms);
    setIcon(ret.data?.url || '');
  };

  const onUploadSvg = async (files: any) => {
    const [file] = files || [];
    const svgText = await getSvgText(file);
    const isSvgFlag = isSvg(svgText);
    if (!isSvgFlag) {
      message.error('svg图片格式有误!');
      throw new Error('error');
    }
    const fileContent = clearSvgColor(getPureSvgText(svgText));
    const forms = new FormData();
    forms.append('type', '0');
    forms.append('picType', '1');
    forms.append('fileContent', fileContent);
    forms.append('isSvg', '1');
    await FileController.uploadApi(forms);
    setIcon(fileContent);
  };

  return (
    <>
      <ModalForm
        layout="horizontal"
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 14 }}
        title={title}
        trigger={children as JSX.Element}
        form={form}
        autoFocusFirstInput
        open={open}
        modalProps={{
          destroyOnClose: true,
          onCancel: () => setOpen(false),
        }}
        submitTimeout={2000}
        onFinish={async (values) => {
          const { menuType, perms, menuName: preMenuName } = values || {};
          const encodeIcon = encodeHtml(icon);
          const { status: _status } = values || {};
          const status = String(2 - Number(_status));
          // 当按钮时需要特别处理
          let menuName = preMenuName;
          if (menuType === 'F') {
            const { label } =
              buttonList?.find((item) => item.value === perms) || {};
            menuName = label;
          }
          if (type === 'add' || type === 'add-child') {
            const { menuId: parentId = '' } = initailParentValues || {};
            await MenuController.addApi({
              ...values,
              parentId,
              icon: encodeIcon,
              menuName,
              status,
            });
          } else if (type === 'update') {
            await MenuController.updateApi({
              ...values,
              menuId: initialValues?.menuId,
              icon: encodeIcon,
              menuName,
              status,
            });
          }
          setIcon('');
          onOk?.();
          return true;
        }}
        onOpenChange={async (open) => {
          if (!open) return;
          if (type === 'add') {
            setButtonList([]);
            setMenuTypes([
              {
                value: 'M',
                label: '目录',
              },
              {
                value: 'C',
                label: '菜单',
              },
            ]);
            form.setFieldValue('menuType', 'M');
          } else if (type === 'add-child') {
            if (['C'].includes(initailParentValues?.menuType || '')) {
              const buttonList = await CommonController.getButtonSelectApi({
                menuPath: initailParentValues?.path,
              });
              setButtonList(buttonList);
            }
            setMenuTypes(() => {
              if (initailParentValues?.menuType === 'M') {
                form.setFieldValue('menuType', 'M');
                return [
                  {
                    value: 'M',
                    label: '目录',
                  },
                  {
                    value: 'C',
                    label: '菜单',
                  },
                ];
              } else if (initailParentValues?.menuType === 'C') {
                form.setFieldValue('menuType', 'F');
                return [
                  {
                    value: 'F',
                    label: '按钮',
                  },
                ];
              }
              return [];
            });
          } else {
            if (['C'].includes(initialValues?.menuType || '')) {
              const buttonList = await CommonController.getButtonSelectApi({
                menuPath: initialValues?.path,
              });
              setButtonList(buttonList);
            } else if (['F'].includes(initialValues?.menuType || '')) {
              const find = (tableList || []).find(
                (item) => item.menuId === initialValues?.parentId,
              );
              const buttonList = await CommonController.getButtonSelectApi({
                menuPath: find?.path,
              });
              setButtonList(buttonList);
            }
            setMenuTypes([
              {
                value: 'M',
                label: '目录',
              },
              {
                value: 'C',
                label: '菜单',
              },
              {
                value: 'F',
                label: '按钮',
              },
            ]);
            const { status: _status } = initialValues || {};
            const status = Boolean(2 - Number(_status));
            form.setFieldsValue({ ...initialValues, status });
          }
        }}
      >
        <ProFormSelect
          disabled
          name="appId"
          label="应用名称"
          options={appList}
          initialValue={appId}
          rules={[
            {
              required: true,
            },
          ]}
        />
        <ProFormRadio.Group
          disabled={type === 'update'}
          name="menuType"
          label="类型"
          options={menuTypes || []}
        />

        <ProFormDependency name={['menuType']}>
          {({ menuType }) => {
            if (['M', 'C'].includes(menuType)) {
              return (
                <Row style={{ marginBottom: 24 }}>
                  <Col
                    span={6}
                    style={{ textAlign: 'right', lineHeight: '32px' }}
                  >
                    图标：
                  </Col>
                  <Col span={14}>
                    <Space>
                      <Truly
                        truly={isSvg(icon)}
                        falsyRender={<IconImg url={icon} width={16}></IconImg>}
                      >
                        <Icon svg={icon} size={16}></Icon>
                      </Truly>
                      <Upload
                        accept="image/*"
                        onUpload={onUpload}
                        trigger={
                          <Button
                            type="link"
                            icon={<UploadOutlined />}
                            style={{ padding: 4 }}
                          >
                            上传图片
                          </Button>
                        }
                      ></Upload>
                      <Upload
                        accept="image/svg+xml"
                        onUpload={onUploadSvg}
                        trigger={
                          <Button
                            type="link"
                            icon={<UploadOutlined />}
                            style={{ padding: 4 }}
                          >
                            上传SVG
                          </Button>
                        }
                      ></Upload>
                      <Button
                        type="link"
                        icon={<PlusSquareOutlined />}
                        style={{ padding: 4 }}
                        onClick={() => setOpenFile(true)}
                      >
                        图标库
                      </Button>
                      <Truly truly={!!icon}>
                        <Button
                          type="link"
                          danger
                          icon={<DeleteOutlined />}
                          style={{ padding: 4 }}
                          onClick={() => setIcon('')}
                        >
                          清除
                        </Button>
                      </Truly>
                    </Space>
                  </Col>
                </Row>
              );
            }
          }}
        </ProFormDependency>
        <ProFormDependency name={['menuType']}>
          {({ menuType }) => {
            if (['F'].includes(menuType)) {
              return (
                <ProFormSelect
                  name="perms"
                  label="名称"
                  options={buttonList || []}
                  rules={[
                    {
                      required: true,
                    },
                  ]}
                />
              );
            }
            return (
              <ProFormText
                name="menuName"
                label="名称"
                rules={[
                  {
                    required: true,
                  },
                ]}
              />
            );
          }}
        </ProFormDependency>

        <ProFormDigit
          name="orderNum"
          label="显示顺序"
          rules={[
            {
              required: true,
            },
          ]}
        />
        <ProFormDependency name={['menuType']}>
          {({ menuType }) => {
            if (['C'].includes(menuType)) {
              return (
                <ProFormText
                  name="path"
                  label="路由地址"
                  rules={[
                    {
                      required: true,
                    },
                  ]}
                />
              );
            }
            return null;
          }}
        </ProFormDependency>
        <ProFormSwitch label="菜单状态" name="status" initialValue={true} />
      </ModalForm>
      <Drawer
        title="选择图片"
        open={openFile}
        onClose={() => setOpenFile(false)}
        width={800}
        destroyOnClose
      >
        <FileImageSelect
          picType="1"
          onSelect={(pick) => {
            const pic = pick.isSvg === '1' ? pick.fileContent : pick.filePath;
            setIcon(pic || '');
            setOpenFile(false);
          }}
        ></FileImageSelect>
      </Drawer>
    </>
  );
};

export default EditForm;
