"use client";

import { useEffect, useState, useRef, createContext, useContext } from "react";
import {
    Tldraw,
    createTLStore,
    TLStore,
    Editor,
    getSnapshot,
    loadSnapshot,
    useDialogs,
    TldrawUiButton,
    TldrawUiButtonLabel,
    TldrawUiButtonIcon,
    TldrawUiDialogHeader,
    TldrawUiDialogTitle,
    TldrawUiDialogCloseButton,
    TldrawUiDialogBody,
    TldrawUiIcon
} from "tldraw";
import "tldraw/tldraw.css";
import { getLessonWhiteboard, saveLessonSnapshot, SnapshotType } from "@/lib/whiteboardActions";
import { toast } from "react-toastify";
import { useUser } from "@clerk/nextjs";

type WhiteboardContextType = {
    activeState: SnapshotType;
    isTeacherOrAdmin: boolean;
    handleSave: (type: SnapshotType) => void;
    handleLoadData: (type: SnapshotType) => void;
    lessonId: number | null;
    whiteboardRecord: any;
    isFullscreen: boolean;
};

const WhiteboardContext = createContext<WhiteboardContextType | null>(null);

const useWhiteboardContext = () => {
    const ctx = useContext(WhiteboardContext);
    if (!ctx) throw new Error("Missing WhiteboardContext.Provider");
    return ctx;
};

function NativeFileManagerDialog({ onClose }: { onClose: () => void }) {
    const { activeState, isTeacherOrAdmin, handleSave, handleLoadData, whiteboardRecord } = useWhiteboardContext();

    const renderFileRow = (type: SnapshotType, title: string) => {
        const hasData = whiteboardRecord && whiteboardRecord[`${type}SnapshotData`];
        const isActive = activeState === type;

        return (
            <div className="flex items-center justify-between p-3 border rounded-md mb-2 bg-gray-50" key={type}>
                <div className="flex flex-col">
                    <span className="font-semibold text-gray-800 flex items-center gap-2">
                        {title}
                        {isActive && <span className="text-[10px] bg-lamaPurple text-white px-2 py-0.5 rounded-full mt-0.5">ACTIVE</span>}
                    </span>
                    <span className="text-xs text-gray-500">
                        {hasData ? "Snapshot available" : "No snapshot saved"}
                    </span>
                </div>
                <div className="flex gap-2">
                    {isTeacherOrAdmin && (
                        <TldrawUiButton type="normal" onClick={() => { handleSave(type); }}>
                            <TldrawUiButtonLabel>Save Here</TldrawUiButtonLabel>
                        </TldrawUiButton>
                    )}
                    <TldrawUiButton type="primary" disabled={!hasData} onClick={() => { handleLoadData(type); onClose(); }}>
                        <TldrawUiButtonLabel>Load</TldrawUiButtonLabel>
                    </TldrawUiButton>
                </div>
            </div>
        );
    };

    return (
        <>
            <TldrawUiDialogHeader>
                <TldrawUiDialogTitle>File Manager</TldrawUiDialogTitle>
                <TldrawUiDialogCloseButton />
            </TldrawUiDialogHeader>
            <TldrawUiDialogBody style={{ maxWidth: 450 }}>
                <div className="mb-4 text-sm text-gray-600">
                    Manage your lesson whiteboard snapshots below.
                    {!isTeacherOrAdmin && " As a student, you can only load available snapshots."}
                </div>
                {renderFileRow("planned", "Planned")}
                {renderFileRow("live", "Live")}
                {renderFileRow("final", "Final")}
            </TldrawUiDialogBody>
        </>
    )
}

const CustomSharePanel = () => {
    const { addDialog } = useDialogs();
    const { isFullscreen, lessonId } = useWhiteboardContext();

    return (
        <div style={{ pointerEvents: 'all', display: 'flex', gap: '8px' }}>
            {!isFullscreen && lessonId && (
                <TldrawUiButton
                    type="icon"
                    title="Open Fullscreen in New Window"
                    onClick={() => {
                        window.open(`/board?lessonId=${lessonId}`, '_blank');
                    }}
                >
                    <TldrawUiButtonIcon icon="external-link" />
                </TldrawUiButton>
            )}
            <TldrawUiButton
                type="icon"
                title="File Manager"
                onClick={() => addDialog({ component: NativeFileManagerDialog })}
            >
                <TldrawUiButtonIcon icon="menu" />
            </TldrawUiButton>
        </div>
    );
};

const WhiteboardCore = ({ lessonId, isFullscreen = false }: { lessonId: number | null, isFullscreen?: boolean }) => {
    const { user } = useUser();
    const role = user?.publicMetadata?.role as string | undefined;
    const isTeacherOrAdmin = role === "teacher" || role === "admin";

    const [store, setStore] = useState<TLStore | null>(null);
    const [loading, setLoading] = useState(true);
    const [activeState, setActiveState] = useState<SnapshotType>("planned");
    const [whiteboardRecord, setWhiteboardRecord] = useState<any>(null);
    const editorRef = useRef<Editor | null>(null);

    useEffect(() => {
        const fetchWhiteboard = async () => {
            if (!lessonId) {
                setLoading(false);
                return;
            }

            const { success, data } = await getLessonWhiteboard(lessonId);
            if (success && data) {
                setWhiteboardRecord(data);

                // Initialize store based on role
                const newStore = createTLStore();

                let defaultSnapshot = data.plannedSnapshotData;
                let defaultState: SnapshotType = "planned";

                // For students, default to live, or final if live doesn't exist. If neither, show empty.
                if (!isTeacherOrAdmin) {
                    if (data.liveSnapshotData) {
                        defaultSnapshot = data.liveSnapshotData;
                        defaultState = "live";
                    } else if (data.finalSnapshotData) {
                        defaultSnapshot = data.finalSnapshotData;
                        defaultState = "final";
                    } else {
                        defaultSnapshot = null;
                        defaultState = "live"; // Wait for live
                    }
                }

                if (defaultSnapshot) {
                    try {
                        loadSnapshot(newStore, defaultSnapshot as any);
                    } catch (e) {
                        console.error("Failed to load snapshot", e);
                    }
                }
                setStore(newStore);
                setActiveState(defaultState);
            }
            setLoading(false);
        };

        if (role !== undefined) {
            fetchWhiteboard();
        }
    }, [isTeacherOrAdmin, lessonId, role]);

    const handleSave = async (type: SnapshotType) => {
        if (!lessonId || !editorRef.current || !isTeacherOrAdmin) return;

        const snapshot = getSnapshot(editorRef.current.store);
        const { success } = await saveLessonSnapshot(lessonId, type, snapshot);

        if (success) {
            toast.success(`Successfully saved ${type} snapshot!`);
            setActiveState(type);
            setWhiteboardRecord((prev: any) => ({
                ...prev,
                [`${type}SnapshotData`]: snapshot
            }));
        } else {
            toast.error("Failed to save snapshot.");
        }
    };

    const handleLoadData = (type: SnapshotType) => {
        if (!whiteboardRecord || !editorRef.current) return;

        let snapshotData = null;
        if (type === "planned") snapshotData = whiteboardRecord.plannedSnapshotData;
        if (type === "live") snapshotData = whiteboardRecord.liveSnapshotData;
        if (type === "final") snapshotData = whiteboardRecord.finalSnapshotData;

        if (snapshotData) {
            try {
                loadSnapshot(editorRef.current.store, snapshotData as any);
                toast.success(`Loaded ${type} snapshot.`);
                setActiveState(type);
            } catch (e) {
                console.error("Failed to load snapshot", e);
                toast.error("Snapshot data is invalid or corrupted.");
            }
        } else {
            toast.info(`No data found for ${type} snapshot.`);
        }
    };

    return (
        <div className={`flex-1 w-full relative bg-white overflow-hidden ${isFullscreen ? 'h-screen' : 'h-[calc(100vh-80px)]'}`}>
            {loading || role === undefined ? (
                <div className="absolute inset-0 flex items-center justify-center text-gray-400">
                    Loading whiteboard...
                </div>
            ) : !lessonId ? (
                <div className="absolute inset-0 flex items-center justify-center text-gray-400">
                    Please provide a ?lessonId URL parameter.
                </div>
            ) : store ? (
                <WhiteboardContext.Provider value={{ activeState, isTeacherOrAdmin, handleSave, handleLoadData, lessonId, whiteboardRecord, isFullscreen }}>
                    <div className="absolute inset-0">
                        <Tldraw
                            store={store}
                            components={{ SharePanel: CustomSharePanel }}
                            onMount={(editor) => {
                                editorRef.current = editor;
                                if (!isTeacherOrAdmin) {
                                    editor.updateInstanceState({ isReadonly: true });
                                }
                            }}
                        />
                    </div>
                </WhiteboardContext.Provider>
            ) : (
                <div className="absolute inset-0 flex items-center justify-center text-gray-400">
                    Failed to initialize whiteboard.
                </div>
            )}
        </div>
    );
};

export default WhiteboardCore;
