import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";

export interface BudMessage {
  id: string;
  role: "user" | "assistant";
  content: string;
  created_at: string;
}

const GATEWAY = "https://ai.gateway.lovable.dev/v1/chat/completions";

const SYSTEM = `You are ChatBud, the friendly companion assistant of Gatavase Corporation (Kampala, Uganda and Doha, Qatar).
You help visitors explore Gatavase's services (website, app, software development, networking, graphics design, computer training, robotics, AI),
products (Kabo Browser, Secure Guard, Gatavase Search, GataMail, Gatavase Messenger, Gatavase Bolt, Books, Podcast, Radio) and divisions.
Be warm, concise and concrete, use short paragraphs or bullets, never invent prices or client names, and point people to paths like /demo-request, /contact, /gatavase-ai or /studio when useful.`;

const sessionSchema = z.string().trim().min(8).max(80);

async function admin() {
  const { supabaseAdmin } = await import("@/integrations/supabase/client.server");
  return supabaseAdmin;
}

export const loadBudThread = createServerFn({ method: "POST" })
  .inputValidator((input: unknown) => z.object({ sessionId: sessionSchema }).parse(input))
  .handler(async ({ data }) => {
    const db = await admin();
    const { data: convo } = await db
      .from("chatbud_conversations")
      .select("id, title, created_at")
      .eq("session_id", data.sessionId)
      .order("updated_at", { ascending: false })
      .limit(1)
      .maybeSingle();
    if (!convo) return { conversationId: null as string | null, messages: [] as BudMessage[] };

    const { data: rows } = await db
      .from("chatbud_messages")
      .select("id, role, content, created_at")
      .eq("conversation_id", convo.id)
      .order("created_at")
      .limit(200);
    return { conversationId: convo.id as string, messages: (rows ?? []) as BudMessage[] };
  });

export const sendBudMessage = createServerFn({ method: "POST" })
  .inputValidator((input: unknown) =>
    z
      .object({
        sessionId: sessionSchema,
        conversationId: z.string().uuid().nullable().default(null),
        message: z.string().trim().min(1).max(4000),
      })
      .parse(input),
  )
  .handler(async ({ data }) => {
    const db = await admin();

    let conversationId = data.conversationId;
    if (!conversationId) {
      const { data: created, error } = await db
        .from("chatbud_conversations")
        .insert({
          session_id: data.sessionId,
          title: data.message.slice(0, 60),
        })
        .select("id")
        .single();
      if (error) throw new Error(error.message);
      conversationId = created.id as string;
    }

    await db
      .from("chatbud_messages")
      .insert({ conversation_id: conversationId, role: "user", content: data.message });

    const { data: history } = await db
      .from("chatbud_messages")
      .select("role, content")
      .eq("conversation_id", conversationId)
      .order("created_at")
      .limit(40);

    const key = process.env.LOVABLE_API_KEY;
    let reply = "ChatBud is offline right now. Please email gazmanadvancedtechnologies@gmail.com.";
    if (key) {
      const res = await fetch(GATEWAY, {
        method: "POST",
        headers: { "content-type": "application/json", "Lovable-API-Key": key },
        body: JSON.stringify({
          model: "google/gemini-2.5-flash",
          messages: [
            { role: "system", content: SYSTEM },
            ...((history ?? []) as { role: string; content: string }[]),
          ],
        }),
      });
      if (res.status === 429) throw new Error("ChatBud is busy. Please try again in a moment.");
      if (res.status === 402) throw new Error("AI credits exhausted. Please top up to continue.");
      if (res.ok) {
        const json = (await res.json()) as { choices?: { message?: { content?: string } }[] };
        reply = json.choices?.[0]?.message?.content?.trim() || reply;
      }
    }

    const { data: saved } = await db
      .from("chatbud_messages")
      .insert({ conversation_id: conversationId, role: "assistant", content: reply })
      .select("id, role, content, created_at")
      .single();

    await db
      .from("chatbud_conversations")
      .update({ updated_at: new Date().toISOString() })
      .eq("id", conversationId);

    return { conversationId, reply: saved as unknown as BudMessage };
  });
