import { existsSync, 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 ?? 43122);
const projectId = "00000000-0000-4000-8000-000000000904";
const dynamicRoot = process.env.DADA_DYNAMIC_ASSET_ROOT ?? join(homedir(), "Desktop", "sticker_interactive", "单模板归档", "templates");
const stickerRoot = process.env.DADA_STATIC_STICKER_ROOT ?? join(homedir(), "Desktop", "贴纸素材");
const textRoot = process.env.DADA_TEXT_ASSET_ROOT ?? join(homedir(), "Desktop", "sticker_text");

const publicAssets = {
  STK001: [join(stickerRoot, "sticker_part1", "01af6384c2a962d17f55736f9895b505.png"), "image/png"],
  STK002: [join(stickerRoot, "sticker_part2", "011db0fb6ac4184e4a708374003bce66.png"), "image/png"],
  "15974853bc3294ef68e7e6d58fe74fd7": [join(dynamicRoot, "DYN002", "fonts", "15974853bc3294ef68e7e6d58fe74fd7", "0202b90o6r57rxed4027b5689e0dxe7e142r0yho9d0lljuqj.ttf"), "font/ttf"],
  "46f8336813e4c48d06a1aef294fdccf6": [join(dynamicRoot, "DYN016", "fonts", "46f8336813e4c48d06a1aef294fdccf6", "9fbfbb420cea1df916d7c7c7ac90b1c88b61e117-PingFang-SC-Semibold-2.ttf"), "font/ttf"],
  "53ca6b704728520da50c145eabb2e635": [join(dynamicRoot, "DYN007", "fonts", "53ca6b704728520da50c145eabb2e635", "fab6c26a0b21d5e9b57fb5238843ac1fb77a2ce6-HYZhengYuan.ttf"), "font/ttf"],
  "cca5efc0e02fb1bf62349bd68ef30fc1": [join(dynamicRoot, "DYN015", "fonts", "cca5efc0e02fb1bf62349bd68ef30fc1", "e11ced673fc7e63e8b0b4730166d29845d8bebae-NotoSansCJKsc-Regular.otf"), "font/otf"],
  "dd25b35dcb7ba4476cbaa9a9592e39e2": [join(dynamicRoot, "DYN001", "fonts", "dd25b35dcb7ba4476cbaa9a9592e39e2", "0202b90o6r57rxed4027b5689e0dxe7e142r0ygbx80porvko.ttf"), "font/ttf"],
  "e4210c9872f0c279b35273f230809821": [join(dynamicRoot, "DYN011", "fonts", "e4210c9872f0c279b35273f230809821", "06b980259e2104e1211a6819a61bc5ddeca77dcb-DJB-Get-Digital-1.ttf"), "font/ttf"],
  "f4bfd4132df2d6be97ceabadf3853505": [join(dynamicRoot, "DYN008", "fonts", "f4bfd4132df2d6be97ceabadf3853505", "6ce05a147aedabbb610d9cb3e75bbe60c064c3f5-BarlowCondensed-SemiBold.ttf"), "font/ttf"],
  "DYN001-image28": [join(dynamicRoot, "DYN001", "resource", "image28.png"), "image/png"],
  "DYN002-image29": [join(dynamicRoot, "DYN002", "resource", "image29.png"), "image/png"],
  "DYN003-image30": [join(dynamicRoot, "DYN003", "resource", "image30.png"), "image/png"],
  "DYN004-image32": [join(dynamicRoot, "DYN004", "resource", "image32.png"), "image/png"],
  "DYN008-backendui0": [join(dynamicRoot, "DYN008", "resource", "backendui0.png"), "image/png"],
  "DYN011-backendui0": [join(dynamicRoot, "DYN011", "resource", "backendui0.png"), "image/png"],
  "DYN015-imager2": [join(dynamicRoot, "DYN015", "resource", "imager2_2.png"), "image/png"],
  "DYN016-image21": [join(dynamicRoot, "DYN016", "resource", "image21.png"), "image/png"],
  FONT081: [join(textRoot, "字体", "面板全量采集", "font_panel_full_20260722", "resources", "font_packages", "FONT081_Lexend Deca", "font_files", "02034l0o6r57rxed4027b5689e0dxe7e142r0vi8920akeqto.ttf"), "font/ttf"],
};

if (!Object.values(publicAssets).every(([path]) => existsSync(path))) throw new Error("WP4-04 original preview assets are unavailable.");

const session = {
  audience: "user", authenticated: true, credits: { available_balance: 10, reserved_balance: 0 },
  csrf_token: "csrf-wp4-manual-preview-0000000000000000000000000000", 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-000000000901" },
};
const backgroundId = "00000000-0000-4000-8000-000000000902";
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="#2b3038"/><rect x="0" y="0" width="216" height="1440" fill="#04d960"/><rect x="216" y="0" width="216" height="1440" fill="#0abf58"/><rect x="432" y="0" width="216" height="1440" fill="#5fd994"/><rect x="648" y="0" width="216" height="1440" fill="#a0f2c4"/><rect x="864" y="0" width="216" height="1440" fill="#d5f2e2"/><rect x="0" y="0" width="1080" height="1440" fill="#15181d" opacity=".58"/></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: "wp4-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-000000000903", 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");
      if (request.method === "POST" && url.pathname === "/api/v1/location/reverse-geocode") return sendJson(response, { formatted_value: "浙江省温州市", service_mode: "mock", status: "resolved" });
      const publicMatch = url.pathname.match(/^\/api\/v1\/assets\/public\/([^/]+)\/([^/]+)$/);
      if (request.method === "GET" && publicMatch) {
        const assetId = decodeURIComponent(publicMatch[2]);
        const asset = publicAssets[assetId];
        if (!asset) return sendJson(response, { error: "not_found" }, 404);
        return send(response, 200, readFileSync(asset[0]), asset[1]);
      }
      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(`WP4-04 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)); });
