/**
 * Expenses API - List and Create
 * GET /api/dashboard/expenses - List expenses with filters
 * POST /api/dashboard/expenses - Create new expense
 *
 * Wired directly to Convex (no Prisma fallback).
 */

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { getAuthenticatedUser } from "@/lib/utils/auth-helpers.util";
import { logger } from "@/lib/logger";
import { convexQuery, convexMutation } from "@/lib/convex-client";

const log = logger.scope("ExpensesAPI");

export const dynamic = "force-dynamic";
export const runtime = "nodejs";

export async function GET(request: NextRequest) {
  try {
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    if (getDataSource("expenses") === "convex") {
      try {
        const { convexQuery } = await import("@/lib/convex-client");
        const result = await convexQuery("expenses/queries:getExpenses", {
          userId: user.userId,
          limit: 50,
        });
        if (result !== null) {
          return NextResponse.json({ expenses: result, success: true });
        }
      } catch {
        // Fall through to Prisma
      }
    }

    const effectiveUserId = await getEffectiveOwnerId(user.userId);
    const params = Object.fromEntries(request.nextUrl.searchParams.entries());
    const categoryId = params.categoryId || undefined;
    const limit = params.limit ? parseInt(params.limit, 10) : 50;

    const expenses = await convexQuery("expenses/queries:getExpenses", {
      userId: user.userId,
      categoryId,
      limit: Number.isFinite(limit) ? limit : 50,
    });

    return NextResponse.json({
      success: true,
      expenses: expenses ?? [],
    });
  } catch (error) {
    log.error("Failed to list expenses", error);
    return NextResponse.json(
      { success: false, error: "Internal server error" },
      { status: 500 },
    );
  }
}

export async function POST(request: NextRequest) {
  try {
    const user = await getAuthenticatedUser(request, auth);
    if (!user) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const body = await request.json();

    // Inline validation — categoryId and amount are required
    if (!body.categoryId || typeof body.categoryId !== "string") {
      return NextResponse.json(
        { success: false, error: "categoryId is required" },
        { status: 400 },
      );
    }
    if (typeof body.amount !== "number" || body.amount <= 0) {
      return NextResponse.json(
        { success: false, error: "amount must be a positive number" },
        { status: 400 },
      );
    }

    const expenseId = await convexMutation("expenses/mutations:createExpense", {
      userId: user.userId,
      categoryId: body.categoryId,
      amount: body.amount,
      currency: body.currency ?? undefined,
      vendor: body.vendor ?? undefined,
      description: body.description ?? undefined,
      date: typeof body.date === "number" ? body.date : Date.now(),
      receiptUrl: body.receiptUrl ?? undefined,
      isRecurring: body.isRecurring ?? undefined,
      recurringFrequency: body.recurringFrequency ?? undefined,
      tags: Array.isArray(body.tags) ? body.tags : undefined,
      notes: body.notes ?? undefined,
    });

    return NextResponse.json(
      { success: true, expense: { id: expenseId } },
      { status: 201 },
    );
  } catch (error) {
    const message =
      error instanceof Error ? error.message : "Internal server error";
    log.error("Failed to create expense", error);
    return NextResponse.json(
      { success: false, error: message },
      { status: message === "Category not found" ? 400 : 500 },
    );
  }
}
