import { Router } from "express";
import { db } from "@workspace/db";
import { transactionsTable, accountsTable, suppliersTable } from "@workspace/db";
import { eq, sql } from "drizzle-orm";

const router = Router();

// /api/supplier-statement?supplierId=X&from=&to=
router.get("/supplier-statement", async (req, res) => {
  const { supplierId, from, to } = req.query as Record<string, string>;
  if (!supplierId) return res.status(400).json({ error: "supplierId required" });
  const id = parseInt(supplierId);
  const [supplier] = await db.select().from(suppliersTable).where(eq(suppliersTable.id, id));
  if (!supplier) return res.status(404).json({ error: "Supplier not found" });

  let txRows = await db.select().from(transactionsTable).where(eq(transactionsTable.supplierId, id)).orderBy(sql`${transactionsTable.date} asc, ${transactionsTable.id} asc`);
  if (from) txRows = txRows.filter((r) => r.date >= from);
  if (to) txRows = txRows.filter((r) => r.date <= to);

  const transactions = await Promise.all(
    txRows.map(async (t) => {
      const [account] = await db.select().from(accountsTable).where(eq(accountsTable.id, t.accountId));
      return {
        id: t.id,
        type: t.type,
        date: t.date,
        documentNo: t.documentNo,
        accountId: t.accountId,
        accountName: account?.name ?? "",
        supplierId: t.supplierId ?? null,
        supplierName: supplier.name,
        amount: Number(t.amount),
        notes: t.notes ?? null,
        createdAt: t.createdAt.toISOString(),
      };
    })
  );

  const totalDebit = transactions.filter((t) => t.type === "payment").reduce((s, t) => s + t.amount, 0);
  const totalCredit = transactions.filter((t) => t.type === "receipt").reduce((s, t) => s + t.amount, 0);

  res.json({
    supplier: { id: supplier.id, name: supplier.name, phone: supplier.phone, address: supplier.address, notes: supplier.notes, balance: totalDebit - totalCredit, createdAt: supplier.createdAt.toISOString() },
    transactions,
    totalDebit,
    totalCredit,
    balance: totalDebit - totalCredit,
  });
});

// /api/account-statement?accountId=X&from=&to=
router.get("/account-statement", async (req, res) => {
  const { accountId, from, to } = req.query as Record<string, string>;
  if (!accountId) return res.status(400).json({ error: "accountId required" });
  const id = parseInt(accountId);
  const [account] = await db.select().from(accountsTable).where(eq(accountsTable.id, id));
  if (!account) return res.status(404).json({ error: "Account not found" });

  let txRows = await db.select().from(transactionsTable).where(eq(transactionsTable.accountId, id)).orderBy(sql`${transactionsTable.date} asc, ${transactionsTable.id} asc`);
  if (from) txRows = txRows.filter((r) => r.date >= from);
  if (to) txRows = txRows.filter((r) => r.date <= to);

  const transactions = await Promise.all(
    txRows.map(async (t) => {
      let supplierName: string | null = null;
      if (t.supplierId) {
        const [supplier] = await db.select().from(suppliersTable).where(eq(suppliersTable.id, t.supplierId));
        supplierName = supplier?.name ?? null;
      }
      return {
        id: t.id,
        type: t.type,
        date: t.date,
        documentNo: t.documentNo,
        accountId: t.accountId,
        accountName: account.name,
        supplierId: t.supplierId ?? null,
        supplierName,
        amount: Number(t.amount),
        notes: t.notes ?? null,
        createdAt: t.createdAt.toISOString(),
      };
    })
  );

  const totalCredit = transactions.filter((t) => t.type === "receipt").reduce((s, t) => s + t.amount, 0);
  const totalDebit = transactions.filter((t) => t.type === "payment").reduce((s, t) => s + t.amount, 0);

  res.json({
    account: { id: account.id, name: account.name, type: account.type, balance: Number(account.balance), notes: account.notes, createdAt: account.createdAt.toISOString() },
    transactions,
    totalDebit,
    totalCredit,
    balance: totalCredit - totalDebit,
  });
});

export default router;
