import { Hono } from "hono";
import * as z from "zod";

import { getCopilotHistory, streamCopilot } from "@turbostarter/ai/copilot/api";
import { copilotMessageSchema } from "@turbostarter/ai/copilot/schema";
import { inferDiagramType } from "@turbostarter/ai/copilot/type-inference";

import { enforceAuth, deductCredits, rateLimiter, validate } from "../../../middleware";

import type { User } from "@turbostarter/auth";

const chatIdQuerySchema = z.object({
  chatId: z.string(),
});

const inferTypeSchema = z.object({
  description: z.string().min(3).max(500),
});

export const copilotRouter = new Hono<{
  Variables: {
    user: User;
  };
}>()
  .get(
    "/messages",
    enforceAuth,
    validate("query", chatIdQuerySchema),
    async (c) => {
      const { chatId } = c.req.valid("query");
      const messages = await getCopilotHistory(chatId);
      return c.json(messages);
    },
  )
  .post(
    "/infer-type",
    enforceAuth,
    rateLimiter,
    validate("json", inferTypeSchema),
    async (c) => {
      const { description } = c.req.valid("json");
      const result = await inferDiagramType(description);
      return c.json(result);
    },
  )
  .post(
    "/",
    enforceAuth,
    rateLimiter,
    validate("json", copilotMessageSchema),
    async (c) => {
      const input = c.req.valid("json");

      // Deduct 1 credit per copilot message
      await deductCredits(1, "copilot")(c, async () => { /* noop */ });

      return streamCopilot({
        ...input,
        signal: c.req.raw.signal,
        userId: c.var.user.id,
      });
    },
  );
