
import { ref } from 'vue';
import pLimit from 'p-limit';
import { type BookPageQuestion, type QuestionsImages, updateBookPageLayoutAxios } from '@/service/api/book';
import { getAliOssTokenAxios } from '@/service/api/upload';
import { initOSSClient } from '@/utils/oss';
import type { CropImageOptions, CurrBookPageAllInfo, QuestionInfo } from './types';
import { compareVersion } from '@/utils/common';

// Crop image function implementation
const cropImage = async (url: string, client: any, options: CropImageOptions, id: number): Promise<QuestionsImages> => {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.crossOrigin = 'anonymous';
    img.src = url;
    img.onload = async () => {
      try {
        const canvas = document.createElement('canvas');
        canvas.width = options.width;
        canvas.height = options.height;
        const ctx = canvas.getContext('2d');
        if (!ctx) {
          reject(new Error('Canvas context not available'));
          return;
        }

        // Draw cropped image
        ctx.drawImage(
          img,
          options.x,
          options.y,
          options.width,
          options.height,
          0,
          0,
          options.width,
          options.height
        );

        // Convert to Blob
        canvas.toBlob(async (blob) => {
          if (!blob) {
            reject(new Error('Canvas to Blob failed'));
            return;
          }

          const file = new File([blob], `question_${id}_${Date.now()}.png`, { type: 'image/png' });
          const path = `book/questions/${id}/${file.name}`;

          try {
            // Upload to OSS
            // Assuming client.put or multipartUpload.
            // Since initOSSClient returns an OSS client, we can use it.
            // Using put for small files (cropped images are usually small)
            const result = await client.put(path, file);

            // Return the result format expected by the API
            // The API expects a map of ID to URL? Or array of objects?
            // Based on usage: `tasks.push(...)` and `imageFiles.push(...list)`
            // And `updateBookPageLayoutAxios` takes `questionsImages: imageFiles`
            // Let's return an object with the ID as key and URL as value, or just the URL object if QuestionsImages is a type.
            // Looking at previous usage `urlObj[item.id!] = item`, it seems `QuestionsImages` might be `{ [id]: url }`.

            resolve({ [id]: result.url });
          } catch (err) {
            reject(err);
          }
        }, 'image/png');
      } catch (err) {
        reject(err);
      }
    };
    img.onerror = (err) => {
      reject(new Error('Image load failed'));
    };
  });
};

/** 提交 */
export function usePageLayoutSubmit() {
  const submmitLoading = ref(false);

  async function pageLayoutSubmit(currBookPage: CurrBookPageAllInfo) {
    try {
      submmitLoading.value = true;
      const urlObj: Record<number, BookPageQuestion> = {};
      currBookPage!.currBookPageData.questions.forEach((item) => {
        if (item.id) {
          urlObj[item.id!] = item;
        }
      });

      // 获取阿里云OSS STS
      const aliOssSTS = await getAliOssTokenAxios();
      const client = initOSSClient(aliOssSTS);

      // 截取图片并上传 （5个并发）
      const imageFiles: QuestionsImages[] = [];
      const limit = pLimit(5);
      const tasks: Promise<QuestionsImages>[] = [];
      currBookPage!.currBookPageData.layout.forEach((item) => {
        const question: QuestionInfo = item.question;
        if (currBookPage!.currBookPageData.url) {
          const cropImageOptions: CropImageOptions = { x: question.x, y: question.y, width: question.w, height: question.h };
          const url = currBookPage!.currBookPageData.url;
          //截取图片并添加到上传队列
          tasks.push(limit(() => cropImage(url, client, cropImageOptions, item.questionId!)));
        }
      });

      const list = await Promise.all(tasks);
      imageFiles.push(...list);

      currBookPage!.currBookPageData.layout = currBookPage!.currBookPageData.layout.sort((a, b) => {
        return compareVersion(a.question.no, b.question.no, '-');
      });
      await updateBookPageLayoutAxios({
        id: currBookPage!.currBookPageData!.bookPageId!,
        layout: JSON.stringify(currBookPage!.currBookPageData.layout),
        questionsImages: imageFiles,
      });
      submmitLoading.value = false;
      return Promise.resolve();
    } catch (error) {
      console.log('error====', error);
      submmitLoading.value = false;
      return Promise.reject(error);
    }
  }
  return {
    pageLayoutSubmit,
    submmitLoading,
  };
}

export function getPDFPageWidth(width: number) {
  return width;
}
