"use client";

import { useEffect, useRef, useState } from "react";
import type { PersonaInfo } from "./PersonaPicker";
import type { Message } from "./ChatPane";

interface Props {
  persona: PersonaInfo;
  apiBase: string;
}

type ColumnKey = "anthropic" | "lmstudio";

interface ColumnState {
  label: string;
  messages: Message[];
  sessionId: string | null;
  streaming: boolean;
  error: string | null;
}

const emptyColumn = (label: string): ColumnState => ({
  label,
  messages: [],
  sessionId: null,
  streaming: false,
  error: null,
});

export default function ComparePane({ persona, apiBase }: Props) {
  const [columns, setColumns] = useState<Record<ColumnKey, ColumnState>>({
    anthropic: emptyColumn("Frontier"),
    lmstudio: emptyColumn("Local"),
  });
  const [input, setInput] = useState("");
  const bottomRefAnthropic = useRef<HTMLDivElement>(null);
  const bottomRefLmstudio = useRef<HTMLDivElement>(null);
  const bottomRefs: Record<ColumnKey, React.RefObject<HTMLDivElement | null>> = {
    anthropic: bottomRefAnthropic,
    lmstudio: bottomRefLmstudio,
  };

  useEffect(() => {
    fetch(`${apiBase}/api/providers`)
      .then((r) => r.json())
      .then((data: { frontier_model: string; local_model: string }) => {
        setColumns((prev) => ({
          anthropic: { ...prev.anthropic, label: data.frontier_model },
          lmstudio: { ...prev.lmstudio, label: data.local_model },
        }));
      })
      .catch(() => {
        /* labels stay at their defaults if this fails */
      });
  }, [apiBase]);

  useEffect(() => {
    bottomRefAnthropic.current?.scrollIntoView({ behavior: "smooth" });
  }, [columns.anthropic.messages]);

  useEffect(() => {
    bottomRefLmstudio.current?.scrollIntoView({ behavior: "smooth" });
  }, [columns.lmstudio.messages]);

  const streamToColumn = async (key: ColumnKey, text: string) => {
    setColumns((prev) => ({
      ...prev,
      [key]: {
        ...prev[key],
        messages: [
          ...prev[key].messages,
          { role: "user", content: text },
          { role: "assistant", content: "", streaming: true },
        ],
        streaming: true,
        error: null,
      },
    }));

    try {
      const sessionId = columns[key].sessionId;
      const resp = await fetch(`${apiBase}/api/chat/${persona.slug}`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ message: text, session_id: sessionId, provider: key }),
      });

      if (!resp.ok || !resp.body) {
        throw new Error(`HTTP ${resp.status}`);
      }

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

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });

        const lines = buffer.split("\n");
        buffer = lines.pop() ?? "";

        for (const line of lines) {
          if (!line.startsWith("data: ")) continue;
          const payload = JSON.parse(line.slice(6));
          if (payload.type === "session") {
            setColumns((prev) => ({
              ...prev,
              [key]: { ...prev[key], sessionId: payload.session_id },
            }));
          } else if (payload.type === "text") {
            setColumns((prev) => {
              const msgs = [...prev[key].messages];
              const last = msgs[msgs.length - 1];
              if (last.role === "assistant") {
                msgs[msgs.length - 1] = { ...last, content: last.content + payload.text };
              }
              return { ...prev, [key]: { ...prev[key], messages: msgs } };
            });
          } else if (payload.type === "done") {
            setColumns((prev) => {
              const msgs = [...prev[key].messages];
              const last = msgs[msgs.length - 1];
              if (last.role === "assistant") {
                msgs[msgs.length - 1] = { ...last, streaming: false };
              }
              return { ...prev, [key]: { ...prev[key], messages: msgs, streaming: false } };
            });
          }
        }
      }
    } catch (err) {
      setColumns((prev) => {
        const msgs = [...prev[key].messages];
        const last = msgs[msgs.length - 1];
        if (last?.role === "assistant") {
          msgs[msgs.length - 1] = { ...last, content: `[Error: ${String(err)}]`, streaming: false };
        }
        return { ...prev, [key]: { ...prev[key], messages: msgs, streaming: false, error: String(err) } };
      });
    }
  };

  const sendToBoth = () => {
    const text = input.trim();
    if (!text || columns.anthropic.streaming || columns.lmstudio.streaming) return;
    setInput("");
    void streamToColumn("anthropic", text);
    void streamToColumn("lmstudio", text);
  };

  const onKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      sendToBoth();
    }
  };

  const disabled = columns.anthropic.streaming || columns.lmstudio.streaming;

  return (
    <div style={styles.container}>
      <div style={styles.columns}>
        {(["anthropic", "lmstudio"] as ColumnKey[]).map((key) => (
          <div key={key} style={styles.column}>
            <div style={styles.header}>
              <span style={styles.headerKind}>
                {key === "anthropic" ? "Frontier" : "Local"}
              </span>
              <span style={styles.headerModel}>{columns[key].label}</span>
            </div>
            <div style={styles.messages}>
              {columns[key].messages.length === 0 && (
                <div style={styles.empty}>Ask {persona.display_name} something below.</div>
              )}
              {columns[key].messages.map((msg, i) => (
                <div
                  key={i}
                  style={{
                    ...styles.bubble,
                    ...(msg.role === "user" ? styles.userBubble : styles.assistantBubble),
                  }}
                >
                  <span style={styles.role}>
                    {msg.role === "user" ? "You" : persona.display_name}
                  </span>
                  <p style={styles.text}>
                    {msg.content}
                    {msg.streaming && <span style={styles.cursor}>▌</span>}
                  </p>
                </div>
              ))}
              <div ref={bottomRefs[key]} />
            </div>
          </div>
        ))}
      </div>

      <div style={styles.inputRow}>
        <textarea
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={onKeyDown}
          placeholder={`Ask ${persona.display_name} something — sent to both panes…`}
          disabled={disabled}
          rows={2}
          style={styles.textarea}
        />
        <button
          onClick={sendToBoth}
          disabled={disabled || !input.trim()}
          style={{
            ...styles.sendBtn,
            ...(disabled || !input.trim() ? styles.sendBtnDisabled : {}),
          }}
        >
          Send to both
        </button>
      </div>
    </div>
  );
}

const styles: Record<string, React.CSSProperties> = {
  container: {
    display: "flex",
    flexDirection: "column",
    height: "100%",
    background: "var(--bg)",
  },
  columns: {
    flex: 1,
    display: "flex",
    overflow: "hidden",
  },
  column: {
    flex: 1,
    display: "flex",
    flexDirection: "column",
    minWidth: 0,
    borderRight: "1px solid var(--border)",
  },
  header: {
    padding: "14px 20px",
    borderBottom: "1px solid var(--border)",
    display: "flex",
    flexDirection: "column",
    gap: "2px",
    background: "var(--surface)",
  },
  headerKind: {
    fontWeight: 700,
    color: "var(--accent)",
    fontSize: "14px",
    textTransform: "uppercase",
    letterSpacing: "0.05em",
  },
  headerModel: {
    color: "var(--text-muted)",
    fontSize: "12px",
  },
  messages: {
    flex: 1,
    overflowY: "auto",
    padding: "16px",
    display: "flex",
    flexDirection: "column",
    gap: "12px",
  },
  empty: {
    color: "var(--text-muted)",
    fontStyle: "italic",
    textAlign: "center",
    marginTop: "40px",
    fontSize: "13px",
  },
  bubble: {
    display: "flex",
    flexDirection: "column",
    gap: "4px",
  },
  userBubble: {
    alignSelf: "flex-end",
    alignItems: "flex-end",
  },
  assistantBubble: {
    alignSelf: "flex-start",
    alignItems: "flex-start",
  },
  role: {
    fontSize: "10px",
    color: "var(--text-muted)",
    fontWeight: 600,
    textTransform: "uppercase",
    letterSpacing: "0.05em",
  },
  text: {
    background: "var(--surface)",
    padding: "8px 12px",
    borderRadius: "var(--radius)",
    lineHeight: 1.6,
    fontSize: "13px",
    border: "1px solid var(--border)",
    whiteSpace: "pre-wrap",
  },
  cursor: {
    animation: "blink 1s step-end infinite",
    color: "var(--accent)",
  },
  inputRow: {
    display: "flex",
    gap: "8px",
    padding: "14px 20px",
    borderTop: "1px solid var(--border)",
    background: "var(--surface)",
  },
  textarea: {
    flex: 1,
    padding: "10px 14px",
    borderRadius: "var(--radius)",
    border: "1px solid var(--border)",
    background: "var(--bg)",
    color: "var(--text)",
    resize: "none",
    outline: "none",
  },
  sendBtn: {
    padding: "0 20px",
    background: "var(--accent)",
    color: "#000",
    borderRadius: "var(--radius)",
    fontWeight: 600,
    fontSize: "13px",
    transition: "opacity 0.15s",
  },
  sendBtnDisabled: {
    opacity: 0.4,
    cursor: "default",
  },
};
