import { existsSync, readdirSync, readFileSync } from "node:fs";
import { homedir } from "node:os";
import { join, resolve } from "node:path";
import { createServer } from "vite";

const host = "127.0.0.1";
const port = Number(process.env.DADA_MANUAL_PREVIEW_PORT ?? 43123);
const projectId = "00000000-0000-4000-8000-000000000802";
const sourceRoot = process.env.DADA_STATIC_STICKER_ROOT ?? join(homedir(), "Desktop", "贴纸素材");
const stickerPaths = new Map();
for (let part = 1, index = 1; part <= 25; part += 1) {
  const partRoot = join(sourceRoot, `sticker_part${part}`);
  if (!existsSync(partRoot)) throw new Error(`Missing sticker source part ${part}.`);
  const files = readdirSync(partRoot).filter((name) => name.toLowerCase().endsWith(".png")).sort();
  for (const file of files) {
    const id = `STK${String(index).padStart(index < 1_000 ? 3 : 4, "0")}`;
    stickerPaths.set(id, join(partRoot, file));
    index += 1;
  }
}
if (stickerPaths.size !== 1_407) throw new Error(`Expected 1,407 stickers, found ${stickerPaths.size}.`);

const session = {
  audience: "user", authenticated: true, credits: { available_balance: 10, reserved_balance: 0 },
  csrf_token: "csrf-wp5-02-manual-000000000000000000000000000000", expires_at: "2026-09-03T08:00:00.000Z",
  user: { creator_name: "Dada Creator", role: "user", social_id: "@dada", status: "active", user_id: "00000000-0000-4000-8000-000000000802" },
};
const backgroundId = "00000000-0000-4000-8000-000000000803";
let stateVersion = 1;
let canvasState = {
  background: { adjustments: { brightness: 0, contrast: 0, crop: null, filter: "none", fit: "fill", saturation: 0, sharpness: 0, temperature: 0 }, asset_id: backgroundId },
  elements: [], pixel_height: 1440, pixel_width: 1080, ratio: "3:4", schema_version: 1,
};
const backgroundSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="1080" height="1440"><rect width="1080" height="1440" fill="#d8e8f2"/><rect x="0" y="0" width="1080" height="720" fill="#b3d8ea"/><rect x="0" y="720" width="1080" height="720" fill="#f4e7cf"/></svg>`;

function send(response, status, body, contentType) {
  response.statusCode = status;
  response.setHeader("Content-Type", contentType);
  response.end(body);
}
function sendJson(response, value, status = 200) { send(response, status, JSON.stringify(value), "application/json; charset=utf-8"); }
function readJson(request) {
  return new Promise((resolveBody, reject) => {
    const chunks = [];
    request.on("data", (chunk) => chunks.push(chunk));
    request.on("end", () => { try { resolveBody(JSON.parse(Buffer.concat(chunks).toString("utf8"))); } catch (error) { reject(error); } });
    request.on("error", reject);
  });
}

const mockApi = {
  name: "wp5-02-manual-preview-api",
  configureServer(server) {
    server.middlewares.use((request, response, next) => {
      const url = new URL(request.url ?? "/", `http://${host}:${port}`);
      if (request.method === "GET" && url.pathname === "/api/v1/auth/session") return sendJson(response, session);
      if (request.method === "GET" && url.pathname === "/api/v1/assets/recent") return sendJson(response, { items: [] });
      if (request.method === "GET" && url.pathname === `/api/v1/projects/${projectId}`) return sendJson(response, {
        canvas_state: canvasState, created_at: "2026-08-03T08:00:00.000Z", current_image_id: backgroundId,
        images: [{ created_at: "2026-08-03T08:00:00.000Z", generation_id: "00000000-0000-4000-8000-000000000804", image_id: backgroundId }],
        name: "普通贴纸目录人工检查", pixel_height: 1440, pixel_width: 1080, project_id: projectId, ratio: "3:4", state_version: stateVersion,
      });
      if (request.method === "PUT" && url.pathname === `/api/v1/projects/${projectId}/state`) {
        void readJson(request).then((body) => { canvasState = body.canvas_state; stateVersion += 1; sendJson(response, { save_status: "saved", state_version: stateVersion }); }).catch(() => sendJson(response, { error: "invalid_state" }, 400));
        return;
      }
      if (request.method === "GET" && url.pathname === `/api/v1/private-assets/projects/${projectId}/images/${backgroundId}`) return send(response, 200, backgroundSvg, "image/svg+xml");
      const publicMatch = url.pathname.match(/^\/api\/v1\/assets\/public\/([^/]+)\/([^/]+)$/);
      if (request.method === "GET" && publicMatch) {
        const assetId = decodeURIComponent(publicMatch[2]);
        const path = stickerPaths.get(assetId);
        if (!path) return sendJson(response, { error: "not_found" }, 404);
        return send(response, 200, readFileSync(path), "image/png");
      }
      next();
    });
  },
};

const vite = await createServer({ configFile: resolve("apps/web/vite.config.ts"), plugins: [mockApi], root: resolve("apps/web"), server: { host, port, strictPort: true } });
await vite.listen();
console.log(`WP5-02 manual preview: http://${host}:${port}/app/projects/${projectId}/editor`);
for (const signal of ["SIGINT", "SIGTERM"]) process.once(signal, () => { void vite.close().finally(() => process.exit(0)); });
