import type { Context } from "hono";
import { prisma } from "../../../lib/prisma";
import type { QuoteType } from "../../../generated/prisma/client";

const VALID_TYPES = ["BLUE", "BNA", "BELO"] as const;

export async function getDailyMinMax(c: Context) {
  const rawType = c.req.param("type")!.toUpperCase();

  if (!VALID_TYPES.includes(rawType as typeof VALID_TYPES[number])) {
    return c.json({ error: `Invalid quote type. Must be one of: ${VALID_TYPES.join(", ")}` }, 400);
  }

  const startDateParam = c.req.query("startDate");
  const endDateParam = c.req.query("endDate");

  const now = new Date();
  const startDate = startDateParam
    ? new Date(startDateParam)
    : new Date(now.getFullYear(), now.getMonth(), 1);
  const endDate = endDateParam
    ? new Date(new Date(endDateParam).getTime() + 86_400_000)
    : now;

  if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) {
    return c.json({ error: "Invalid date format. Use ISO 8601." }, 400);
  }

  const rows = await prisma.$queryRaw<Array<{
    date: string;
    minBuy: number;
    maxBuy: number;
    minSell: number;
    maxSell: number;
  }>>`
    SELECT
      DATE("timeStamp")::text AS date,
      MIN(buy::numeric)::float8 AS "minBuy",
      MAX(buy::numeric)::float8 AS "maxBuy",
      MIN(sell::numeric)::float8 AS "minSell",
      MAX(sell::numeric)::float8 AS "maxSell"
    FROM "quotes_history"
    WHERE "type" = ${rawType}::"QuoteType"
      AND "timeStamp" >= ${startDate}::timestamptz
      AND "timeStamp" < ${endDate}::timestamptz
    GROUP BY DATE("timeStamp")
    ORDER BY DATE("timeStamp") ASC
  `;

  if (rows.length === 0) {
    const current = await prisma.quote.findFirst({
      where: { type: rawType as QuoteType },
      orderBy: { timeStamp: "desc" },
    });

    if (current) {
      const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
      return c.json([
        {
          date: today,
          minBuy: Number(current.buy),
          maxBuy: Number(current.buy),
          minSell: Number(current.sell),
          maxSell: Number(current.sell),
        },
      ]);
    }
  }

  return c.json(rows);
}
