"use client";

import { useRef, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";

interface ChatMessage {
  role: "user" | "assistant";
  content: string;
}

interface DocChatProps {
  /** The document title shown above the chat. */
  title?: string;
  /** Plain-text document content the assistant can read. */
  content: string;
  /** Initial prompts shown above the input when the chat is empty. */
  suggestions?: string[];
  /** Compact mode shrinks padding + hides the heading row. */
  compact?: boolean;
}

/**
 * Reusable reader3-style document chat panel. Drop into any page that has
 * a chunk of text it wants to make queryable.
 *
 * Inspiration: https://github.com/karpathy/reader3
 */
export function DocChat({ title, content, suggestions = [], compact = false }: DocChatProps) {
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [input, setInput] = useState("");
  const [pending, setPending] = useState(false);
  const [error, setError] = useState<string>("");
  const inputRef = useRef<HTMLInputElement>(null);

  async function send(text: string) {
    const trimmed = text.trim();
    if (!trimmed || pending) return;
    const next = [...messages, { role: "user" as const, content: trimmed }];
    setMessages(next);
    setInput("");
    setError("");
    setPending(true);
    try {
      const resp = await fetch("/api/reader/chat", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          doc: { title, content },
          messages: next,
        }),
      });
      const data = await resp.json();
      if (!resp.ok) throw new Error(data.error || "Failed");
      setMessages([...next, { role: "assistant", content: data.message }]);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Unknown error");
    } finally {
      setPending(false);
      // Refocus input so the user can keep typing.
      setTimeout(() => inputRef.current?.focus(), 0);
    }
  }

  const contentBytes = new Blob([content]).size;

  return (
    <Card>
      <CardContent className={compact ? "p-3 space-y-2" : "p-4 space-y-3"}>
        {!compact && (
          <div className="flex items-center justify-between gap-2 flex-wrap">
            <h3 className="text-sm font-semibold inline-flex items-center gap-2">
              💬 Ask about this {title ? `“${title}”` : "document"}
            </h3>
            <Badge variant="outline" className="text-[10px]">
              {Math.ceil(contentBytes / 1024)} KB context
            </Badge>
          </div>
        )}

        <div className="space-y-2 max-h-96 overflow-y-auto">
          {messages.length === 0 ? (
            <div className="rounded-md border border-dashed bg-muted/30 p-3 text-xs text-muted-foreground">
              Ask anything answerable from the document. The assistant answers from the text only;
              it will say so if the answer isn’t there.
              {suggestions.length > 0 && (
                <div className="mt-2 flex flex-wrap gap-1">
                  {suggestions.map((s, i) => (
                    <button
                      key={i}
                      onClick={() => void send(s)}
                      className="text-[11px] px-2 py-1 rounded-full border bg-background hover:bg-accent"
                    >
                      {s}
                    </button>
                  ))}
                </div>
              )}
            </div>
          ) : (
            messages.map((m, i) => (
              <div
                key={i}
                className={`rounded-md border p-3 text-sm whitespace-pre-wrap ${
                  m.role === "user"
                    ? "bg-muted/40 border-input"
                    : "bg-background border-input"
                }`}
              >
                <div className="section-label mb-1">
                  {m.role === "user" ? "You" : "Reader"}
                </div>
                {m.content}
              </div>
            ))
          )}
          {pending && (
            <div className="rounded-md border border-dashed bg-muted/30 p-3 text-sm text-muted-foreground">
              Reader is thinking…
            </div>
          )}
        </div>

        {error && <p className="text-xs text-destructive">{error}</p>}

        <form
          onSubmit={(e) => {
            e.preventDefault();
            void send(input);
          }}
          className="flex items-center gap-2"
        >
          <input
            ref={inputRef}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="Ask a question…"
            disabled={pending}
            className="flex-1 h-10 rounded-md border border-input bg-background px-3 text-sm"
          />
          <Button type="submit" variant="brand" size="sm" disabled={pending || !input.trim()}>
            Ask
          </Button>
          {messages.length > 0 && (
            <Button
              type="button"
              variant="ghost"
              size="sm"
              onClick={() => {
                setMessages([]);
                setError("");
              }}
            >
              Clear
            </Button>
          )}
        </form>
      </CardContent>
    </Card>
  );
}
