// 九宫格图生成器 - 下载处理模块
// 实现类似 Texture Packer 的功能：将多张图片拼接成一张图，并生成 JSON 文件

(function () {
  // 获取当前登录用户名
  function getCurrentUsername() {
    try {
      const loginDataStr = localStorage.getItem('loginData');
      if (!loginDataStr) {
        return null;
      }
      
      const loginData = JSON.parse(loginDataStr);
      const now = Date.now();
      
      // 检查是否过期
      if (now >= loginData.expireTime) {
        localStorage.removeItem('loginData');
        return null;
      }
      
      return loginData.user ? loginData.user.username : null;
    } catch (error) {
      console.error('[SpriteSheet] 获取用户名失败:', error);
      return null;
    }
  }

  // 显示提示信息（使用全局 Alert 组件，直接调用）
  function showAlert(message, duration = 2000) {
    // 直接调用父窗口的 GlobalAlert（不通过 postMessage）
    try {
      // 优先使用父窗口的 GlobalAlert
      if (window.parent && window.parent !== window && window.parent.GlobalAlert) {
        window.parent.GlobalAlert.show(message, duration);
        return;
      }
      
      // 如果不在 iframe 中，直接使用当前窗口的 GlobalAlert
      if (window.GlobalAlert) {
        window.GlobalAlert.show(message, duration);
        return;
      }
      
      // 降级处理
      console.log('[Alert]', message);
    } catch (error) {
      console.error('[SpriteSheet] 显示 alert 失败:', error);
      alert(message);
    }
  }

  // 统一的错误处理函数：解析服务端错误响应并显示
  async function handleServerError(response, defaultMessage = '操作失败') {
    let errorMessage = defaultMessage;
    
    try {
      // 尝试解析 JSON 错误响应
      const errorData = await response.json().catch(() => null);
      if (errorData) {
        // 优先使用服务端返回的 message
        if (errorData.message) {
          errorMessage = errorData.message;
        } else if (errorData.error) {
          errorMessage = errorData.error;
        } else if (typeof errorData === 'string') {
          errorMessage = errorData;
        }
      }
    } catch (e) {
      // 如果解析失败，使用默认消息或状态码
      if (response.status) {
        errorMessage = `${defaultMessage} (状态码: ${response.status})`;
      }
    }
    
    showAlert(errorMessage);
    return errorMessage;
  }

  // Cocos Creator 配置选项
  const COCOS_CONFIG = {
    // 是否使用 2 的幂次方尺寸（Cocos Creator 3.8 不需要，但可以启用以获得更好的性能）
    usePowerOfTwo: false,
    // 图片拼接时是否对齐到像素边界（推荐开启）
    pixelPerfect: true
  };

  // 计算最小2的幂次方（可选，用于优化纹理内存使用）
  function nextPowerOfTwo(n) {
    if (n <= 0) return 1;
    if ((n & (n - 1)) === 0) return n; // 已经是2的幂
    let power = 1;
    while (power < n) {
      power <<= 1;
    }
    return power;
  }

  // 计算最终尺寸（根据配置决定是否使用 2 的幂次方）
  function calculateFinalSize(width, height) {
    if (COCOS_CONFIG.usePowerOfTwo) {
      return {
        width: nextPowerOfTwo(width),
        height: nextPowerOfTwo(height)
      };
    } else {
      // 直接使用实际尺寸，Cocos Creator 3.8 完全支持
      return { width, height };
    }
  }

  // 加载图片
  function loadImage(src) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.crossOrigin = 'anonymous';
      img.onload = () => resolve(img);
      img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
      img.src = src;
    });
  }

  // 显示加载动画
  function showLoadingModal(folderName) {
    // 创建模态框
    const modal = document.createElement('div');
    modal.id = 'spriteSheetLoadingModal';
    modal.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.7);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      z-index: 99999;
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    `;

    const content = document.createElement('div');
    content.style.cssText = `
      background: #ffffff;
      border-radius: 12px;
      padding: 30px 40px;
      text-align: center;
      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
      min-width: 300px;
    `;

    const title = document.createElement('div');
    title.textContent = '正在生成 Sprite Sheet';
    title.style.cssText = `
      font-size: 18px;
      font-weight: 600;
      color: #1f2937;
      margin-bottom: 10px;
    `;

    const folder = document.createElement('div');
    folder.textContent = folderName;
    folder.style.cssText = `
      font-size: 14px;
      color: #6b7280;
      margin-bottom: 20px;
    `;

    // 加载动画
    const spinner = document.createElement('div');
    spinner.style.cssText = `
      width: 40px;
      height: 40px;
      border: 4px solid #e5e7eb;
      border-top-color: #3b82f6;
      border-radius: 50%;
      animation: spin 0.8s linear infinite;
      margin: 0 auto 20px;
    `;

    // 添加动画样式
    if (!document.getElementById('spriteSheetLoadingStyle')) {
      const style = document.createElement('style');
      style.id = 'spriteSheetLoadingStyle';
      style.textContent = `
        @keyframes spin {
          to { transform: rotate(360deg); }
        }
      `;
      document.head.appendChild(style);
    }

    const status = document.createElement('div');
    status.id = 'spriteSheetStatus';
    status.textContent = '加载图片中...';
    status.style.cssText = `
      font-size: 14px;
      color: #374151;
    `;

    content.appendChild(title);
    content.appendChild(folder);
    content.appendChild(spinner);
    content.appendChild(status);
    modal.appendChild(content);
    document.body.appendChild(modal);

    return {
      modal,
      updateStatus: (text) => {
        status.textContent = text;
      }
    };
  }

  // 隐藏加载动画
  function hideLoadingModal() {
    const modal = document.getElementById('spriteSheetLoadingModal');
    if (modal) {
      modal.remove();
    }
  }

  // 下载文件
  function downloadFile(data, filename, mimeType) {
    const blob = new Blob([data], { type: mimeType });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  // 生成 Cocos Creator 3.8 兼容的 JSON 格式的 sprite sheet 数据
  // Cocos Creator 使用标准的 TexturePacker JSON 格式，坐标系统从上到下（左上角为原点）
  function generateJSON(folderName, images, sheetWidth, sheetHeight) {
    const frames = {};
    
    images.forEach((img, index) => {
      const frameNum = (index + 1).toString().padStart(2, '0');
      const frameName = `${frameNum}.png`;
      const x = img.x;
      const y = img.y;  // Cocos Creator 和 Canvas 都使用从上到下的坐标系统
      const width = img.width;
      const height = img.height;
      
      // 标准的 TexturePacker JSON 格式，Cocos Creator 3.8 完全兼容
      frames[frameName] = {
        frame: { 
          x: x, 
          y: y,
          w: width, 
          h: height 
        },
        rotated: false,
        trimmed: false,
        spriteSourceSize: { x: 0, y: 0, w: width, h: height },
        sourceSize: { w: width, h: height }
      };
    });

    const json = {
      frames: frames,
      meta: {
        app: "SpriteSheetMaker for Cocos Creator 3.8",
        version: "1.0",
        image: `${folderName}.png`,
        format: "RGBA8888",
        size: { w: sheetWidth, h: sheetHeight },
        scale: "1"
      }
    };

    return JSON.stringify(json, null, 2);
  }

  // 将 Blob 转换为 Base64
  function blobToBase64(blob) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onloadend = () => {
        // 移除 data:image/png;base64, 前缀
        const base64 = reader.result.split(',')[1];
        resolve(base64);
      };
      reader.onerror = reject;
      reader.readAsDataURL(blob);
    });
  }

  // 发送数据到服务器打包并下载
  async function packAndDownload(folderName, imageBlob, jsonData, loading) {
    try {
      loading.updateStatus('转换图片数据...');
      // 将图片转换为 Base64
      const imageBase64 = await blobToBase64(imageBlob);
      
      loading.updateStatus('发送到服务器打包...');
      // 发送到服务器打包
      const response = await fetch('http://localhost:3000/api/pack', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          folderName: folderName,
          imageData: imageBase64,
          jsonData: jsonData
        })
      });

      if (!response.ok) {
        const errorMessage = await handleServerError(response, '打包失败');
        throw new Error(errorMessage);
      }

      loading.updateStatus('下载 ZIP 文件...');
      // 获取 ZIP 文件的 Blob
      const zipBlob = await response.blob();
      
      // 下载 ZIP 文件
      downloadFile(zipBlob, `${folderName}.zip`, 'application/zip');
      
      hideLoadingModal();
    } catch (error) {
      hideLoadingModal();
      console.error('打包失败:', error);
      showAlert(`打包失败: ${error.message}`);
    }
  }

  // 拼接图片
  async function packImages(folderName, frameNumbers) {
    const loading = showLoadingModal(folderName);

    try {
      // 1. 加载所有图片
      loading.updateStatus(`加载图片中... (0/${frameNumbers.length})`);
      const images = [];
      
      // 获取用户名
      const username = getCurrentUsername();
      if (!username) {
        throw new Error('请先登录');
      }
      
      for (let i = 0; i < frameNumbers.length; i++) {
        const frameNum = frameNumbers[i];
        const frameName = frameNum.toString().padStart(2, '0');
        // 使用API路径，从用户目录加载
        const imagePath = `${folderName}/${frameName}.png`;
        const imgSrc = `/api/disk/preview?username=${encodeURIComponent(username)}&path=${encodeURIComponent(imagePath)}`;
        
        loading.updateStatus(`加载图片中... (${i + 1}/${frameNumbers.length})`);
        const img = await loadImage(imgSrc);
        images.push({
          img: img,
          width: img.width,
          height: img.height,
          frameNum: frameNum
        });
      }

      // 2. 计算最优布局（尽可能接近正方形）
      loading.updateStatus('计算布局中...');
      
      // 计算所有图片的平均尺寸和总面积
      let totalArea = 0;
      let maxImageWidth = 0;
      let maxImageHeight = 0;
      images.forEach((item) => {
        totalArea += item.width * item.height;
        maxImageWidth = Math.max(maxImageWidth, item.width);
        maxImageHeight = Math.max(maxImageHeight, item.height);
      });
      
      // 估算目标尺寸（接近正方形）
      const estimatedSide = Math.ceil(Math.sqrt(totalArea));
      const estimatedCols = Math.ceil(estimatedSide / maxImageWidth);
      
      // 尝试不同的列数，找到长宽差最小的方案
      let bestLayout = null;
      let bestDiff = Infinity;
      
      // 缩小搜索范围以提高效率，但确保覆盖合理的范围
      let maxCols = Math.min(images.length, Math.ceil(estimatedCols * 1.5));
      let minCols = Math.max(1, Math.floor(estimatedCols * 0.7));
      
      // 确保minCols不超过maxCols，并且至少尝试几种列数
      if (minCols > maxCols) {
        minCols = Math.max(1, Math.floor(maxCols * 0.5));
      }
      
      // 对于图片数量很少的情况，确保尝试所有可能的列数
      if (images.length <= 10) {
        minCols = 1;
        maxCols = images.length;
      }
      
      for (let cols = minCols; cols <= maxCols; cols++) {
        const rows = Math.ceil(images.length / cols);
        const layout = [];
        
        // 计算每行的宽度和高度
        const rowWidths = new Array(rows).fill(0);
        const rowHeights = new Array(rows).fill(0);
        
        images.forEach((item, index) => {
          const row = Math.floor(index / cols);
          const col = index % cols;
          
          rowWidths[row] += item.width;
          rowHeights[row] = Math.max(rowHeights[row], item.height);
        });
        
        // 计算总尺寸（实际尺寸）
        const totalWidth = Math.max(...rowWidths);
        const totalHeight = rowHeights.reduce((sum, h) => sum + h, 0);
        
        // 计算最终尺寸（根据配置决定是否使用 2 的幂次方）
        const finalSize = calculateFinalSize(totalWidth, totalHeight);
        const sheetWidth = finalSize.width;
        const sheetHeight = finalSize.height;
        
        // 计算长宽差的绝对值（使用实际尺寸比较，以便找到最接近正方形的布局）
        const diff = Math.abs(totalWidth - totalHeight);
        
        // 如果这个方案更好，保存它
        if (diff < bestDiff) {
          bestDiff = diff;
          
          // 生成完整的布局位置信息
          const currentLayout = [];
          let currentY = 0;
          
          for (let row = 0; row < rows; row++) {
            let currentX = 0;
            const rowHeight = rowHeights[row];
            
            for (let col = 0; col < cols; col++) {
              const index = row * cols + col;
              if (index >= images.length) break;
              
              const item = images[index];
              currentLayout.push({
                x: currentX,
                y: currentY,
                width: item.width,
                height: item.height,
                img: item.img,
                frameNum: item.frameNum
              });
              
              currentX += item.width;
            }
            
            currentY += rowHeight;
          }
          
          bestLayout = {
            layout: currentLayout,
            width: sheetWidth,
            height: sheetHeight
          };
        }
      }
      
      // 如果没找到最佳布局（理论上不应该发生），使用默认的水平布局作为后备
      if (!bestLayout) {
        let currentX = 0;
        let maxHeight = 0;
        const defaultLayout = [];
        
        images.forEach((item) => {
          defaultLayout.push({
            x: currentX,
            y: 0,
            width: item.width,
            height: item.height,
            img: item.img,
            frameNum: item.frameNum
          });
          currentX += item.width;
          maxHeight = Math.max(maxHeight, item.height);
        });
        
        const totalWidth = currentX;
        const totalHeight = maxHeight;
          const finalSize = calculateFinalSize(totalWidth, totalHeight);
          bestLayout = {
            layout: defaultLayout,
            width: finalSize.width,
            height: finalSize.height
          };
      }
      
      // 使用最佳布局
      const layout = bestLayout.layout;
      const sheetWidth = bestLayout.width;
      const sheetHeight = bestLayout.height;

      // 4. 创建 Canvas 并绘制
      loading.updateStatus('拼接图片中...');
      const canvas = document.createElement('canvas');
      canvas.width = sheetWidth;
      canvas.height = sheetHeight;
      const ctx = canvas.getContext('2d');

      // 填充透明背景
      ctx.clearRect(0, 0, sheetWidth, sheetHeight);

      // 绘制所有图片
      layout.forEach((item) => {
        ctx.drawImage(item.img, item.x, item.y);
      });

      // 5. 生成 JSON 文件
      loading.updateStatus('生成 JSON 文件...');
      const jsonData = generateJSON(folderName, layout, sheetWidth, sheetHeight);

      // 6. 打包并下载（使用服务器端打包）
      loading.updateStatus('准备打包...');
      
      // 将图片转换为 blob，然后发送到服务器打包
      canvas.toBlob(async (imageBlob) => {
        await packAndDownload(folderName, imageBlob, jsonData, loading);
      }, 'image/png');

    } catch (error) {
      hideLoadingModal();
      showAlert(`生成失败: ${error.message}`);
    }
  }

  // 处理卡片下载按钮点击事件
  async function handleDownloadClick(folderName, index) {
    if (!folderName) {
      return;
    }

    try {
      // 获取帧列表
      const encodedFolderName = encodeURIComponent(folderName);
      const response = await fetch(`http://localhost:3000/api/frames/${encodedFolderName}`);
      if (!response.ok) {
        const errorMessage = await handleServerError(response, '无法获取帧列表');
        throw new Error(errorMessage);
      }

      const data = await response.json();
      const frameNumbers = data.frames || [];

      if (frameNumbers.length === 0) {
        showAlert('该文件夹中没有图片');
        return;
      }

      // 开始拼接
      await packImages(folderName, frameNumbers);

    } catch (error) {
      showAlert(`下载失败: ${error.message}`);
    }
  }

  // 导出到全局
  window.SpriteSheetMaker = {
    handleDownloadClick: handleDownloadClick
  };
})();
