import fs from "fs";
import path from "path";
import https from "https";
import http from "http";

export function ensureDir(dir: string): void {
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
}

/**
 * 从填色详情页 URL 中提取素材 ID 并拼接 zip 下载地址。
 *
 * 输入：https://color2.jccytech.cn/app/zh/pages/detail/6a154397957ac783bac98e10
 * 输出：https://color2.jccytech.cn/zips/v2/number_mini/1501/6a154397957ac783bac98e10.zip
 */
export function parseDetailUrl(detailUrl: string): { id: string; zipUrl: string } | null {
  try {
    const url = new URL(detailUrl);
    // 取路径最后一段作为 ID
    const segments = url.pathname.split("/").filter(Boolean);
    const id = segments[segments.length - 1];
    if (!id || id.length < 20) return null;

    const zipUrl = `https://color2.jccytech.cn/zips/v2/number_mini/1501/${id}.zip`;
    return { id, zipUrl };
  } catch {
    return null;
  }
}

/**
 * 下载远程文件到 Buffer
 */
export function downloadFile(url: string): Promise<Buffer> {
  return new Promise((resolve, reject) => {
    const client = url.startsWith("https") ? https : http;
    client.get(url, (res) => {
      if (res.statusCode !== 200) {
        reject(new Error(`Download failed: HTTP ${res.statusCode}`));
        return;
      }
      const chunks: Buffer[] = [];
      res.on("data", (chunk: Buffer) => chunks.push(chunk));
      res.on("end", () => resolve(Buffer.concat(chunks)));
      res.on("error", reject);
    }).on("error", reject);
  });
}

/**
 * XOR 解密 zip 文件。
 *
 * 密钥 = 文件名（不含扩展名），即素材 ID。
 * 对整个文件逐字节异或解密，密钥循环使用。
 */
export function xorDecryptBuffer(encrypted: Buffer, key: string): Buffer {
  const keyBuf = Buffer.from(key);
  const keyLen = keyBuf.length;
  const decrypted = Buffer.alloc(encrypted.length);

  for (let i = 0; i < encrypted.length; i++) {
    decrypted[i] = encrypted[i] ^ keyBuf[i % keyLen];
  }

  return decrypted;
}

export function getCreativeAssetsDir(storageDir: string, creativeId: string): string {
  const dir = path.join(storageDir, "creatives", creativeId, "assets");
  return dir;
}

export function getBuildOutputDir(
  storageDir: string,
  creativeId: string,
  buildId: string
): string {
  const dir = path.join(storageDir, "creatives", creativeId, "builds", buildId);
  ensureDir(dir);
  return dir;
}

export function scanAssetFiles(
  assetsDir: string
): { config: boolean; page: boolean; map: boolean; special: string | null } {
  const result = { config: false, page: false, map: false, special: null as string | null };

  if (!fs.existsSync(assetsDir)) return result;

  const files = fs.readdirSync(assetsDir);
  for (const file of files) {
    const lower = file.toLowerCase();
    if (lower === "config.json") result.config = true;
    else if (lower === "page.png" || lower === "page.jpg" || lower === "page.jpeg")
      result.page = true;
    else if (lower === "map.png") result.map = true;
    else if (lower.startsWith("special.")) result.special = file;
  }

  return result;
}
