import { NextRequest, NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth";
import { getTransactions } from "@/lib/queries";
import { queryRaw } from "@/lib/db";
import { completeSplit } from "@/lib/splits";

export async function GET(req: NextRequest) {
  const user = await getCurrentUser(req);
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 403 });

  const sp = req.nextUrl.searchParams;
  const parseArr = (key: string) => { const v = sp.get(key); return v ? v.split(",").filter(Boolean) : undefined; };
  const result = await getTransactions(user.id, {
    from: sp.get("from") || undefined,
    to: sp.get("to") || undefined,
    categories: parseArr("categories"),
    exclude_categories: parseArr("exclude_categories"),
    bank_names: parseArr("bank_names"),
    tag_ids: parseArr("tag_ids"),
    transaction_types: parseArr("transaction_types"),
    search: sp.get("search") || undefined,
    statement_id: sp.get("statement_id") || undefined,
    sort_by: sp.get("sort_by") || undefined,
    sort_dir: sp.get("sort_dir") || undefined,
    limit: sp.get("limit") ? Number(sp.get("limit")) : undefined,
    offset: sp.get("offset") ? Number(sp.get("offset")) : undefined,
    amount_min: sp.get("amount_min") ? Number(sp.get("amount_min")) : undefined,
    amount_max: sp.get("amount_max") ? Number(sp.get("amount_max")) : undefined,
    has_split: sp.get("has_split") || undefined,
    trip_id: sp.get("trip_id") || undefined,
    trip_all_rows: sp.get("trip_all_rows") === "1" || undefined,
  });

  return NextResponse.json(result);
}

export async function POST(req: NextRequest) {
  const user = await getCurrentUser(req);
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 403 });

  const body = await req.json() as {
    date: string;
    description: string;
    amount: number;
    transaction_type?: string;
    merchant_normalized?: string;
    category?: string;
    payment_method?: string;
    splits?: { participant_id: number; share_percent: number }[];
  };

  if (!body.date || !body.description || body.amount == null) {
    return NextResponse.json({ error: "date, description, amount are required" }, { status: 400 });
  }

  // Insert manual transaction with no statement (statement_id = NULL, owner_id set directly)
  const txRows = await queryRaw<{ id: number }>(
    `INSERT INTO transactions (statement_id, owner_id, transaction_date, description, amount, transaction_type, merchant_normalized, category, payment_method, row_index)
     VALUES (NULL, $1, $2, $3, $4, $5, $6, $7, $8, (
       SELECT COALESCE(MAX(row_index), -1) + 1 FROM transactions WHERE owner_id = $1 AND statement_id IS NULL
     ))
     RETURNING id`,
    [
      user.id,
      body.date,
      body.description,
      body.amount,
      body.transaction_type || "debit",
      body.merchant_normalized || null,
      body.category || null,
      body.payment_method || null,
    ]
  );
  const transactionId = txRows[0].id;

  // Insert splits if provided
  if (body.splits?.length) {
    for (const s of body.splits) {
      await queryRaw(
        `INSERT INTO transaction_splits (transaction_id, participant_id, share_percent)
         VALUES ($1, $2, $3) ON CONFLICT DO NOTHING`,
        [transactionId, s.participant_id, s.share_percent]
      );
    }
    // The form lets you name just the other person and shows the total in amber
    // when it is under 100 — which is how "Lawn Mowing, Sonu 50%" was saved with
    // the other half nowhere. Fill in the payer's share rather than refusing:
    // naming only the other person is a reasonable thing to mean.
    await completeSplit(transactionId);
  }

  return NextResponse.json({ id: transactionId }, { status: 201 });
}
