import { FormEvent, useEffect, useRef, useState } from "react";
import ReactMarkdown from "react-markdown";
import { api, ChatMessage, ChatSession } from "../api/client";
import PomodoroWidget from "../components/PomodoroWidget";
import { usePomodoro } from "../hooks/usePomodoro";
import "./Chat.css";

function shouldShowMessage(msg: ChatMessage): boolean {
  if (msg.role === "tool") return false;
  if (msg.role === "assistant" && !msg.content.trim()) return false;
  return true;
}

function roleLabel(role: string): string {
  if (role === "notice") return "таймер";
  if (role === "user") return "вы";
  return role;
}

export default function Chat() {
  const [sessions, setSessions] = useState<ChatSession[]>([]);
  const [activeId, setActiveId] = useState<number | null>(null);
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [input, setInput] = useState("");
  const [loading, setLoading] = useState(false);
  const [streaming, setStreaming] = useState("");
  const [liveNotices, setLiveNotices] = useState<string[]>([]);
  const bottomRef = useRef<HTMLDivElement>(null);
  const { status: pomodoroStatus, refresh: refreshPomodoro } = usePomodoro();
  const [lastNotifySeq, setLastNotifySeq] = useState(0);

  const loadSessions = async () => {
    const data = await api.listSessions();
    setSessions(data);
    if (!activeId && data.length > 0) {
      setActiveId(data[0].id);
    }
  };

  const loadMessages = async (sessionId: number) => {
    const data = await api.getSession(sessionId);
    setMessages(data.messages);
  };

  useEffect(() => {
    loadSessions().catch(console.error);
  }, []);

  useEffect(() => {
    if (activeId) {
      loadMessages(activeId).catch(console.error);
    }
  }, [activeId]);

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [messages, streaming, liveNotices]);

  useEffect(() => {
    const seq = pomodoroStatus?.cycle?.chat_notify_seq ?? 0;
    if (seq > lastNotifySeq && activeId) {
      setLastNotifySeq(seq);
      loadMessages(activeId).catch(console.error);
    }
  }, [pomodoroStatus?.cycle?.chat_notify_seq, activeId, lastNotifySeq]);

  const handleNewChat = async () => {
    const session = await api.createSession();
    await loadSessions();
    setActiveId(session.id);
    setMessages([]);
    setLiveNotices([]);
  };

  const handleDelete = async (id: number) => {
    await api.deleteSession(id);
    const data = await api.listSessions();
    setSessions(data);
    if (activeId === id) {
      setActiveId(data[0]?.id ?? null);
      setMessages([]);
      setLiveNotices([]);
    }
  };

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    if (!input.trim() || !activeId || loading) return;

    const text = input.trim();
    setInput("");
    setLoading(true);
    setStreaming("");
    setLiveNotices([]);

    const tempUser: ChatMessage = {
      id: Date.now(),
      role: "user",
      content: text,
      created_at: new Date().toISOString(),
    };
    setMessages((prev) => [...prev, tempUser]);

    try {
      for await (const chunk of api.sendMessage(activeId, text)) {
        if (chunk.event === "token") {
          setStreaming((prev) => prev + chunk.data.content);
        }
        if (chunk.event === "notice") {
          setLiveNotices((prev) => [...prev, chunk.data.content]);
          refreshPomodoro();
        }
        if (chunk.event === "pomodoro") {
          refreshPomodoro();
        }
        if (chunk.event === "done") {
          await loadMessages(activeId);
          await loadSessions();
          setStreaming("");
          setLiveNotices([]);
        }
        if (chunk.event === "error") {
          throw new Error(chunk.data.message);
        }
      }
    } catch (err) {
      console.error(err);
      setStreaming("");
      setLiveNotices([]);
    } finally {
      setLoading(false);
    }
  };

  const visibleMessages = messages.filter(shouldShowMessage);

  return (
    <div className="chat-layout">
      <aside className="chat-sidebar">
        <button className="primary-btn" onClick={handleNewChat}>
          + Новый чат
        </button>

        <PomodoroWidget />

        <ul className="session-list">
          {sessions.map((session) => (
            <li key={session.id} className={activeId === session.id ? "active" : ""}>
              <button onClick={() => setActiveId(session.id)}>{session.title}</button>
              <button className="delete-btn" onClick={() => handleDelete(session.id)}>
                ×
              </button>
            </li>
          ))}
        </ul>
      </aside>

      <section className="chat-main">
        {!activeId ? (
          <div className="chat-empty">Создайте новый чат, чтобы начать</div>
        ) : (
          <>
            <div className="messages">
              {visibleMessages.map((msg) => (
                <div key={msg.id} className={`message message-${msg.role}`}>
                  <div className="message-role">{roleLabel(msg.role)}</div>
                  <div className="message-content">
                    {msg.role === "assistant" || msg.role === "notice" ? (
                      <ReactMarkdown>{msg.content}</ReactMarkdown>
                    ) : (
                      msg.content
                    )}
                  </div>
                </div>
              ))}

              {liveNotices.map((notice, idx) => (
                <div key={`notice-${idx}`} className="message message-notice">
                  <div className="message-role">таймер</div>
                  <div className="message-content">
                    <ReactMarkdown>{notice}</ReactMarkdown>
                  </div>
                </div>
              ))}

              {streaming && (
                <div className="message message-assistant">
                  <div className="message-role">assistant</div>
                  <div className="message-content">
                    <ReactMarkdown>{streaming}</ReactMarkdown>
                  </div>
                </div>
              )}
              <div ref={bottomRef} />
            </div>

            <form className="chat-input" onSubmit={handleSubmit}>
              <textarea
                value={input}
                onChange={(e) => setInput(e.target.value)}
                placeholder="Напишите сообщение..."
                rows={2}
                onKeyDown={(e) => {
                  if (e.key === "Enter" && !e.shiftKey) {
                    e.preventDefault();
                    handleSubmit(e);
                  }
                }}
              />
              <button type="submit" disabled={loading || !input.trim()}>
                {loading ? "..." : "Отправить"}
              </button>
            </form>
          </>
        )}
      </section>
    </div>
  );
}
