import express, { Request, Response } from "express";
import process from "node:process";
import { fromFileUrl } from "@std/path";
import { dirname } from "@std/path";
import path from "node:path";
import { PrismaClient } from "./generated/client.ts";

const __dirname = dirname(fromFileUrl(import.meta.url));
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());

app.use(express.static(path.join(__dirname, "public")));

const prisma = new PrismaClient();

const customers = await prisma.customer.findMany();

app.get("/customers",  async (_req: Request, res: Response) => {
  const customers = await prisma.customer.findMany();
  res.json(customers);
});

app.get("/customers/:id",  async (req: Request, res: Response) => {
  const id = parseInt(req.params.id);
  const customer = await prisma.customer.findUnique({
    where: { id },
  });

  if (!customer) {
    return res.status(404).json({ error: "Customer not found" });
  }

  res.json(customer);
});

app.post("/customers", async (req: Request, res: Response) => {
  const { name, balance } = req.body;

  if (!name || !balance) {
    return res.status(400).json({ error: "Name and balance are required!" });
  }

  const newCustomer = await prisma.customer.create({
    data: { name, balance }
  });
  res.status(201).json(newCustomer);
});

app.put("/customers/:id", async(req: Request, res: Response) => {
  const id = parseInt(req.params.id);
  const { name, balance } = req.body;

  if (!name || !balance) {
    return res.status(400).json({ error: "Name and balance are required!" });
  }

  try {
    const updatedCustomer = await prisma.customer.update({
      where: { id },
      data: { name, balance: Number(balance) }
    });
    res.json(updatedCustomer);
  } catch {
    return res.status(404).json({ error: "Customer not found" });
  }

});

app.patch("/customers/:id", async (req: Request, res: Response) => {
  const id = parseInt(req.params.id);
  const { name, balance } = req.body;

  const data: { name?: string; balance?: number } = {};

  if (name !== undefined) data.name = name;
  if (balance !== undefined) data.balance = Number(balance);

  try {
    const updatedCustomer = await prisma.customer.update({
      where: { id },
      data
    });

    res.json(updatedCustomer);
  } catch {
    return res.status(404).json({ error: "Customer not found" });
  }
});

app.delete("/customers/:id", async (req: Request, res: Response) => {
  const id = parseInt(req.params.id);

  try {
    await prisma.customer.delete({
      where: { id }
    });

    return res.status(204).send(); // No Content
  } catch {
    return res.status(404).json({ error: "Customer not found" });
  }
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});