import sharp from "sharp";
import { puterChatComplete } from "../puter-inference.js";
import type { RenderResult, WallpaperBundle, AppIconBundle } from "./types.js";

// ─── Platform dimensions ────────────────────────────────────────────────────────

export const PLATFORM_DIMENSIONS: Record<
  string,
  { width: number; height: number; label: string }
> = {
  "desktop-hd":        { width: 2560, height: 1440, label: "Desktop HD (2560×1440)" },
  "desktop-fhd":       { width: 1920, height: 1080, label: "Desktop FHD (1920×1080)" },
  "desktop-4k":        { width: 3840, height: 2160, label: "Desktop 4K (3840×2160)" },
  "mobile-portrait":   { width: 1080, height: 1920, label: "Mobile Portrait (1080×1920)" },
  "mobile-landscape":  { width: 1920, height: 1080, label: "Mobile Landscape (1920×1080)" },
  "og-image":          { width: 1200, height:  630, label: "OG Image (1200×630)" },
  "twitter-card":      { width: 1200, height:  628, label: "Twitter Card (1200×628)" },
  "instagram-post":    { width: 1080, height: 1080, label: "Instagram Post (1080×1080)" },
  "instagram-banner":  { width: 1080, height:  566, label: "Instagram Banner (1080×566)" },
  "linkedin-banner":   { width: 1584, height:  396, label: "LinkedIn Banner (1584×396)" },
  "app-icon":          { width: 1024, height: 1024, label: "App Icon (1024×1024)" },
  "favicon":           { width:   32, height:   32, label: "Favicon (32×32)" },
};

export const APP_ICON_SIZES = [1024, 512, 256, 64, 32] as const;

// ─── SVG generation ─────────────────────────────────────────────────────────────

function buildWallpaperSystemPrompt(width: number, height: number): string {
  return [
    `You are an SVG artwork generator.`,
    `Output ONLY valid SVG — no markdown fences, no explanation, no surrounding text.`,
    `Use viewBox="0 0 ${width} ${height}" matching the target dimensions exactly.`,
    `Create a visually rich scene based on the user prompt.`,
    `Use gradients, shapes, patterns, and organic forms to fill the canvas.`,
    `Do NOT include any text elements (<text>, <tspan>).`,
    `Do NOT include external images or scripts.`,
    `The SVG must start with <svg and end with </svg>.`,
  ].join("\n");
}

function stripMarkdownFences(raw: string): string {
  return raw
    .trim()
    .replace(/^```(?:svg|xml)?\s*/i, "")
    .replace(/\s*```$/, "")
    .trim();
}


// ─── Rasterization helpers ──────────────────────────────────────────────────────

async function rasterizeSvgToPng(
  svgString: string,
  width: number,
  height: number,
): Promise<Buffer> {
  return sharp(Buffer.from(svgString), { density: 300 })
    .resize(width, height, { fit: "fill" })
    .png({ compressionLevel: 9 })
    .toBuffer();
}

// ─── Main renderer ──────────────────────────────────────────────────────────────

export async function renderWallpaper(
  input: Record<string, unknown>,
): Promise<RenderResult> {
  const prompt =
    typeof input.prompt === "string" ? input.prompt : "abstract digital art";
  const platform =
    typeof input.platform === "string" ? input.platform : "desktop-fhd";

  const dims = PLATFORM_DIMENSIONS[platform];
  if (!dims) {
    throw new Error(
      `renderWallpaper: unknown platform "${platform}". ` +
        `Available: ${Object.keys(PLATFORM_DIMENSIONS).join(", ")}`,
    );
  }

  const { width, height } = dims;
  const systemPrompt = buildWallpaperSystemPrompt(width, height);

  const rawSvg = await puterChatComplete([
    { role: "system", content: systemPrompt },
    { role: "user", content: prompt },
  ]);
  const svgString = stripMarkdownFences(rawSvg);

  // App icon / favicon → multi-size bundle
  if (platform === "app-icon" || platform === "favicon") {
    const sizes: AppIconBundle["sizes"] = [];

    for (const size of APP_ICON_SIZES) {
      const pngBuffer = await rasterizeSvgToPng(svgString, size, size);
      sizes.push({ size, pngBase64: pngBuffer.toString("base64") });
    }

    const bundle: AppIconBundle = {
      type: "app-icon-bundle",
      sizes,
      prompt,
    };

    return {
      filename: "app-icon-bundle.json",
      contentType: "application/json",
      buffer: Buffer.from(JSON.stringify(bundle)),
    };
  }

  // All other platforms → single PNG at exact target dimensions
  const pngBuffer = await rasterizeSvgToPng(svgString, width, height);

  const bundle: WallpaperBundle = {
    type: "wallpaper-bundle",
    platform,
    width,
    height,
    pngBase64: pngBuffer.toString("base64"),
    prompt,
  };

  return {
    filename: `wallpaper-${platform}.png`,
    contentType: "image/png",
    buffer: pngBuffer,
  };
}
