import { Router } from "express";
import { z } from "zod";
import multer from "multer";
import path from "path";
import { fileURLToPath } from "url";
import { prisma } from "@stamp/shared";
import { requireAdmin } from "../middleware/admin.js";
import { generateQRCodeDataURL } from "../lib/qrcode.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const uploadsDir = path.join(__dirname, "../../uploads");

const storage = multer.diskStorage({
  destination: uploadsDir,
  filename: (_req, file, cb) => {
    const ext = path.extname(file.originalname);
    cb(null, `${Date.now()}-${Math.random().toString(36).slice(2, 8)}${ext}`);
  },
});
const upload = multer({ storage, limits: { fileSize: 5 * 1024 * 1024 } });
const audioUpload = multer({ storage, limits: { fileSize: 20 * 1024 * 1024 } });

const router = Router();
router.use(requireAdmin);

// ===== Stamps CRUD =====

router.get("/stamps", async (_req, res) => {
  const stamps = await prisma.stamp.findMany({ orderBy: { sortOrder: "asc" } });
  res.json({ success: true, data: stamps });
});

const stampSchema = z.object({
  name: z.string().min(1, "图章名称不能为空"),
  note: z.string().optional(),
  imageColor: z.string().optional(),
  imageGrey: z.string().optional(),
  sortOrder: z.number().int().optional(),
  enabled: z.boolean().optional(),
});

router.post("/stamps", async (req, res) => {
  const parsed = stampSchema.safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ success: false, error: { code: "VALIDATION", message: parsed.error.issues[0].message } });
    return;
  }
  const stamp = await prisma.stamp.create({
    data: {
      name: parsed.data.name,
      note: parsed.data.note,
      imageColor: parsed.data.imageColor ?? "",
      imageGrey: parsed.data.imageGrey ?? "",
      sortOrder: parsed.data.sortOrder ?? 0,
      enabled: parsed.data.enabled ?? true,
    },
  });
  res.json({ success: true, data: stamp });
});

router.put("/stamps/:id", async (req, res) => {
  const parsed = stampSchema.partial().safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ success: false, error: { code: "VALIDATION", message: parsed.error.issues[0].message } });
    return;
  }
  const stamp = await prisma.stamp.update({
    where: { id: req.params.id },
    data: parsed.data,
  }).catch(() => null);
  if (!stamp) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "图章不存在" } });
    return;
  }
  res.json({ success: true, data: stamp });
});

router.delete("/stamps/:id", async (req, res) => {
  await prisma.stamp.delete({ where: { id: req.params.id } }).catch(() => null);
  res.json({ success: true, data: null });
});

// Upload stamp image
router.post("/stamps/:id/upload", upload.single("image"), async (req, res) => {
  if (!req.file) {
    res.status(400).json({ success: false, error: { code: "NO_FILE", message: "请选择图片" } });
    return;
  }

  const field = req.body.field as string;
  if (field !== "imageColor" && field !== "imageGrey") {
    res.status(400).json({ success: false, error: { code: "INVALID_FIELD", message: "field 必须是 imageColor 或 imageGrey" } });
    return;
  }

  const imagePath = `/uploads/${req.file.filename}`;
  const stamp = await prisma.stamp.update({
    where: { id: req.params.id },
    data: { [field]: imagePath },
  }).catch(() => null);

  if (!stamp) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "图章不存在" } });
    return;
  }
  res.json({ success: true, data: { path: imagePath } });
});

// Generate QR code
router.get("/stamps/:id/qrcode", async (req, res) => {
  const stamp = await prisma.stamp.findUnique({ where: { id: req.params.id } });
  if (!stamp) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "图章不存在" } });
    return;
  }

  const siteUrl = process.env.SITE_URL || "http://localhost:5173";
  const collectUrl = `${siteUrl}/collect/${stamp.id}`;
  const qrDataUrl = await generateQRCodeDataURL(collectUrl, { width: 400 });

  res.json({ success: true, data: { qrDataUrl, collectUrl, stampName: stamp.name } });
});

// ===== Redemption Rules CRUD =====

router.get("/rules", async (_req, res) => {
  const rules = await prisma.redemptionRule.findMany({ orderBy: { sortOrder: "asc" } });
  res.json({ success: true, data: rules });
});

const ruleSchema = z.object({
  name: z.string().min(1, "奖品名称不能为空"),
  description: z.string().optional(),
  threshold: z.number().int().min(1, "兑换门槛至少为 1"),
  enabled: z.boolean().optional(),
  sortOrder: z.number().int().optional(),
});

router.post("/rules", async (req, res) => {
  const parsed = ruleSchema.safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ success: false, error: { code: "VALIDATION", message: parsed.error.issues[0].message } });
    return;
  }
  const rule = await prisma.redemptionRule.create({
    data: {
      name: parsed.data.name,
      description: parsed.data.description,
      threshold: parsed.data.threshold,
      enabled: parsed.data.enabled ?? true,
      sortOrder: parsed.data.sortOrder ?? 0,
    },
  });
  res.json({ success: true, data: rule });
});

router.put("/rules/:id", async (req, res) => {
  const parsed = ruleSchema.partial().safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ success: false, error: { code: "VALIDATION", message: parsed.error.issues[0].message } });
    return;
  }
  const rule = await prisma.redemptionRule.update({
    where: { id: req.params.id },
    data: parsed.data,
  }).catch(() => null);
  if (!rule) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "规则不存在" } });
    return;
  }
  res.json({ success: true, data: rule });
});

router.delete("/rules/:id", async (req, res) => {
  await prisma.redemptionRule.delete({ where: { id: req.params.id } }).catch(() => null);
  res.json({ success: true, data: null });
});

// ===== Redemption Records & Stats =====

router.get("/redemptions", async (_req, res) => {
  const records = await prisma.redemption.findMany({
    include: { user: { select: { username: true, phone: true } }, rule: { select: { name: true } } },
    orderBy: { redeemedAt: "desc" },
  });
  res.json({ success: true, data: records });
});

router.get("/stats", async (_req, res) => {
  const [userCount, collectionCount, redemptionCount] = await Promise.all([
    prisma.user.count(),
    prisma.collection.count(),
    prisma.redemption.count(),
  ]);
  res.json({ success: true, data: { userCount, collectionCount, redemptionCount } });
});

// Asia/Shanghai 边界（UTC+8，无夏令时）
function shanghaiBoundaries() {
  const OFFSET_MS = 8 * 60 * 60 * 1000;
  const nowShanghai = new Date(Date.now() + OFFSET_MS);
  const y = nowShanghai.getUTCFullYear();
  const m = nowShanghai.getUTCMonth();
  const d = nowShanghai.getUTCDate();
  const weekdaySun0 = nowShanghai.getUTCDay();
  const mondayOffset = (weekdaySun0 + 6) % 7;
  const startOfToday = new Date(Date.UTC(y, m, d) - OFFSET_MS);
  const startOfWeek = new Date(startOfToday.getTime() - mondayOffset * 86_400_000);
  const startOfMonth = new Date(Date.UTC(y, m, 1) - OFFSET_MS);
  return { startOfToday, startOfWeek, startOfMonth };
}

router.get("/dashboard", async (_req, res) => {
  const { startOfToday, startOfWeek, startOfMonth } = shanghaiBoundaries();

  const [
    uTotal, uDay, uWeek, uMonth,
    cTotal, cDay, cWeek, cMonth,
    rTotal, rDay, rWeek, rMonth,
  ] = await Promise.all([
    prisma.user.count(),
    prisma.user.count({ where: { createdAt: { gte: startOfToday } } }),
    prisma.user.count({ where: { createdAt: { gte: startOfWeek } } }),
    prisma.user.count({ where: { createdAt: { gte: startOfMonth } } }),
    prisma.collection.count(),
    prisma.collection.count({ where: { collectedAt: { gte: startOfToday } } }),
    prisma.collection.count({ where: { collectedAt: { gte: startOfWeek } } }),
    prisma.collection.count({ where: { collectedAt: { gte: startOfMonth } } }),
    prisma.redemption.count(),
    prisma.redemption.count({ where: { redeemedAt: { gte: startOfToday } } }),
    prisma.redemption.count({ where: { redeemedAt: { gte: startOfWeek } } }),
    prisma.redemption.count({ where: { redeemedAt: { gte: startOfMonth } } }),
  ]);

  res.json({
    success: true,
    data: {
      users: { total: uTotal, today: uDay, thisWeek: uWeek, thisMonth: uMonth },
      collections: { total: cTotal, today: cDay, thisWeek: cWeek, thisMonth: cMonth },
      redemptions: { total: rTotal, today: rDay, thisWeek: rWeek, thisMonth: rMonth },
    },
  });
});

router.get("/users", async (_req, res) => {
  const users = await prisma.user.findMany({
    orderBy: { createdAt: "desc" },
    include: {
      _count: { select: { collections: true, redemptions: true } },
    },
  });
  const data = users.map((u) => ({
    id: u.id,
    username: u.username,
    phone: u.phone,
    createdAt: u.createdAt,
    collectionCount: u._count.collections,
    redemptionCount: u._count.redemptions,
  }));
  res.json({ success: true, data });
});

// ===== Articles CRUD =====

router.get("/articles", async (_req, res) => {
  const articles = await prisma.article.findMany({ orderBy: { sortOrder: "asc" } });
  res.json({ success: true, data: articles });
});

const articleSchema = z.object({
  title: z.string().min(1, "标题不能为空"),
  subtitle: z.string().optional(),
  body: z.string().min(1, "正文不能为空"),
  coverImage: z.string().optional(),
  caption: z.string().optional(),
  sortOrder: z.number().int().optional(),
  enabled: z.boolean().optional(),
});

router.post("/articles", async (req, res) => {
  const parsed = articleSchema.safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ success: false, error: { code: "VALIDATION", message: parsed.error.issues[0].message } });
    return;
  }
  const article = await prisma.article.create({
    data: {
      title: parsed.data.title,
      subtitle: parsed.data.subtitle,
      body: parsed.data.body,
      coverImage: parsed.data.coverImage ?? "",
      caption: parsed.data.caption,
      sortOrder: parsed.data.sortOrder ?? 0,
      enabled: parsed.data.enabled ?? true,
    },
  });
  res.json({ success: true, data: article });
});

router.put("/articles/:id", async (req, res) => {
  const parsed = articleSchema.partial().safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ success: false, error: { code: "VALIDATION", message: parsed.error.issues[0].message } });
    return;
  }
  const article = await prisma.article.update({
    where: { id: req.params.id },
    data: parsed.data,
  }).catch(() => null);
  if (!article) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "文章不存在" } });
    return;
  }
  res.json({ success: true, data: article });
});

router.delete("/articles/:id", async (req, res) => {
  await prisma.article.delete({ where: { id: req.params.id } }).catch(() => null);
  res.json({ success: true, data: null });
});

router.post("/articles/:id/upload", upload.single("image"), async (req, res) => {
  if (!req.file) {
    res.status(400).json({ success: false, error: { code: "NO_FILE", message: "请选择图片" } });
    return;
  }
  const imagePath = `/uploads/${req.file.filename}`;
  const article = await prisma.article.update({
    where: { id: req.params.id },
    data: { coverImage: imagePath },
  }).catch(() => null);
  if (!article) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "文章不存在" } });
    return;
  }
  res.json({ success: true, data: { path: imagePath } });
});

router.get("/articles/:id/qrcode", async (req, res) => {
  const article = await prisma.article.findUnique({ where: { id: req.params.id } });
  if (!article) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "文章不存在" } });
    return;
  }
  const siteUrl = process.env.SITE_URL || "http://localhost:5173";
  const articleUrl = `${siteUrl}/article/${article.id}`;
  const qrDataUrl = await generateQRCodeDataURL(articleUrl, { width: 400 });
  res.json({ success: true, data: { qrDataUrl, articleUrl, articleTitle: article.title } });
});

// ===== Music CRUD =====

router.get("/music", async (_req, res) => {
  const music = await prisma.music.findMany({ orderBy: { sortOrder: "asc" } });
  res.json({ success: true, data: music });
});

const musicSchema = z.object({
  title: z.string().min(1, "标题不能为空"),
  subtitle: z.string().optional(),
  audioFile: z.string().optional(),
  sortOrder: z.number().int().optional(),
  enabled: z.boolean().optional(),
});

router.post("/music", async (req, res) => {
  const parsed = musicSchema.safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ success: false, error: { code: "VALIDATION", message: parsed.error.issues[0].message } });
    return;
  }
  const music = await prisma.music.create({
    data: {
      title: parsed.data.title,
      subtitle: parsed.data.subtitle,
      audioFile: parsed.data.audioFile ?? "",
      sortOrder: parsed.data.sortOrder ?? 0,
      enabled: parsed.data.enabled ?? true,
    },
  });
  res.json({ success: true, data: music });
});

router.put("/music/:id", async (req, res) => {
  const parsed = musicSchema.partial().safeParse(req.body);
  if (!parsed.success) {
    res.status(400).json({ success: false, error: { code: "VALIDATION", message: parsed.error.issues[0].message } });
    return;
  }
  const music = await prisma.music.update({
    where: { id: req.params.id },
    data: parsed.data,
  }).catch(() => null);
  if (!music) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "音乐不存在" } });
    return;
  }
  res.json({ success: true, data: music });
});

router.delete("/music/:id", async (req, res) => {
  await prisma.music.delete({ where: { id: req.params.id } }).catch(() => null);
  res.json({ success: true, data: null });
});

router.post("/music/:id/upload", audioUpload.single("audio"), async (req, res) => {
  if (!req.file) {
    res.status(400).json({ success: false, error: { code: "NO_FILE", message: "请选择音频文件" } });
    return;
  }
  const audioPath = `/uploads/${req.file.filename}`;
  const music = await prisma.music.update({
    where: { id: req.params.id },
    data: { audioFile: audioPath },
  }).catch(() => null);
  if (!music) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "音乐不存在" } });
    return;
  }
  res.json({ success: true, data: { path: audioPath } });
});

router.get("/music/:id/qrcode", async (req, res) => {
  const music = await prisma.music.findUnique({ where: { id: req.params.id } });
  if (!music) {
    res.status(404).json({ success: false, error: { code: "NOT_FOUND", message: "音乐不存在" } });
    return;
  }
  const siteUrl = process.env.SITE_URL || "http://localhost:5173";
  const musicUrl = `${siteUrl}/music/${music.id}`;
  const qrDataUrl = await generateQRCodeDataURL(musicUrl, { width: 400 });
  res.json({ success: true, data: { qrDataUrl, musicUrl, musicTitle: music.title } });
});

export default router;
