import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { toast } from 'react-toastify';
import { nanoid } from 'nanoid';
import { toastLogin } from '@kevisual/resources/pages/message/ToastLogin';

export type ConvertOpts = {
  appKey?: string;
  version?: string;
  username?: string;
  directory?: string;
  isPublic?: boolean;
  filename?: string;
};

export const uploadFileChunked = async (file: File, opts: ConvertOpts) => {
  const { directory, appKey, version, username, isPublic } = opts;
  return new Promise(async (resolve, reject) => {
    const token = localStorage.getItem('token');
    if (!token) {
      console.log('uploadFileChunked token', token);
      toastLogin();
      return;
    }

    const taskId = nanoid();
    const filename = opts.filename || file.name;
    const load = toast.loading(`${filename} 上传中...`);
    NProgress.start();
    // const eventSource = new EventSource('http://49.232.155.236:11015/api/s1/events?taskId=' + taskId);
    const searchParams = new URLSearchParams();
    searchParams.set('taskId', taskId);
    if (isPublic) {
      searchParams.set('public', 'true');
    }
    const eventSource = new EventSource('/api/s1/events?' + searchParams.toString());
    let isError = false;
    // 监听服务器推送的进度更新
    eventSource.onmessage = function (event) {
      console.log('Progress update:', event.data);
      const parseIfJson = (data: string) => {
        try {
          return JSON.parse(data);
        } catch (e) {
          return data;
        }
      };
      const receivedData = parseIfJson(event.data);
      if (typeof receivedData === 'string') return;
      const progress = receivedData.progress;
      const progressFixed = progress.toFixed(2);
      console.log('progress', progress, progressFixed);
      toast.update(load, { render: `${filename} \n上传中...${progressFixed}%`, isLoading: true, autoClose: false });
      if (progress) {
        NProgress.set(progress);
      }
    };
    eventSource.onerror = function (event) {
      console.log('eventSource.onerror', event);
      isError = true;
      reject(event);
    };

    const chunkSize = 1 * 1024 * 1024; // 1MB
    const totalChunks = Math.ceil(file.size / chunkSize);

    for (let currentChunk = 0; currentChunk < totalChunks; currentChunk++) {
      const start = currentChunk * chunkSize;
      const end = Math.min(start + chunkSize, file.size);
      const chunk = file.slice(start, end);

      const formData = new FormData();
      formData.append('file', chunk, filename);
      formData.append('chunkIndex', currentChunk.toString());
      formData.append('totalChunks', totalChunks.toString());
      const isLast = currentChunk === totalChunks - 1;
      if (directory) {
        formData.append('directory', directory);
      }
      if (appKey && version) {
        formData.append('appKey', appKey);
        formData.append('version', version);
      }
      if (username) {
        formData.append('username', username);
      }
      try {
        const res = await fetch('/api/s1/resources/upload/chunk?taskId=' + taskId, {
          method: 'POST',
          body: formData,
          headers: {
            'task-id': taskId,
            Authorization: `Bearer ${token}`,
          },
        }).then((response) => response.json());
        fetch('/api/s1/events/close?taskId=' + taskId);
        if (res?.code !== 200) {
          toast.error('上传失败');
          isError = true;
          NProgress.done();
          eventSource.close();
          toast.dismiss(load);
          reject(new Error(res?.message || '上传失败'));
          return;
        }
        if (isLast) {
          NProgress.done();
          eventSource.close();
          toast.dismiss(load);
          resolve(res);
        }
        // console.log(`Chunk ${currentChunk + 1}/${totalChunks} uploaded`, res);
      } catch (error) {
        console.log('Error uploading chunk', error);
        reject(error);
        return;
      }
    }
  });
};
