"use client";

import { useRef, useCallback } from "react";
import { useChatStore } from "@/lib/store";
import { consumeSSEChunk } from "@/lib/sse";

export function InputBar() {
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const isStreaming = useChatStore((s) => s.isStreaming);
  const addUserMessage = useChatStore((s) => s.addUserMessage);
  const startStreaming = useChatStore((s) => s.startStreaming);
  const appendToken = useChatStore((s) => s.appendToken);
  const finishStreaming = useChatStore((s) => s.finishStreaming);
  const setError = useChatStore((s) => s.setError);
  const messages = useChatStore((s) => s.messages);
  const activeConversationId = useChatStore((s) => s.activeConversationId);
  const personId = useChatStore((s) => s.personId);
  const createConversation = useChatStore((s) => s.createConversation);

  const send = useCallback(async () => {
    const textarea = textareaRef.current;
    if (!textarea) return;
    const content = textarea.value.trim();
    if (!content || isStreaming) return;

    textarea.value = "";

    // Auto-create conversation if none active
    let conversationId = activeConversationId;
    if (!conversationId) {
      conversationId = createConversation();
    }

    addUserMessage(content);

    const history = [
      ...messages.map((m) => ({ role: m.role, content: m.content })),
      { role: "user" as const, content },
    ];

    const assistantId = startStreaming();

    try {
      const res = await fetch("/api/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ messages: history, conversationId, personId }),
      });

      if (!res.ok) {
        throw new Error(`Server returned ${res.status}`);
      }

      const reader = res.body!.getReader();
      const decoder = new TextDecoder();
      let buffer = "";

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        const { jsonLines, buffer: next } = consumeSSEChunk(
          buffer,
          decoder.decode(value, { stream: true })
        );
        buffer = next;

        for (const jsonStr of jsonLines) {
          try {
            const data = JSON.parse(jsonStr);
            if (data.error) {
              setError(data.error);
              return;
            }
            if (data.token) {
              appendToken(assistantId, data.token);
            }
          } catch {
            // skip malformed
          }
        }
      }

      finishStreaming(assistantId);
    } catch (err) {
      const msg =
        err instanceof Error ? err.message : "Something went wrong";
      setError(msg);
    }

    textarea.focus();
  }, [
    isStreaming,
    messages,
    activeConversationId,
    personId,
    createConversation,
    addUserMessage,
    startStreaming,
    appendToken,
    finishStreaming,
    setError,
  ]);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "Enter" && !e.shiftKey) {
        e.preventDefault();
        send();
      }
    },
    [send]
  );

  return (
    <div className="border-t border-border px-4 py-3 md:px-8">
      <div className="max-w-2xl mx-auto flex items-end gap-3">
        <textarea
          ref={textareaRef}
          onKeyDown={handleKeyDown}
          placeholder="say something..."
          disabled={isStreaming}
          rows={1}
          className="flex-1 bg-bg-elevated text-text placeholder:text-text-faint rounded-xl px-4 py-3 text-[15px] leading-relaxed resize-none min-h-[48px] max-h-[160px] focus:outline-none focus:ring-1 focus:ring-accent/50 disabled:opacity-50 transition-opacity"
        />
        <button
          onClick={send}
          disabled={isStreaming}
          className="h-[48px] px-4 rounded-xl bg-accent-subtle text-accent hover:bg-accent-muted transition-colors disabled:opacity-30 disabled:cursor-not-allowed text-sm font-medium"
        >
          {isStreaming ? "..." : "send"}
        </button>
      </div>
    </div>
  );
}
