import { Router } from "express";
import Database from "better-sqlite3";
import { v4 as uuidv4 } from "uuid";
import fs from "fs";
import path from "path";

type ThemeSavedCallback = (
  creativeId: string,
  theme: Record<string, string>,
  storageDir: string
) => void;

export function creativesRouter(
  db: Database.Database,
  storageDir: string,
  onThemeSaved?: ThemeSavedCallback
): Router {
  const router = Router();

  // GET /api/v1/creatives — 创意列表
  router.get("/", (req, res) => {
    const { status, page = "1", limit = "20" } = req.query;
    const offset = (Number(page) - 1) * Number(limit);

    let sql = `
      SELECT c.*, t.name as template_name
      FROM creatives c
      JOIN templates t ON c.template_id = t.id
    `;
    const params: any[] = [];

    if (status) {
      sql += " WHERE c.status = ?";
      params.push(status);
    }

    sql += " ORDER BY c.updated_at DESC LIMIT ? OFFSET ?";
    params.push(Number(limit), offset);

    const rows = db.prepare(sql).all(...params) as any[];

    const data = rows.map((row) => ({
      id: row.id,
      name: row.name,
      templateId: row.template_id,
      templateName: row.template_name,
      status: row.status,
      createdAt: row.created_at,
      updatedAt: row.updated_at,
    }));

    res.json({ data });
  });

  // POST /api/v1/creatives — 新建创意
  router.post("/", (req, res) => {
    const { name, templateId } = req.body;

    if (!name || !templateId) {
      res.status(400).json({
        error: { message: "name and templateId are required" },
      });
      return;
    }

    // 校验模板存在
    const template = db
      .prepare("SELECT id FROM templates WHERE id = ?")
      .get(templateId);
    if (!template) {
      res.status(400).json({
        error: { message: `Template '${templateId}' not found` },
      });
      return;
    }

    const id = uuidv4();
    db.prepare(
      "INSERT INTO creatives (id, name, template_id) VALUES (?, ?, ?)"
    ).run(id, name, templateId);

    const creative = db.prepare("SELECT * FROM creatives WHERE id = ?").get(id) as any;

    res.status(201).json({
      data: {
        id: creative.id,
        name: creative.name,
        templateId: creative.template_id,
        status: creative.status,
        theme: JSON.parse(creative.theme),
        createdAt: creative.created_at,
        updatedAt: creative.updated_at,
      },
    });
  });

  // GET /api/v1/creatives/:id — 创意详情
  router.get("/:id", (req, res) => {
    const creative = db
      .prepare(
        `SELECT c.*, t.name as template_name
         FROM creatives c
         JOIN templates t ON c.template_id = t.id
         WHERE c.id = ?`
      )
      .get(req.params.id) as any;

    if (!creative) {
      res.status(404).json({ error: { message: "Creative not found" } });
      return;
    }

    // 获取素材列表
    const assets = db
      .prepare("SELECT * FROM creative_assets WHERE creative_id = ?")
      .all(creative.id) as any[];

    // 获取最近构建
    const recentBuilds = db
      .prepare(
        "SELECT id, status, platforms, results, error_log, started_at, finished_at, created_at FROM builds WHERE creative_id = ? ORDER BY created_at DESC LIMIT 5"
      )
      .all(creative.id) as any[];

    res.json({
      data: {
        id: creative.id,
        name: creative.name,
        templateId: creative.template_id,
        template: {
          id: creative.template_id,
          name: creative.template_name,
        },
        status: creative.status,
        theme: JSON.parse(creative.theme),
        assets: assets.map((a) => ({
          key: a.file_key,
          fileName: a.file_name,
          fileSize: a.file_size,
          isRequired: !!a.is_required,
        })),
        recentBuilds: recentBuilds.map((b) => ({
          id: b.id,
          status: b.status,
          platforms: JSON.parse(b.platforms),
          previewUrl: b.status === "completed" ? `/q/${b.id.replace(/-/g, "").slice(0, 8)}.html` : null,
          results: b.results ? JSON.parse(b.results) : null,
          errorLog: b.error_log,
          startedAt: b.started_at,
          finishedAt: b.finished_at,
          createdAt: b.created_at,
        })),
        createdAt: creative.created_at,
        updatedAt: creative.updated_at,
      },
    });
  });

  // PATCH /api/v1/creatives/:id — 更新创意
  router.patch("/:id", (req, res) => {
    const creative = db
      .prepare("SELECT * FROM creatives WHERE id = ?")
      .get(req.params.id) as any;

    if (!creative) {
      res.status(404).json({ error: { message: "Creative not found" } });
      return;
    }

    const { name, theme } = req.body;

    if (name !== undefined) {
      db.prepare("UPDATE creatives SET name = ?, updated_at = datetime('now') WHERE id = ?")
        .run(name, req.params.id);
    }

    if (theme !== undefined) {
      db.prepare("UPDATE creatives SET theme = ?, updated_at = datetime('now') WHERE id = ?")
        .run(JSON.stringify(theme), req.params.id);
      // 通知预览服务更新配置
      onThemeSaved?.(req.params.id as string, theme, storageDir);
    }

    // 返回更新后的数据
    const updated = db
      .prepare("SELECT * FROM creatives WHERE id = ?")
      .get(req.params.id) as any;

    res.json({
      data: {
        id: updated.id,
        name: updated.name,
        templateId: updated.template_id,
        status: updated.status,
        theme: JSON.parse(updated.theme),
        updatedAt: updated.updated_at,
      },
    });
  });

  // DELETE /api/v1/creatives/:id — 删除创意
  router.delete("/:id", (req, res) => {
    const creative = db
      .prepare("SELECT * FROM creatives WHERE id = ?")
      .get(req.params.id) as any;

    if (!creative) {
      res.status(404).json({ error: { message: "Creative not found" } });
      return;
    }

    // 删除磁盘文件
    const creativeDir = path.join(storageDir, "creatives", creative.id);
    if (fs.existsSync(creativeDir)) {
      fs.rmSync(creativeDir, { recursive: true, force: true });
    }

    // 级联删除数据库记录（foreign key ON DELETE CASCADE）
    db.prepare("DELETE FROM creatives WHERE id = ?").run(req.params.id);

    res.json({ data: { id: req.params.id, deleted: true } });
  });

  return router;
}
