import React, { useState, useEffect, useCallback } from 'react';
import JSZip from 'jszip';
import saveAs from 'file-saver';
import ExportModal from '../themePanel/ExportModal';
import { request } from 'utils/fetch';
import { api } from 'constants/config';
import {getAssetsUrl} from 'utils/utils';


export default function ExportContainer({ children, list }: { children: React.ReactElement; list: any }) {
  const [visible, setVisible] = useState(false);
  const [total, setTotal] = useState(0);
  const [loaded, setLoaded] = useState(0);
  const [status, setStatus] = useState('normal');
  const [retryCount, setRetryCount] = useState(0);

  useEffect(() => {
    const controller = window.AbortController && new AbortController();
    const zipFiles = (zip, src) => {
      const signal = controller && controller.signal;
      const path = src.slice(0, src.lastIndexOf('/'));
      const name = src.slice(src.lastIndexOf('/') + 1);

      return fetch(getAssetsUrl(`${src}`), { signal, cache: 'no-store' })
        .then((res) => {
          if (res.status === 200) {
            return res.blob();
          } else {
            return Promise.reject(res.statusText);
          }
        })
        .then((result) => {
          setLoaded((prev) => prev + 1);
          zip.folder(path).file(name, result);
        });
    };

    async function startExport() {
      const result = await request(api.materialExport, { id: list[0] });

      if (result) {
        const { material } = result;

        const zip = new JSZip();

        // 数据
        zip.file('data.json', JSON.stringify(result));

        // 文件
        let files = Array.from(new Set([material.content, material.thumb, material.preview]));

        const all = files.map((d) => zipFiles(zip, d));

        setTotal(all.length);

        try {
          await Promise.all(all);
          setStatus('success');
        } catch (error) {
          controller && controller.abort();
          setStatus('exception');
        }

        zip.generateAsync({ type: 'blob' }).then((blob) => {
          hideModal();
          if (list.length === 1) {
            saveAs(blob, `${material.name}.material`);
          } else {
            saveAs(blob, `设计素材包(${list.length}).material`);
          }
        });
      } else {
        controller && controller.abort();
        setStatus('exception');
      }
    }

    if (visible) {
      setTotal(0);
      setLoaded(0);
      setStatus('active');

      startExport();
    }
    return () => {
      controller && controller.abort();
    };
  }, [visible, retryCount, list]);

  const hideModal = useCallback(() => {
    setVisible(false);
  }, []);

  const handleRestart = useCallback(() => {
    setRetryCount((prev) => prev + 1);
  }, []);

  const percent = loaded ? Math.round((loaded / total) * 100) : 0;

  return (
    <span>
      <span onClick={() => setVisible(true)}>{children}</span>
      <ExportModal
        visible={visible}
        title="导出"
        status={status}
        statusText={status === 'success' ? '导出成功' : status === 'exception' ? '导出失败，请重试' : '正在导出，请稍后...'}
        percent={percent}
        onCancel={hideModal}
        onRestart={handleRestart}
      />
    </span>
  );
}
