import { postDeviceGroupGetDeviceGroupTree } from '@/services/device/DeviceGroup';
import { postProjectCreateProject } from '@/services/project/Project';
import { postAlgorithmModelGetAlgorithmModelFkSelect } from '@/services/resource/AlgorithmModel';
import { beforeUploadFile } from '@/utils/common';
import { CloseOutlined, SnippetsOutlined } from '@ant-design/icons';
import type { ProFormInstance } from '@ant-design/pro-components';
import {
  ProCard,
  ProForm,
  ProFormList,
  ProFormSwitch,
  ProFormText,
  ProFormUploadDragger,
  StepsForm,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Modal, Switch, Transfer, Tree, UploadFile, message } from 'antd';
import type { TransferDirection } from 'antd/es/transfer';
import { DataNode } from 'antd/es/tree';
import React, { useEffect, useRef, useState } from 'react';
// @ts-ignore
import { FormListActionType } from '@ant-design/pro-form/lib';
import yaml from 'js-yaml';
// @ts-ignore
import cookie from 'react-cookies';
import { proFormItemStyleProps } from '../../../../../config/defaultForm';

interface RecordType {
  key: string;
  title: string;
  description: string;
  chosen: boolean;
}

interface ProjectConfig {
  params: Array<object>;
}

export type FormValueType = {
  target?: string;
  template?: string;
  type?: string;
  time?: string;
  frequency?: string;
} & Partial<API.Project>;

export type CreateFormProps = {
  createModalOpen: boolean;
  handleModal: () => void;
  values: Partial<API.Project>;
  reload: any;
};
const waitTime = (time: number = 100) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(true);
    }, time);
  });
};

/**styles 配置 */

const MyCreateForm: React.FC<CreateFormProps> = (props) => {
  const [treeData, setTreeData] = React.useState<DataNode[]>([]);
  const [modalData, setModalData] = useState<RecordType[]>([]);
  const [targetKeys, setTargetKeys] = useState<string[]>([]);
  const [selectKeys, setSelectKeys] = useState([]);
  const [filePath, setFilePath] = useState('');
  const [configData, setConfigData] = useState<ProjectConfig>({ params: [] });
  const intl = useIntl();
  const [isAuto, setIsAuto] = useState(true);
  const formRef = useRef<ProFormInstance>();
  const formRef3 = useRef<ProFormInstance>();
  const [current, setCurrent] = useState(0);

  const [dataFormList, setDataFormList] = useState<any>([]);
  const dataFormListRef = useRef(dataFormList);
  const [fileList, setFileList] = useState<UploadFile<any>[]>([]);

  const actionFormListRef = useRef<
    FormListActionType<{
      name: string;
    }>
  >();
  const handleFileChange = ({ file }: { file: UploadFile }) => {
    let curFile: any;

    switch (file.status) {
      case 'uploading':
      case 'done':
        curFile = [file];
        break;

      case 'removed':
      default:
        curFile = [];
        break;
    }

    setFileList([...curFile]);
  };

  const getModelData = () => {
    postAlgorithmModelGetAlgorithmModelFkSelect({ keyword: '' }).then((res) => {
      let result = (res.data?.list || []).map((v: any) => {
        return {
          key: v.id,
          title: v.name,
          chosen: false,
        };
      });
      setModalData(result);
    });
    // setMockData(tempMockData);
    // setTargetKeys(tempTargetKeys);
  };

  const handleChange = (newTargetKeys: string[]) => {
    setTargetKeys(newTargetKeys);
  };
  useEffect(() => {
    setTargetKeys([]);
    if (props.createModalOpen) {
      getModelData();
      postDeviceGroupGetDeviceGroupTree()
        .then((resp: API.Response) => {
          setTreeData(resp.data.tree);
        })
        .catch(() => {});
    } else {
      formRef.current?.resetFields();
    }
  }, [props.createModalOpen]);
  const handleSearch = (dir: TransferDirection, value: string) => {
    postAlgorithmModelGetAlgorithmModelFkSelect({ keyword: value }).then((res) => {
      let result = (res.data?.list || []).map((v: any) => {
        return {
          key: v.id,
          title: v.name,
          chosen: false,
        };
      });
      setModalData(result);
    });
  };
  return (
    <div className="gn">
      <StepsForm<{
        name: string;
      }>
        stepsProps={{
          labelPlacement: 'vertical',
        }}
        current={current}
        onCurrentChange={setCurrent}
        onFinish={async () => {
          setFileList([]);
          let formData = formRef.current?.getFieldsValue();
          if (formData?.name) {
            formData.inferConfig = { models: targetKeys, params: configData?.params || [] };
            formData.groupIds = selectKeys;
            formData.projectFilePath = filePath;
            postProjectCreateProject(formData)
              .then(() => {
                message.success(
                  intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' }),
                );
                props.handleModal();
                props.reload();
              })
              .catch(() => {
                message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' }));
                return false;
              });
          }
          return true;
        }}
        formProps={{
          validateMessages: {
            required: '此项为必填项',
          },
        }}
        stepsFormRender={(dom, submitter) => {
          return (
            <Modal
              title="分步表单"
              width={803}
              onCancel={() => {
                setCurrent(0);
                setFileList([]);
                formRef.current?.resetFields();
                formRef3.current?.resetFields();
                props.handleModal();
              }}
              open={props.createModalOpen}
              footer={submitter}
              destroyOnClose
            >
              {dom}
            </Modal>
          );
        }}
      >
        {/* 创建项目数据 */}
        <StepsForm.StepForm<{
          name: string;
        }>
          name="base"
          formRef={formRef}
          title="创建项目数据"
          stepProps={{
            description: '这里填入项目基本信息',
          }}
          onFinish={async () => {
            // setFormData(formRef.current?.getFieldsValue());
            await waitTime(500);
            return true;
          }}
        >
          <ProForm.Group>
            <ProFormText
              {...proFormItemStyleProps}
              name="name"
              label={<FormattedMessage id="project.project.table.list.name" defaultMessage="$$$" />}
              placeholder={`${intl.formatMessage({
                id: 'common.please_input',
                defaultMessage: '$$$',
              })}${intl.formatMessage({
                id: 'project.project.table.list.name',
                defaultMessage: '$$$',
              })}`}
              required={true}
              rules={[
                {
                  required: true,
                  message: (
                    <FormattedMessage
                      id="project.project.table.rule.required.name"
                      defaultMessage="name is required"
                    />
                  ),
                },
              ]}
            />
            <ProFormText
              width={680}
              name="code"
              label={<FormattedMessage id="project.project.table.list.code" defaultMessage="$$$" />}
              placeholder={`${intl.formatMessage({
                id: 'common.please_input',
                defaultMessage: '$$$',
              })}${intl.formatMessage({
                id: 'project.project.table.list.code',
                defaultMessage: '$$$',
              })}`}
              required={!isAuto}
              initialValue=""
              disabled={isAuto}
              rules={
                isAuto
                  ? []
                  : [
                      {
                        required: true,
                        message: (
                          <FormattedMessage
                            id="project.project.table.rule.required.code"
                            defaultMessage="code is required"
                          />
                        ),
                      },
                    ]
              }
              addonAfter={
                <Switch
                  checked={isAuto}
                  checkedChildren={<FormattedMessage id="common.auto" defaultMessage="$$$" />}
                  unCheckedChildren={<FormattedMessage id="common.edit" defaultMessage="$$$" />}
                  onChange={setIsAuto}
                />
              }
            />
            <ProFormText
              {...proFormItemStyleProps}
              name="info"
              label={<FormattedMessage id="project.project.table.list.info" defaultMessage="$$$" />}
              placeholder={`${intl.formatMessage({
                id: 'common.please_input',
                defaultMessage: '$$$',
              })}${intl.formatMessage({
                id: 'project.project.table.list.info',
                defaultMessage: '$$$',
              })}`}
              required={true}
              rules={[
                {
                  required: true,
                  message: (
                    <FormattedMessage
                      id="project.project.table.rule.required.info"
                      defaultMessage="info is required"
                    />
                  ),
                },
              ]}
            />
            <ProFormText
              {...proFormItemStyleProps}
              name="remark"
              label={
                <FormattedMessage id="project.project.table.list.remark" defaultMessage="$$$" />
              }
              placeholder={`${intl.formatMessage({
                id: 'common.please_input',
                defaultMessage: '$$$',
              })}${intl.formatMessage({
                id: 'project.project.table.list.remark',
                defaultMessage: '$$$',
              })}`}
              required={false}
            />
          </ProForm.Group>
          <ProForm.Group>
            <ProFormSwitch
              width="lg"
              name="isEnable"
              label={
                <FormattedMessage id="project.project.table.list.isEnable" defaultMessage="$$$" />
              }
              initialValue={true}
            />
          </ProForm.Group>
        </StepsForm.StepForm>
        {/* 关联算法模型 */}
        <StepsForm.StepForm<{
          model: string;
        }>
          name="model"
          title="关联算法模型"
          stepProps={{
            description: '选择算法模型',
          }}
          onFinish={async () => {
            return true;
          }}
        >
          <Transfer
            dataSource={modalData}
            showSearch
            titles={['未选模型', '已选模型']}
            locale={{ itemUnit: '项', itemsUnit: '项', searchPlaceholder: '请输入搜索内容' }}
            targetKeys={targetKeys}
            onChange={handleChange}
            onSearch={handleSearch}
            style={{ marginBottom: '20px' }}
            listStyle={{ width: 289, height: 300 }}
            operationStyle={{ width: 100, alignItems: 'center' }}
            render={(item) => item.title}
          />
        </StepsForm.StepForm>
        {/* 上传业务代码 */}
        <StepsForm.StepForm<{
          project_file: string;
        }>
          name="project_file"
          title="上传业务代码"
          style={{ width: proFormItemStyleProps.width }}
          stepProps={{
            description: '上传业务代码格式为(.zip,.tar.gz)',
          }}
          onFinish={async (values: any) => {
            if ('projectFilePath' in values && values['projectFilePath'].length > 0) {
              let projectFilePath = values['projectFilePath'][0]?.response?.data?.path || '';
              setFilePath(projectFilePath);
            }
            return true;
          }}
        >
          <ProFormUploadDragger
            label="上传文件"
            name="projectFilePath"
            action="/api/v1/file/uploadFile"
            max={1}
            fieldProps={{
              name: 'file',
              beforeUpload: beforeUploadFile,
              data: { path: 'project/files' },
              headers: {
                'X-CSRFToken': cookie.load('csrftoken'),
                Authorization: `Bearer ${localStorage.getItem('access') || ''}`,
              },
            }}
          />
        </StepsForm.StepForm>
        {/* 业务参数配置 */}
        <StepsForm.StepForm<{
          config: string;
        }>
          name="config"
          title="业务参数配置"
          stepProps={{
            description: '业务参数配置',
          }}
          onFinish={async (values: any) => {
            setConfigData(values);
            return true;
          }}
        >
          {/* <Icon type="delete" /> */}
          {/* TODO 图标需要替换 */}

          <ProFormUploadDragger
            max={1}
            label="配置文件上传"
            value={fileList}
            name="dragger"
            fieldProps={{
              onChange: handleFileChange,
              onRemove: () => {
                let index_ids = actionFormListRef.current?.getList()?.map((v, i) => {
                  return i;
                });
                actionFormListRef.current?.remove(index_ids || []);
              },
              beforeUpload: (file, fileList) => {
                if (
                  !file.name.endsWith('.yaml') &&
                  !file.name.endsWith('.yml') &&
                  !file.name.endsWith('.json')
                ) {
                  message.error('请上传yaml或json文件').then(() => {});
                  return false;
                } else {
                  let parsedData = {};
                  file
                    .text()
                    .then((text) => {
                      if (file.name.endsWith('.yaml') || file.name.endsWith('.yml')) {
                        parsedData = yaml.load(text) as Record<string, unknown>;
                      }
                      if (file.name.endsWith('.json')) {
                        parsedData = JSON.parse(text) as Record<string, unknown>;
                      }
                      if (Object.keys(parsedData).length > 0) {
                        dataFormListRef.current = Object.entries(parsedData).map(
                          ([key, value]) => ({
                            name: key,
                            default: value,
                          }),
                        );

                        dataFormListRef.current.forEach((v: any, i: number) => {
                          actionFormListRef.current?.add(v, i);
                        });
                      }
                      return true;
                    })
                    .catch(() => {
                      return false;
                    });
                }
              },
            }}
          />
          <ProFormList
            style={{ width: proFormItemStyleProps.width }}
            actionRef={actionFormListRef}
            copyIconProps={{
              Icon: SnippetsOutlined,
            }}
            deleteIconProps={{
              Icon: CloseOutlined,
            }}
            name="params"
            label="模型参数"
          >
            {(f, index, action) => {
              return (
                <ProCard style={{ padding: 0, margin: 0 }} bodyStyle={{ padding: 0, margin: 0 }}>
                  <ProCard
                    style={{ padding: 0, margin: 0 }}
                    bodyStyle={{ padding: 0, marginRight: 10 }}
                  >
                    <ProFormText key="name" name="name" label="键名" />
                  </ProCard>
                  <ProCard
                    style={{ padding: 0, margin: 0 }}
                    bodyStyle={{ padding: 0, marginRight: 10 }}
                  >
                    <ProFormText key="default" name="default" label="默认值" />
                  </ProCard>
                </ProCard>
              );
            }}
          </ProFormList>
        </StepsForm.StepForm>
        {/* 关联网点 */}
        <StepsForm.StepForm<{
          group: string;
        }>
          name="group"
          title="关联网点"
          stepProps={{
            description: '选择网点',
          }}

          onFinish={async () => {
            return true;
          }}
          style={{ width: proFormItemStyleProps.width }}
          formRef={formRef3}
        >
          <div style={{ paddingBottom: 10, fontWeight: 700 }}>{'选择网点'}</div>
          <Tree
            checkable
            defaultExpandAll={true}
            defaultCheckedKeys={[]}
            autoExpandParent={true}
            onCheck={(checkedKeys: any) => {
              // form.setFieldsValue({menuIds: checkedKeys})
              setSelectKeys(checkedKeys);
              // formRef3.current?.setFieldValue('groupIds', checkedKeys)
            }}
            treeData={treeData}
            // loadData={({treeNode}) => {
            //   return treeData
            // }}
          />
        </StepsForm.StepForm>
      </StepsForm>
    </div>
  );
};
export default MyCreateForm;
