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

import { getDefaultPathForRole } from "@/config/access-control";
import { ensureAuthBootstrap } from "@/features/auth/lib/bootstrap-auth";
import {
  getSessionTimeoutSeconds,
  isEmailVerificationRequired
} from "@/lib/app-settings";
import { createAuditTrailSafe } from "@/lib/audit-trail";
import {
  AUTH_COOKIE_NAME,
  createSessionToken,
  getSessionTtlSeconds,
  getSessionCookieOptions,
  verifyPassword
} from "@/lib/auth";
import { prisma } from "@/lib/prisma";

const loginSchema = z.object({
  identity: z.string().trim().min(1, "Email atau username wajib diisi"),
  password: z.string().min(1, "Password wajib diisi"),
  remember_me: z.boolean().optional().default(false)
});

const REMEMBER_ME_TTL_SECONDS = 60 * 60 * 24 * 30;

export async function POST(request: Request) {
  try {
    await ensureAuthBootstrap();

    const body = await request.json();
    const parsed = loginSchema.safeParse(body);

    if (!parsed.success) {
      return NextResponse.json(
        {
          message: "Validasi gagal",
          errors: parsed.error.flatten().fieldErrors
        },
        { status: 422 }
      );
    }

    const { identity, password, remember_me: rememberMe } = parsed.data;
    const normalizedIdentity = identity.toLowerCase();
    const [mustVerifyEmail, sessionTtlSeconds] = await Promise.all([
      isEmailVerificationRequired(),
      getSessionTimeoutSeconds()
    ]);

    const user = await prisma.user.findFirst({
      where: {
        status: "ACTIVE",
        OR: [{ email: normalizedIdentity }, { username: normalizedIdentity }]
      },
      include: {
        role: true
      }
    });

	    if (!user || !user.passwordHash || !verifyPassword(password, user.passwordHash)) {
        await createAuditTrailSafe({
          action: "LOGIN_FAILED",
          entityType: "AUTH",
          method: request.method,
          pathname: new URL(request.url).pathname,
          statusCode: 401,
          summary: "Login gagal",
          metadata: { identity: normalizedIdentity }
        });
	      return NextResponse.json(
	        {
	          message: "Email/username atau password tidak valid"
	        },
	        { status: 401 }
	      );
	    }

    if (mustVerifyEmail && !user.emailVerifiedAt) {
      await createAuditTrailSafe({
        userId: user.id,
        action: "LOGIN_BLOCKED_UNVERIFIED",
        entityType: "AUTH",
        entityId: user.id,
        method: request.method,
        pathname: new URL(request.url).pathname,
        statusCode: 403,
        summary: "Login ditolak karena email belum diverifikasi"
      });
      return NextResponse.json(
        {
          message: "Email belum diverifikasi. Cek inbox Anda atau kirim ulang verifikasi."
        },
        { status: 403 }
      );
    }

	    const sessionUser = {
      id: user.id.toString(),
      name: user.name,
      role: user.role.code,
      email: user.email,
      username: user.username
    };
    const effectiveSessionTtlSeconds = rememberMe
      ? REMEMBER_ME_TTL_SECONDS
      : sessionTtlSeconds || getSessionTtlSeconds();
    const sessionToken = createSessionToken(sessionUser, effectiveSessionTtlSeconds);

    const response = NextResponse.json({
      message: "Login berhasil",
      data: {
        user: sessionUser,
        redirect_to: getDefaultPathForRole(sessionUser.role),
        session_token: sessionToken,
        token_type: "Bearer",
        expires_in: effectiveSessionTtlSeconds
      }
    });

	    response.cookies.set(
	      AUTH_COOKIE_NAME,
	      sessionToken,
	      getSessionCookieOptions(effectiveSessionTtlSeconds)
	    );

      await createAuditTrailSafe({
        userId: user.id,
        action: "LOGIN_SUCCESS",
        entityType: "AUTH",
        entityId: user.id,
        method: request.method,
        pathname: new URL(request.url).pathname,
        statusCode: 200,
        summary: "Login berhasil"
      });

	    return response;
  } catch (error) {
    return NextResponse.json(
      {
        message: error instanceof Error ? error.message : "Gagal login"
      },
      { status: 500 }
    );
  }
}
