import React, { useState } from 'react';
import saveAs from 'file-saver';
import JSZip from 'jszip';
import ConfirmModal from 'components/ConfirmModal';
import ExportAssets from 'components/ExportAssets';
import exportConfig from 'constants/export-config';
import { request } from 'utils/fetch';
import { api } from 'constants/config';
import { useEffect } from 'react';
import { getAssetsFromConfig } from 'utils/component';

const { extension } = exportConfig;

export default function MultiExportModal({ data, children }) {
  const [visible, setVisible] = useState(false);
  const [all, setAll] = useState<any[]>(data);
  const [completed, setCompleted] = useState<any[]>([]);

  useEffect(() => {
    setAll(data);
  }, [data]);

  const onRequest = async (id) => {
    const result = await request(api.resourceExport, { id });
    if (result) {
      const { material, storeCanvas, storeComponents } = result;

      let componentsFiles = storeComponents.reduce((all: any, item: any) => {
        if (!item.parentId) {
          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 files = componentsFiles;

      let componentsThumbs = storeComponents.reduce((all: any, item: any) => {
        if (!item.parentId) {
          const base = JSON.parse(item.base);
          if (base.thumb) {
            all.push(base.thumb);
          }
        }
        return all;
      }, []);
      componentsThumbs = Array.from(new Set(componentsThumbs));

      const componentsAssets = storeComponents.reduce((all, item) => all.concat(getAssetsFromConfig(JSON.parse(item.config))), []);
      const screensAssets = storeCanvas.reduce((all, item) => all.concat(getAssetsFromConfig(JSON.parse(item.config))), []);

      const assets = componentsThumbs
        .concat(componentsAssets)
        .concat(screensAssets)
        .concat(Array.from(new Set([material.thumb, material.preview].filter((d) => d))));

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

  const onComplete = ({ id, zip, name }) => {
    if (all.length === 1) {
      zip.generateAsync({ type: 'blob' }).then((blob) => {
        saveAs(blob, `${name}${extension.resource}`);
        setVisible(false);
      });
    } else {
      setCompleted((prev) => prev.concat([{ id, zip, name }]));
    }
  };

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

  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.resource}`, blob);
            resolve(blob);
          });
        });
      })
    );
    allZip.generateAsync({ type: 'blob' }).then((blob) => {
      saveAs(blob, `资源(${completed.length})${extension.resource}`);
    });

    setVisible(false);
  };

  return (
    <span>
      <span onClick={() => setVisible(true)}>{children}</span>
      {visible && (
        <ConfirmModal
          title="导出模板"
          visible={visible}
          onClose={() => setVisible(false)}
          onOk={onDownloadAll}
          footer={all.length > 1 ? true : false}
          okText="下载"
          cancelText={''}
        >
          <div className="export-container">
            {all.map((item) => (
              <ExportAssets key={item.id} name={item.name} id={item.id} onRequest={onRequest} onComplete={onComplete} onRemove={onRemove} />
            ))}
          </div>
        </ConfirmModal>
      )}
    </span>
  );
}
