import { NextResponse } from "next/server";

import { sendEmailVerificationEmail } from "@/features/auth/lib/auth-emails";
import {
  buildEmailVerificationUrl,
  issueEmailVerificationToken
} from "@/features/auth/lib/email-verification";
import { createUserSchema } from "@/features/users/schemas/user.schema";
import { serializeUser } from "@/features/users/lib/serialize-user";
import { createAuditTrailSafe } from "@/lib/audit-trail";
import { hashPassword } from "@/lib/auth";
import { requireApiAccess } from "@/lib/authorization";
import { prisma } from "@/lib/prisma";

export async function GET(request: Request) {
  const auth = requireApiAccess(request);
  if (!auth.ok) return auth.response;

  const users = await prisma.user.findMany({
    include: {
      role: true
    },
    orderBy: [{ createdAt: "desc" }]
  });

  return NextResponse.json({
    data: users.map(serializeUser)
  });
}

export async function POST(request: Request) {
  const auth = requireApiAccess(request);
  if (!auth.ok) return auth.response;

  try {
    const parsed = createUserSchema.safeParse(await request.json());
    if (!parsed.success) {
      return NextResponse.json(
        {
          message: "Validasi gagal",
          errors: parsed.error.flatten().fieldErrors
        },
        { status: 422 }
      );
    }

    const email = parsed.data.email.toLowerCase();
    const username = parsed.data.username.toLowerCase();

    const [role, existingEmail, existingUsername] = await Promise.all([
      prisma.role.findUnique({ where: { code: parsed.data.role_code } }),
      prisma.user.findFirst({ where: { email } }),
      prisma.user.findFirst({ where: { username } })
    ]);

    if (!role) {
      return NextResponse.json({ message: "Role tidak ditemukan" }, { status: 404 });
    }
    if (existingEmail) {
      return NextResponse.json({ message: "Email sudah dipakai" }, { status: 409 });
    }
    if (existingUsername) {
      return NextResponse.json({ message: "Username sudah dipakai" }, { status: 409 });
    }

    const user = await prisma.user.create({
      data: {
        roleId: role.id,
        name: parsed.data.name,
        email,
        username,
        phone: parsed.data.phone || null,
        passwordHash: hashPassword(parsed.data.password),
        emailVerifiedAt: null,
        status: parsed.data.status
      },
      include: {
        role: true
      }
    });

    if (user.email) {
      const { plainToken } = await issueEmailVerificationToken(user.id);
      await sendEmailVerificationEmail({
        to: user.email,
        name: user.name,
        verifyUrl: buildEmailVerificationUrl(plainToken)
      });
    }

    await createAuditTrailSafe({
      userId: auth.user.id,
      action: "USER_CREATED",
      entityType: "USER",
      entityId: user.id,
      method: request.method,
      pathname: new URL(request.url).pathname,
      statusCode: 201,
      summary: `User ${user.email ?? user.username ?? user.name} dibuat`,
      metadata: {
        role: user.role.code,
        email: user.email,
        verified: false
      }
    });

    return NextResponse.json(
      {
        data: serializeUser(user)
      },
      { status: 201 }
    );
  } catch (error) {
    return NextResponse.json(
      {
        message: error instanceof Error ? error.message : "Gagal membuat user"
      },
      { status: 500 }
    );
  }
}
