import { and, asc, eq } from "drizzle-orm";
import { cards, financialAccounts, transactions } from "@/db/schema";
import {
	buildDashboardAdminPeriodFilters,
	excludeAutoGeneratedEntryNotes,
} from "@/features/dashboard/transaction-filters";
import { db } from "@/shared/lib/db";
import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id";
import { safeToNumber as toNumber } from "@/shared/utils/number";

export type TopExpense = {
	id: string;
	name: string;
	amount: number;
	purchaseDate: Date;
	paymentMethod: string;
	logo?: string | null;
};

export type TopExpensesData = {
	expenses: TopExpense[];
};

export async function fetchTopExpenses(
	userId: string,
	period: string,
	cardOnly: boolean = false,
): Promise<TopExpensesData> {
	const adminPayerId = await getAdminPayerId(userId);
	if (!adminPayerId) {
		return { expenses: [] };
	}

	const conditions = [
		...buildDashboardAdminPeriodFilters({
			userId,
			period,
			adminPayerId,
		}),
		eq(transactions.transactionType, "Despesa"),
		excludeAutoGeneratedEntryNotes(),
	];

	// Se cardOnly for true, filtra apenas pagamentos com cartão
	if (cardOnly) {
		conditions.push(eq(transactions.paymentMethod, "Cartão de Crédito"));
	}

	const results = await db
		.select({
			id: transactions.id,
			name: transactions.name,
			amount: transactions.amount,
			purchaseDate: transactions.purchaseDate,
			paymentMethod: transactions.paymentMethod,
			cardId: transactions.cardId,
			accountId: transactions.accountId,
			cardLogo: cards.logo,
			accountLogo: financialAccounts.logo,
		})
		.from(transactions)
		.leftJoin(cards, eq(transactions.cardId, cards.id))
		.leftJoin(
			financialAccounts,
			eq(transactions.accountId, financialAccounts.id),
		)
		.where(and(...conditions))
		.orderBy(asc(transactions.amount))
		.limit(10);

	const expenses = results.map(
		(row: (typeof results)[number]): TopExpense => ({
			id: row.id,
			name: row.name,
			amount: Math.abs(toNumber(row.amount)),
			purchaseDate: row.purchaseDate,
			paymentMethod: row.paymentMethod,
			logo: row.cardLogo ?? row.accountLogo ?? null,
		}),
	);

	return {
		expenses,
	};
}
