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

const router = Router();

async function formatPayment(p: typeof paymentsTable.$inferSelect) {
  const [account] = await db.select().from(accountsTable).where(eq(accountsTable.id, p.accountId));
  let supplierName: string | null = null;
  let factoryName: string | null = null;
  if (p.supplierId) {
    const [s] = await db.select().from(suppliersTable).where(eq(suppliersTable.id, p.supplierId));
    supplierName = s?.name ?? null;
  }
  if (p.factoryId) {
    const [f] = await db.select().from(factoriesTable).where(eq(factoriesTable.id, p.factoryId));
    factoryName = f?.name ?? null;
  }
  return {
    id: p.id,
    date: p.date,
    amount: Number(p.amount),
    accountId: p.accountId,
    accountName: account?.name ?? "",
    supplierId: p.supplierId ?? null,
    supplierName,
    factoryId: p.factoryId ?? null,
    factoryName,
    notes: p.notes ?? null,
    createdAt: p.createdAt.toISOString(),
  };
}

router.get("/", async (req, res) => {
  const { supplierId, factoryId } = req.query as Record<string, string>;
  let rows = await db.select().from(paymentsTable).orderBy(sql`${paymentsTable.date} desc, ${paymentsTable.id} desc`);
  if (supplierId) rows = rows.filter((r) => r.supplierId === parseInt(supplierId));
  if (factoryId) rows = rows.filter((r) => r.factoryId === parseInt(factoryId));
  const result = await Promise.all(rows.map(formatPayment));
  res.json(result);
});

router.post("/", async (req, res) => {
  const { date, amount, accountId, supplierId, factoryId, notes } = req.body;
  if (!date || !amount || !accountId) return res.status(400).json({ error: "Missing required fields" });
  const [p] = await db
    .insert(paymentsTable)
    .values({
      date,
      amount: String(amount),
      accountId: parseInt(accountId),
      supplierId: supplierId ? parseInt(supplierId) : null,
      factoryId: factoryId ? parseInt(factoryId) : null,
      notes,
    })
    .returning();
  // Deduct from account balance
  await db
    .update(accountsTable)
    .set({ balance: sql`${accountsTable.balance} - ${String(amount)}` })
    .where(eq(accountsTable.id, parseInt(accountId)));
  res.status(201).json(await formatPayment(p));
});

router.delete("/:id", async (req, res) => {
  const id = parseInt(req.params.id);
  const [p] = await db.select().from(paymentsTable).where(eq(paymentsTable.id, id));
  if (p) {
    // Reverse balance effect
    await db
      .update(accountsTable)
      .set({ balance: sql`${accountsTable.balance} + ${String(p.amount)}` })
      .where(eq(accountsTable.id, p.accountId));
    await db.delete(paymentsTable).where(eq(paymentsTable.id, id));
  }
  res.status(204).end();
});

export default router;
