"use client";

import { useState, useEffect, useRef, useCallback } from "react";
import { useAgent } from "@/hooks/useAgent";
import { useSessionManager } from "@/hooks/useSessionManager";
import { useRepositories } from "@/hooks/useRepositories";
import { useWiki } from "@/hooks/useWiki";
import { useWikiProgress } from "@/hooks/useWikiProgress";
import { ChatView } from "@/components/ChatView";
import { ChatSidebar } from "@/components/sidebar/ChatSidebar";
import { RepositoryModal } from "@/components/RepositoryModal";
import { WikiView } from "@/components/WikiView";

type MainTab = "chat" | "wiki";

interface ChatAppProps {
  activeTab?: MainTab;
}

export default function ChatApp({ activeTab = "chat" }: ChatAppProps) {
  const { repositories, addRepository, deleteRepository } = useRepositories();
  const sessionManager = useSessionManager();
  const [showRepoModal, setShowRepoModal] = useState(false);
  const wiki = useWiki(sessionManager.repositoryId);
  const { status: wikiStatus, reconnect: reconnectWikiProgress, markCancelled } = useWikiProgress(sessionManager.repositoryId);

  const {
    messages,
    isStreaming,
    error,
    pendingInterrupt,
    analysisState,
    sendMessage,
    resolveInterrupt,
    resetSession,
  } = useAgent({
    onMessagesChange: sessionManager.persistMessages,
    repositoryId: sessionManager.repositoryId,
  });

  const initializedRef = useRef(false);
  const isChatMode = activeTab === "chat";

  const selectRepository = useCallback(
    (id: string) => {
      wiki.markBootstrapped();
      sessionManager.setRepositoryId(id);
    },
    [wiki, sessionManager],
  );

  const handleSendMessage = async (text: string) => {
    let activeSession = sessionManager.activeSession;

    if (!activeSession && sessionManager.repositoryId) {
      activeSession = await sessionManager.createNewSession();
      resetSession({
        messages: activeSession.messages,
        history: activeSession.agui_history,
        threadId: activeSession.thread_id,
        analysisState: activeSession.analysis_state,
        pendingInterrupt: activeSession.pending_interrupt,
      });
    }

    await sendMessage(text);
  };

  useEffect(() => {
    if (!sessionManager.repositoryId && repositories.length > 0) {
      selectRepository(repositories[0].id);
    }
  }, [repositories, sessionManager.repositoryId, selectRepository]);

  useEffect(() => {
    if (!sessionManager.repositoryId) return;
    let cancelled = false;

    (async () => {
      try {
        const res = await fetch(`/api/bootstrap?repositoryId=${sessionManager.repositoryId}`);
        if (!res.ok || cancelled) return;
        const data = await res.json();

        sessionManager.initFromBootstrap({
          sessions: data.sessions,
          activeSession: data.activeSession,
        });
        wiki.initManifest(data.manifest);
      } catch {
        sessionManager.clearBootstrapped();
      }
    })();

    return () => { cancelled = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sessionManager.repositoryId]);

  useEffect(() => {
    const session = sessionManager.activeSession;
    if (!session) return;
    resetSession({
      messages: session.messages,
      history: session.agui_history,
      threadId: session.thread_id,
      analysisState: session.analysis_state,
      pendingInterrupt: session.pending_interrupt,
    });
    initializedRef.current = true;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sessionManager.activeSessionId]);

  // Refresh manifest on terminal states and periodically as new pages complete.
  const prevPageCountRef = useRef(0);
  useEffect(() => {
    if (wikiStatus?.state === "done" || wikiStatus?.state === "error") {
      wiki.refreshManifest();
      prevPageCountRef.current = 0;
      return;
    }
    const currentCount = wikiStatus?.completedPageIds?.length ?? 0;
    if (currentCount > 0 && currentCount !== prevPageCountRef.current) {
      prevPageCountRef.current = currentCount;
      wiki.refreshManifest();
    }
  }, [wikiStatus?.state, wikiStatus?.completedPageIds?.length, wiki.refreshManifest]);

  const resumeWikiGeneration = useCallback(async () => {
    if (!sessionManager.repositoryId) return;
    reconnectWikiProgress();
    await fetch(`/api/repositories/${sessionManager.repositoryId}/wiki/job`, { method: "POST" });
  }, [sessionManager.repositoryId, reconnectWikiProgress]);

  const regenerateWiki = useCallback(async () => {
    if (!sessionManager.repositoryId) return;
    reconnectWikiProgress();
    await fetch(`/api/repositories/${sessionManager.repositoryId}/wiki/job?fresh=true`, { method: "POST" });
  }, [sessionManager.repositoryId, reconnectWikiProgress]);

  const cancelWikiGeneration = useCallback(() => {
    if (!sessionManager.repositoryId) return;
    markCancelled();
    fetch(`/api/repositories/${sessionManager.repositoryId}/wiki/job`, {
      method: "DELETE",
    }).catch(() => { /* ignore */ });
  }, [sessionManager.repositoryId, markCancelled]);

  return (
    <div className="flex h-full bg-rp-bg">
      {isChatMode && sessionManager.sidebarOpen && (
        <ChatSidebar
          groupedSessions={sessionManager.groupedSessions}
          activeSessionId={sessionManager.activeSessionId}
          onSelectSession={sessionManager.switchSession}
          onDeleteSession={sessionManager.deleteSessionById}
          onNewSession={sessionManager.createNewSession}
          onClose={sessionManager.toggleSidebar}
          repositories={repositories}
          selectedRepositoryId={sessionManager.repositoryId}
          onSelectRepository={selectRepository}
          onManageRepositories={() => setShowRepoModal(true)}
          onToggleSidebar={sessionManager.toggleSidebar}
        />
      )}

      <div className="flex flex-col flex-1 min-w-0">
        {isChatMode && !sessionManager.sidebarOpen && (
          <div className="absolute top-2 left-2 z-10">
            <button
              onClick={sessionManager.toggleSidebar}
              className="text-rp-muted hover:text-rp-text transition-colors p-1.5 rounded-lg hover:bg-rp-surface"
              title="Open sidebar"
            >
              <SidebarIcon />
            </button>
          </div>
        )}

        {sessionManager.repositoryId ? (
          <div className="flex-1 min-h-0">
            {activeTab === "chat" && (
              <ChatView
                messages={messages}
                isStreaming={isStreaming}
                error={error}
                pendingInterrupt={pendingInterrupt}
                analysisState={analysisState}
                onSend={handleSendMessage}
                onResolveInterrupt={resolveInterrupt}
              />
            )}
            {activeTab === "wiki" && (
              <WikiView
                repositoryId={sessionManager.repositoryId}
                manifest={wiki.manifest}
                selectedPageId={wiki.selectedPageId}
                page={wiki.page}
                loading={wiki.loading}
                error={wiki.error}
                onSelectPage={wiki.selectPage}
                wikiStatus={wikiStatus}
                onResume={resumeWikiGeneration}
                onRegenerate={regenerateWiki}
                onCancel={cancelWikiGeneration}
              />
            )}
          </div>
        ) : (
          <div className="flex-1 min-h-0 flex items-center justify-center">
            <div className="text-center">
              <p className="text-rp-muted text-r-sm mb-3">No repository selected</p>
              <button
                onClick={() => setShowRepoModal(true)}
                className="btn-accent"
              >
                Add Repository
              </button>
            </div>
          </div>
        )}
      </div>

      {showRepoModal && (
        <RepositoryModal
          repositories={repositories}
          onAdd={addRepository}
          onDelete={deleteRepository}
          onClose={() => setShowRepoModal(false)}
        />
      )}
    </div>
  );
}

function SidebarIcon() {
  return (
    <svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round">
      <rect x="2" y="3" width="14" height="12" rx="2" />
      <path d="M7 3V15" />
    </svg>
  );
}
