import React, { useEffect, useState } from 'react';
import saveAs from 'file-saver';
import JSZip from 'jszip';
import ConfirmModal from 'components/ConfirmModal';
import ExportAssets from 'components/ExportAssets';
import { getAssetsFromConfig } from 'utils/component';
import exportConfig from 'constants/export-config';
import { exportTemplates } from '../../api';
import './index.less';
import { useExportQueue } from 'hooks/useExportQueue';

const { extension } = exportConfig;

interface IProps {
  list: any[];
  onComplete?: () => void;
  children: React.ReactElement;
}

function ExportTemplatesModal(props: IProps) {
  const [visible, setVisible] = useState<boolean>(false);
  const [templates, setTemplates] = useState<any[]>([]);
  const [completed, setCompleted] = useState<any[]>([]);
  const { current, watchBehavior, exportQueuelear } = useExportQueue({
    assets: templates,
    assetsKey: 'id'
  });

  const showModal = () => {
    const { list } = props;
    if (list?.length > 0) {
      setVisible(true);
      setTemplates(list);
    }
  };

  const hideModal = () => {
    setVisible(false);
    setTemplates([]);
    setCompleted([]);
    exportQueuelear();
  };

  useEffect(() => {
    if (templates.length === 1 && props.list.length > 1) {
      const { id } = templates[0];
      const item = completed.find((d) => d.id === id);
      if (item) {
        onComplete(item);
      }
    }
  }, [templates, props.list, completed]);

  const onRequest = (id) => {
    return exportTemplates(id).then(async (res) => {
      if (res) {
        const data = res;
        const components = data.componentsConfig;
        const screens = [data.screenConfig];
        const getComponentsConfigAndScreenConfig = (config) => {
          config.forEach((d) => {
            if (d.statesConfig.length) {
              d.statesConfig.forEach((o) => {
                components.push(...o.componentsConfig);
                screens.push(o.screenConfig);
                if (o.panelsConfig.length) {
                  getComponentsConfigAndScreenConfig(o.panelsConfig);
                }
              });
            }
          });
        };
        getComponentsConfigAndScreenConfig(data.panelsConfig);

        let componentsFiles = components.reduce((all, item) => {
          if (!item.parent) {
            const base = JSON.parse(item.base);
            all.push(`components/${base.module_name}/${base.version}/${base.module_name}.js`);
          }
          return all;
        }, []);
        componentsFiles = Array.from(new Set(componentsFiles));

        const componentsThumbs = components.reduce((all, item) => {
          if (!item.parent) {
            const base = JSON.parse(item.base);
            if (base.thumb) {
              all.push(base.thumb);
            }
          }
          return all;
        }, []);

        const componentsAssets = components.reduce((all, item) => all.concat(getAssetsFromConfig(JSON.parse(item.config))), []);
        const screensAssets = screens.reduce((all, item) => all.concat(getAssetsFromConfig(JSON.parse(item.config))), []);
        const templateThumb = data.templateConfig.thumb;
        const templatePreviewThumb = data.templateConfig.previewThumb;

        const assets = Array.from(
          new Set(componentsThumbs.concat(componentsAssets).concat(screensAssets).concat([templateThumb, templatePreviewThumb]))
        );

        return { data, files: componentsFiles, assets };
      } else {
        return Promise.reject();
      }
    });
  };

  const onComplete = ({ id, zip, name }) => {
    if (templates.length === 1) {
      zip.generateAsync({ type: 'blob' }).then((blob) => {
        saveAs(blob, `${name}${extension.template}`);
        hideModal();
        props.onComplete && props.onComplete();
      });
    } else {
      setCompleted((prev) => {
        return prev.concat([{ id, zip, name }]);
      });
    }
    watchBehavior({
      id,
      state: 1
    });
  };

  const onRemove = (id) => {
    setTemplates((prev) => {
      return prev.filter((d) => d.id != id);
    });

    watchBehavior({
      id,
      state: -1
    });
  };

  const onDownloadAll = async () => {
    const allZip = new JSZip();
    await Promise.all(
      completed.map((d) => {
        return new Promise((resolve) => {
          d.zip.generateAsync({ type: 'blob' }).then((blob) => {
            allZip.file(`${d.name.replace(/\//g, '_')}${extension.template}`, blob);
            resolve(blob);
          });
        });
      })
    );
    allZip.generateAsync({ type: 'blob' }).then((blob) => {
      saveAs(blob, `templates(${completed.length})${extension.template}`);
      hideModal();
      props.onComplete && props.onComplete();
    });
  };
  const { children } = props;
  return (
    <span>
      <span onClick={showModal}>{children}</span>
      {visible && (
        <ConfirmModal
          className="source-easyv-modal source-export-modal"
          title="导出模板"
          visible={visible}
          onClose={hideModal}
          onOk={onDownloadAll}
          footer={templates.length > 1 ? true : false}
          okText="下载"
          cancelText={''}>
          <div className="export-container">
            {templates.map((item) => (
              <ExportAssets
                start={current.includes(item.id)}
                key={item.id}
                name={item.name}
                id={item.id}
                onRequest={onRequest}
                onComplete={onComplete}
                onRemove={onRemove}
              />
            ))}
          </div>
        </ConfirmModal>
      )}
    </span>
  );
}

export default ExportTemplatesModal;
