import { NextResponse } from "next/server";

import { serializeAgent } from "@/features/agents/lib/serialize-agent";
import { requireApiAccess } from "@/lib/authorization";
import { prisma } from "@/lib/prisma";

type RouteContext = { params: Promise<{ id: string }> };

function parseId(id: string) {
  try {
    return BigInt(id);
  } catch {
    return null;
  }
}

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

  const parsedId = parseId((await context.params).id);
  if (parsedId === null) return NextResponse.json({ message: "Invalid id" }, { status: 400 });

  const agent = await prisma.agent.findUnique({
    where: { id: parsedId },
    include: {
      profitShareScheme: true,
      bankAccounts: { include: { bank: true } },
      _count: {
        select: {
          purchases: true
        }
      }
    }
  });

  if (!agent) {
    return NextResponse.json({ message: "Agent not found" }, { status: 404 });
  }

  const [mutations, consignmentCount, regularSaleCount] = await Promise.all([
    prisma.agentBalanceMutation.findMany({
      where: { agentId: parsedId },
      orderBy: [{ occurredAt: "asc" }, { id: "asc" }]
    }),
    prisma.consignmentLine.count({
      where: {
        status: "CLOSED",
        agentCommission: { gt: 0 },
        lot: {
          purchase: {
            agentId: parsedId
          }
        }
      }
    }),
    prisma.regularSaleLine.findMany({
      where: {
        agentId: parsedId,
        regularSale: {
          status: "CLOSED"
        }
      },
      select: {
        regularSaleId: true
      },
      distinct: ["regularSaleId"]
    })
  ]);

  return NextResponse.json({
    data: {
      ...serializeAgent(agent),
      stats: {
        purchase_count: agent._count.purchases,
        consignment_close_count: consignmentCount,
        regular_sale_close_count: regularSaleCount.length,
        history_count: mutations.length
      },
      balance_history: mutations.map((item) => ({
        id: item.id.toString(),
        balance_type: item.balanceType as "PROFIT_SHARE" | "CAPITAL",
        source: item.source as
          | "OPENING_BALANCE"
          | "MANUAL_ADJUSTMENT"
          | "CONSIGNMENT_COMMISSION"
          | "REGULAR_SALE_COMMISSION"
          | "JIT_SALE_COMMISSION"
          | "OFFICE_BUYOUT_COMMISSION"
          | "FUND_REQUEST_PROFIT_SHARE"
          | "FUND_REQUEST_CAPITAL",
        direction: item.direction as "IN" | "OUT",
        amount: item.amount.toNumber(),
        balance_after: item.balanceAfter.toNumber(),
        occurred_at: item.occurredAt.toISOString(),
        effective_date: item.effectiveDate?.toISOString().slice(0, 10) ?? null,
        reference_no: item.referenceNo,
        description:
          item.notes ??
          (item.source === "CONSIGNMENT_COMMISSION"
            ? "Komisi agen dari titip jual"
            : item.source === "REGULAR_SALE_COMMISSION"
              ? "Komisi agen dari penjualan reguler"
              : item.source === "JIT_SALE_COMMISSION"
                ? "Komisi agen dari penjualan just in time"
                : item.source === "OFFICE_BUYOUT_COMMISSION"
                  ? "Komisi agen dari pembelian kantor / buyout"
                : item.source === "FUND_REQUEST_PROFIT_SHARE"
                  ? "Transfer dana bagi hasil ke agen"
                  : item.source === "FUND_REQUEST_CAPITAL"
                    ? "Transfer dana modal ke agen"
                : item.source === "MANUAL_ADJUSTMENT"
                  ? "Penyesuaian manual saldo agen"
                  : "Saldo pembuka agen"),
        notes: item.referenceType
          ? `${item.referenceType}${item.referenceId ? ` · ${item.referenceId}` : ""}`
          : null
      }))
    }
  });
}
