"use client";
import { SessionState } from "@/lib/SessionData/Enums";
import Drawing from "./Drawing";
import { createContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import SessionHandler from "@/lib/SessionHandler/SessionHandler";
import Lobby from "./Lobby";
import Reviewing from "./Reviewing";
import React from "react";
import { useRouter } from "next/router";
import type { User, ReviewCounts } from "@/lib/SessionData/Interfaces";

const SessionHandlerContext = createContext<SessionHandler | null>(null)

// Separate PDF-Mode-Komponente, die Daten über API lädt statt WebSocket
function PdfModeReviewing({ sessionCode, pdfToken }: { sessionCode: string; pdfToken?: string }) {
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);
    const [data, setData] = useState<{
        topic: string;
        users: User[];
        ideas: Array<{ id: string; images: string[]; ownerIndex: number }>;
        reviewCounts: Record<string, ReviewCounts>;
    } | null>(null);

    useEffect(() => {
        const fetchData = async () => {
            try {
                // Token aus URL (PDF-Modus) oder localStorage
                const token = pdfToken || localStorage.getItem("wsClientToken") || "";
                const url = `/api/session/data?code=${encodeURIComponent(sessionCode)}${token ? `&token=${encodeURIComponent(token)}` : ""}`;
                const res = await fetch(url, {
                    credentials: 'include', // Wichtig für Auth-Cookies im PDF-Modus
                });
                if (!res.ok) {
                    const json = await res.json().catch(() => ({}));
                    throw new Error(json.message || "Fehler beim Laden der Daten");
                }
                const json = await res.json();
                setData(json);
            } catch (err) {
                setError(err instanceof Error ? err.message : "Unbekannter Fehler");
            } finally {
                setLoading(false);
            }
        };
        fetchData();
    }, [sessionCode]);

    if (loading) {
        return <div>Lade PDF-Daten...</div>;
    }
    if (error || !data) {
        return <div>Fehler: {error || "Keine Daten"}</div>;
    }

    return (
        <Reviewing
            sessionId={sessionCode}
            isPdfMode={true}
            pdfData={data}
        />
    );
}

function Session({ sessionCode }: { sessionCode: string }) {
    const router = useRouter();
    const forceReviewing = router.query?.pdf === "1";
    const pdfToken = router.query?.pdfToken as string | undefined;

    // SessionHandler muss stabil bleiben, sonst reißt die WS-Verbindung ab
    const sessionHandler = useMemo(() => new SessionHandler(sessionCode), [sessionCode]);
    const [sessionState, setSessionState] = useState<SessionState>(() => {
        // sessionState vom sessionHandler initial setzen
        return sessionHandler.getSessionState();
    });
    const hasConnectedRef = useRef(false);

    sessionHandler.registerSessionStateListener((state) => {
        setSessionState(state);
    });

    const connectWebSocket = useCallback(async (sessionHandler: SessionHandler) => {
        if (await sessionHandler.connectWs() !== false) {
        } else {
            // Im PDF-Modus nicht weiterleiten
            if (!forceReviewing) {
                router.push("/");
            }
        }
    }, [router, forceReviewing]);

    // wenn seite geladen wird - aber nicht im PDF-Modus
    useEffect(() => {
        if (forceReviewing) return; // Im PDF-Modus keine WS-Verbindung
        if (!sessionHandler) return;
        if (hasConnectedRef.current) return;
        hasConnectedRef.current = true;

        connectWebSocket(sessionHandler);

    }, [sessionHandler, connectWebSocket, forceReviewing]);

    function content() {
        // Im PDF-Modus: Direkt PdfModeReviewing anzeigen (ohne WebSocket)
        if (forceReviewing) {
            return <PdfModeReviewing sessionCode={sessionCode} pdfToken={pdfToken} />;
        }

        switch (sessionState) {
            case SessionState.Lobby:
                return <Lobby sessionCode={sessionCode} />;
            case SessionState.Drawing:
                return <Drawing sessionId={sessionCode} />;
            case SessionState.Reviewing:
                return <Reviewing sessionId={sessionCode} isPdfMode={false} />;
            case SessionState.Loading:
                return <div>Lade...</div>;
            case SessionState.Init:
                // TODO: besserer Loading Screen
                return <div>Lade...</div>;
            case SessionState.Closed:
                return <div>Die Sitzung ist geschlossen</div>;
            default:
                return <div>Unknown session state</div>;
        }
    };

    return (
        <SessionHandlerContext.Provider value={sessionHandler}>
            {content()}
        </SessionHandlerContext.Provider>
    );
}

export default Session;
export { SessionHandlerContext };