import { newId } from "./id";

/** 編輯器內附圖（本地選檔或 mock 產圖） */
export type AttachedImage = {
  id: string;
  /** 預覽用（data URL 或已上傳的 https） */
  url: string;
  name?: string;
  /** 產圖 prompt；選檔可無 */
  prompt?: string;
  /** 已上傳的公開 https（Meta 可抓）；有值即可送出 */
  remoteUrl?: string;
  /** 背景上傳中 */
  uploading?: boolean;
  /** 上傳失敗訊息 */
  uploadError?: string;
};

export const MAX_ATTACHED_IMAGES = 10;

/** 單檔上限（與後端 media upload 5MB 對齊） */
const MAX_FILE_BYTES = 5 * 1024 * 1024;

export function withAttachedImageNote(text: string, count: number): string {
  const body = text.trim();
  if (!count || count <= 0) return body;
  if (/（附圖\s*\d+\s*張）/.test(body)) return body;
  return `${body}\n\n（附圖 ${count} 張）`;
}

function readFileAsDataUrl(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(String(reader.result || ""));
    reader.onerror = () => reject(new Error(`讀取失敗：${file.name}`));
    reader.readAsDataURL(file);
  });
}

/**
 * 壓縮 data URL：長邊 ≤ maxEdge、JPEG quality，大幅縮短上傳 JSON。
 * 失敗則回傳原圖。
 */
export async function compressDataUrlForUpload(
  dataUrl: string,
  opts?: { maxEdge?: number; quality?: number },
): Promise<string> {
  const maxEdge = opts?.maxEdge ?? 1600;
  const quality = opts?.quality ?? 0.82;
  if (!dataUrl.startsWith("data:image")) return dataUrl;

  try {
    const img = await loadImage(dataUrl);
    let { width, height } = img;
    if (!width || !height) return dataUrl;
    const scale = Math.min(1, maxEdge / Math.max(width, height));
    width = Math.max(1, Math.round(width * scale));
    height = Math.max(1, Math.round(height * scale));

    const canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext("2d");
    if (!ctx) return dataUrl;
    ctx.drawImage(img, 0, 0, width, height);

    // JPEG 體積小；有透明感的 PNG 也轉 JPEG（白底）以加速上傳
    const out = canvas.toDataURL("image/jpeg", quality);
    // 若壓縮後反而更大（極小圖），用原檔
    if (out.length >= dataUrl.length * 0.95 && dataUrl.length < 200_000) {
      return dataUrl;
    }
    return out;
  } catch {
    return dataUrl;
  }
}

function loadImage(src: string): Promise<HTMLImageElement> {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = () => reject(new Error("image decode failed"));
    img.src = src;
  });
}

/**
 * 把本機圖檔讀成可預覽的 data URL。
 * 選完後應背景上傳；不要在「送出」時才塞巨大 data URL。
 */
export async function filesToAttachedImages(
  files: FileList | File[],
  opts?: { max?: number; existingCount?: number },
): Promise<AttachedImage[]> {
  const max = opts?.max ?? MAX_ATTACHED_IMAGES;
  const existing = opts?.existingCount ?? 0;
  const room = Math.max(0, max - existing);
  const list = Array.from(files).filter((f) => f.type.startsWith("image/"));
  if (list.length === 0) throw new Error("請選擇圖片檔");
  const take = list.slice(0, room);
  if (take.length === 0) throw new Error(`最多附 ${max} 張圖`);

  const out: AttachedImage[] = [];
  for (const file of take) {
    if (file.size > MAX_FILE_BYTES) {
      throw new Error(`${file.name} 超過 5MB`);
    }
    const url = await readFileAsDataUrl(file);
    if (!url.startsWith("data:image")) throw new Error(`無法讀取：${file.name}`);
    out.push({
      id: newId("img"),
      url,
      name: file.name,
      uploading: true,
    });
  }
  return out;
}

/** 送出用：優先 remoteUrl，其次已是 http(s) 的 url */
export function resolvePublishImageUrls(images: AttachedImage[]): string[] {
  const out: string[] = [];
  for (const img of images) {
    const remote = (img.remoteUrl || "").trim();
    if (remote.startsWith("https://") || remote.startsWith("http://")) {
      out.push(remote);
      continue;
    }
    const u = (img.url || "").trim();
    if (u.startsWith("https://") || u.startsWith("http://")) {
      out.push(u);
    }
  }
  return out;
}

export function anyImageUploading(images: AttachedImage[]): boolean {
  return images.some((i) => i.uploading);
}

export function anyImageUploadFailed(images: AttachedImage[]): boolean {
  return images.some((i) => !!i.uploadError);
}

/** 大 data URL 不寫進 localStorage；改成可顯示的 mock 縮圖 seed */
export function toPersistableImageUrl(img: AttachedImage): string {
  if (img.remoteUrl) return img.remoteUrl;
  if (img.url.startsWith("data:") && img.url.length > 1800) {
    const seed = encodeURIComponent((img.name || img.id || "attach").slice(0, 40));
    return `https://api.dicebear.com/9.x/shapes/svg?seed=${seed}&backgroundColor=20b49c,69d4c5,ff7b73,b6f3e4,ffd5dc`;
  }
  return img.url;
}
