"use client";

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

export interface Message {
  role: "user" | "assistant";
  content: string;
  streaming?: boolean;
}

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

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

export default function ComparePane({ persona, apiBase }: Props) {
  const [input, setInput] = useState("");
  const [columns, setColumns] = useState<Record<string, ColumnState>>({
    anthropic: {
      messages: [],
      sessionId: null,
      streaming: false,
    },
    lmstudio: {
      messages: [],
      sessionId: null,
      streaming: false,
    },
  });
  const [modelIds, setModelIds] = useState<Record<string, string>>({
    anthropic: "Frontier",
    lmstudio: "Local",
  });
  const bottomRefs = {
    anthropic: useRef<HTMLDivElement>(null),
    lmstudio: useRef<HTMLDivElement>(null),
  };

  // Scroll to bottom on new messages
  useEffect(() => {
    Object.values(bottomRefs).forEach(ref => ref.current?.scrollIntoView({ behavior: "smooth" }));
  }, []);

  // Fetch model IDs on mount
  useEffect(() => {
    const fetchModelIds = async () => {
      try {
        const resp = await fetch(`${apiBase}/api/providers`);
        if (resp.ok) {
          const data = await resp.json();
          setModelIds({
            anthropic: data.frontier_model,
            lmstudio: data.local_model,
          });
        }
      } catch (err) {
        // Fall back to generic labels if fetch fails
        console.warn("Failed to fetch provider info:", err);
      }
    };

    fetchModelIds();
  }, [apiBase]);

  const sendMessage = async () => {
    const text = input.trim();
    if (!text) return;
    setInput("");

    // Initialize columns with user message
    const userMsg: Message = { role: "user", content: text };
    
    setColumns(prev => {
      const newColumns = { ...prev };
      newColumns.anthropic.messages = [...newColumns.anthropic.messages, userMsg];
      newColumns.lmstudio.messages = [...newColumns.lmstudio.messages, userMsg];
      return newColumns;
    });

    // Set streaming state for both columns
    setColumns(prev => {
      const newColumns = { ...prev };
      newColumns.anthropic.streaming = true;
      newColumns.lmstudio.streaming = true;
      return newColumns;
    });

    // Create assistant messages for both columns
    const assistantMsg: Message = {
      role: "assistant",
      content: "",
      streaming: true,
    };

    // Start concurrent requests to both providers
    const anthropicPromise = new Promise<void>(async (resolve) => {
      try {
        setColumns(prev => {
          const newColumns = { ...prev };
          newColumns.anthropic.messages = [...newColumns.anthropic.messages, assistantMsg];
          return newColumns;
        });

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

        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 => {
                const newColumns = { ...prev };
                newColumns.anthropic.sessionId = payload.session_id;
                return newColumns;
              });
            } else if (payload.type === "text") {
              setColumns(prev => {
                const newColumns = { ...prev };
                const lastMsg = newColumns.anthropic.messages[newColumns.anthropic.messages.length - 1];
                if (lastMsg.role === "assistant") {
                  const updatedMessages = [...newColumns.anthropic.messages];
                  updatedMessages[updatedMessages.length - 1] = {
                    ...lastMsg,
                    content: lastMsg.content + payload.text,
                  };
                  newColumns.anthropic.messages = updatedMessages;
                }
                return newColumns;
              });
            } else if (payload.type === "done") {
              setColumns(prev => {
                const newColumns = { ...prev };
                const lastMsg = newColumns.anthropic.messages[newColumns.anthropic.messages.length - 1];
                if (lastMsg.role === "assistant") {
                  const updatedMessages = [...newColumns.anthropic.messages];
                  updatedMessages[updatedMessages.length - 1] = { ...lastMsg, streaming: false };
                  newColumns.anthropic.messages = updatedMessages;
                }
                newColumns.anthropic.streaming = false;
                return newColumns;
              });
            }
          }
        }
      } catch (err) {
        setColumns(prev => {
          const newColumns = { ...prev };
          const lastMsg = newColumns.anthropic.messages[newColumns.anthropic.messages.length - 1];
          if (lastMsg.role === "assistant") {
            const updatedMessages = [...newColumns.anthropic.messages];
            updatedMessages[updatedMessages.length - 1] = {
              ...lastMsg,
              content: `[Error: ${String(err)}]`,
              streaming: false,
            };
          }
          newColumns.anthropic.streaming = false;
          return newColumns;
        });
      } finally {
        resolve();
      }
    });

    const lmstudioPromise = new Promise<void>(async (resolve) => {
      try {
        setColumns(prev => {
          const newColumns = { ...prev };
          newColumns.lmstudio.messages = [...newColumns.lmstudio.messages, assistantMsg];
          return newColumns;
        });

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

        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 => {
                const newColumns = { ...prev };
                newColumns.lmstudio.sessionId = payload.session_id;
                return newColumns;
              });
            } else if (payload.type === "text") {
              setColumns(prev => {
                const newColumns = { ...prev };
                const lastMsg = newColumns.lmstudio.messages[newColumns.lmstudio.messages.length - 1];
                if (lastMsg.role === "assistant") {
                  const updatedMessages = [...newColumns.lmstudio.messages];
                  updatedMessages[updatedMessages.length - 1] = {
                    ...lastMsg,
                    content: lastMsg.content + payload.text,
                  };
                  newColumns.lmstudio.messages = updatedMessages;
                }
                return newColumns;
              });
            } else if (payload.type === "done") {
              setColumns(prev => {
                const newColumns = { ...prev };
                const lastMsg = newColumns.lmstudio.messages[newColumns.lmstudio.messages.length - 1];
                if (lastMsg.role === "assistant") {
                  const updatedMessages = [...newColumns.lmstudio.messages];
                  updatedMessages[updatedMessages.length - 1] = { ...lastMsg, streaming: false };
                  newColumns.lmstudio.messages = updatedMessages;
                }
                newColumns.lmstudio.streaming = false;
                return newColumns;
              });
            }
          }
        }
      } catch (err) {
        setColumns(prev => {
          const newColumns = { ...prev };
          const lastMsg = newColumns.lmstudio.messages[newColumns.lmstudio.messages.length - 1];
          if (lastMsg.role === "assistant") {
            const updatedMessages = [...newColumns.lmstudio.messages];
            updatedMessages[updatedMessages.length - 1] = {
              ...lastMsg,
              content: `[Error: ${String(err)}]`,
              streaming: false,
            };
          }
          newColumns.lmstudio.streaming = false;
          return newColumns;
        });
      } finally {
        resolve();
      }
    });

    // Wait for both promises to complete
    await Promise.all([anthropicPromise, lmstudioPromise]);
  };

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

  return (
    <div style={styles.container}>
      <div style={styles.header}>
        <span style={styles.headerName}>{persona.display_name}</span>
        <span style={styles.headerMeta}>compare view</span>
      </div>

      <div style={styles.columnsContainer}>
        <div style={{ ...styles.column, ...styles.leftColumn }}>
          <div style={styles.columnHeader}>
            <span style={styles.columnTitle}>Frontier</span>
            <span style={styles.columnModel}>{modelIds.anthropic}</span>
          </div>
          <div style={styles.messages}>
            {columns.anthropic.messages.length === 0 && (
              <div style={styles.empty}>
                Begin your conversation with {persona.display_name}.
              </div>
            )}
            {columns.anthropic.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.anthropic} />
          </div>
        </div>

        <div style={{ ...styles.column, ...styles.rightColumn }}>
          <div style={styles.columnHeader}>
            <span style={styles.columnTitle}>Local</span>
            <span style={styles.columnModel}>{modelIds.lmstudio}</span>
          </div>
          <div style={styles.messages}>
            {columns.lmstudio.messages.length === 0 && (
              <div style={styles.empty}>
                Begin your conversation with {persona.display_name}.
              </div>
            )}
            {columns.lmstudio.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.lmstudio} />
          </div>
        </div>
      </div>

      <div style={styles.inputRow}>
        <textarea
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={onKeyDown}
          placeholder={`Ask ${persona.display_name} something…`}
          disabled={columns.anthropic.streaming || columns.lmstudio.streaming}
          rows={2}
          style={styles.textarea}
        />
        <button
          onClick={sendMessage}
          disabled={columns.anthropic.streaming || columns.lmstudio.streaming || !input.trim()}
          style={{
            ...styles.sendBtn,
            ...(columns.anthropic.streaming || columns.lmstudio.streaming || !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)",
  },
  header: {
    padding: "14px 20px",
    borderBottom: "1px solid var(--border)",
    display: "flex",
    alignItems: "baseline",
    gap: "10px",
    background: "var(--surface)",
  },
  headerName: {
    fontWeight: 700,
    color: "var(--accent)",
    fontSize: "16px",
  },
  headerMeta: {
    color: "var(--text-muted)",
    fontSize: "12px",
  },
  columnsContainer: {
    display: "flex",
    flex: 1,
    overflow: "hidden",
  },
  column: {
    display: "flex",
    flexDirection: "column",
    flex: 1,
    overflowY: "auto",
  },
  leftColumn: {
    borderRight: "1px solid var(--border)",
  },
  rightColumn: {},
  columnHeader: {
    padding: "14px 20px",
    borderBottom: "1px solid var(--border)",
    display: "flex",
    justifyContent: "space-between",
    background: "var(--surface)",
  },
  columnTitle: {
    fontWeight: 700,
    color: "var(--accent)",
    fontSize: "14px",
  },
  columnModel: {
    color: "var(--text-muted)",
    fontSize: "12px",
  },
  messages: {
    flex: 1,
    overflowY: "auto",
    padding: "20px",
    display: "flex",
    flexDirection: "column",
    gap: "16px",
  },
  empty: {
    color: "var(--text-muted)",
    fontStyle: "italic",
    textAlign: "center",
    marginTop: "40px",
    fontSize: "14px",
  },
  bubble: {
    maxWidth: "700px",
    display: "flex",
    flexDirection: "column",
    gap: "4px",
  },
  userBubble: {
    alignSelf: "flex-end",
    alignItems: "flex-end",
  },
  assistantBubble: {
    alignSelf: "flex-start",
    alignItems: "flex-start",
  },
  role: {
    fontSize: "11px",
    color: "var(--text-muted)",
    fontWeight: 600,
    textTransform: "uppercase",
    letterSpacing: "0.05em",
  },
  text: {
    background: "var(--surface)",
    padding: "10px 14px",
    borderRadius: "var(--radius)",
    lineHeight: 1.65,
    fontSize: "14px",
    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",
  },
};