import { NextResponse } from "next/server";
import prisma from "@/lib/prisma";
import { z } from "zod";

const createPostSchema = z.object({
  boardId: z.string().min(1),
  authorId: z.string().optional(),
  title: z.string().min(1),
  content: z.string().min(1),
  isAnonymous: z.boolean().optional(),
});

export async function POST(req: Request) {
  const body = await req.json();
  const parsed = createPostSchema.safeParse(body);
  if (!parsed.success) {
    return NextResponse.json({ error: parsed.error.flatten() }, { status: 400 });
  }
  const { boardId, authorId, title, content, isAnonymous } = parsed.data;
  const board = await prisma.board.findUnique({ where: { id: boardId } });
  // 사진형 보드 필수 이미지 검증: content 내 이미지 링크 최소 1개
  const isImageOnly = (board?.requiredFields as any)?.imageOnly;
  const minImages = (board?.requiredFields as any)?.minImages ?? 0;
  if (isImageOnly || minImages > 0) {
    const imageLinks = (content.match(/!\[[^\]]*\]\([^\)]+\)/g) ?? []).length;
    if (imageLinks < (minImages || 1)) {
      return NextResponse.json({ error: { message: `이미지 최소 ${minImages || 1}개 필요` } }, { status: 400 });
    }
  }
  const post = await prisma.post.create({
    data: {
      boardId,
      authorId: authorId ?? null,
      title,
      content,
      isAnonymous: !!isAnonymous,
      status: "published",
    },
  });
  return NextResponse.json({ post }, { status: 201 });
}

const listQuerySchema = z.object({
  page: z.coerce.number().min(1).default(1),
  pageSize: z.coerce.number().min(1).max(100).default(10),
  boardId: z.string().optional(),
  q: z.string().optional(),
  sort: z.enum(["recent", "popular"]).default("recent").optional(),
  tag: z.string().optional(), // Tag.slug
  author: z.string().optional(), // User.nickname contains
  start: z.coerce.date().optional(), // createdAt >= start
  end: z.coerce.date().optional(), // createdAt <= end
});

export async function GET(req: Request) {
  const { searchParams } = new URL(req.url);
  const parsed = listQuerySchema.safeParse(Object.fromEntries(searchParams));
  if (!parsed.success) {
    return NextResponse.json({ error: parsed.error.flatten() }, { status: 400 });
  }
  const { page, pageSize, boardId, q, sort = "recent", tag, author, start, end } = parsed.data;
  const where = {
    NOT: { status: "deleted" as const },
    ...(boardId ? { boardId } : {}),
    ...(q
      ? {
          OR: [
            { title: { contains: q } },
            { content: { contains: q } },
          ],
        }
      : {}),
    ...(tag
      ? {
          postTags: { some: { tag: { slug: tag } } },
        }
      : {}),
    ...(author
      ? {
          author: { nickname: { contains: author } },
        }
      : {}),
    ...(start || end
      ? {
          createdAt: {
            ...(start ? { gte: start } : {}),
            ...(end ? { lte: end } : {}),
          },
        }
      : {}),
  } as const;

  const [total, items] = await Promise.all([
    prisma.post.count({ where }),
    prisma.post.findMany({
      where,
      orderBy:
        sort === "popular"
          ? [{ isPinned: "desc" }, { stat: { recommendCount: "desc" } }, { createdAt: "desc" }]
          : [{ isPinned: "desc" }, { createdAt: "desc" }],
      skip: (page - 1) * pageSize,
      take: pageSize,
      select: {
        id: true,
        title: true,
        createdAt: true,
        boardId: true,
        isPinned: true,
        status: true,
        author: { select: { nickname: true } },
        stat: { select: { recommendCount: true, views: true, commentsCount: true } },
        postTags: { select: { tag: { select: { name: true, slug: true } } } },
      },
    }),
  ]);

  return NextResponse.json({ total, page, pageSize, items, sort });
}


