"use client";

import Button from "@/components/Button";
import Image from "next/image";
import React from "react";
import { DrawBoardHandle } from "@/components/DrawBoard/DrawBoard";
import PriorImages from "@/components/webpage/PriorImages";
import styles from "@/styles/Session/Drawing.module.css";
import type { Settings, User, WsData, Update } from "@/lib/SessionData/Interfaces";
import RandomUnsplash from "@/components/RandomPictures";

import { useActiveUsers, socket } from "@/hooks/useActiveUsers";
import { SessionHandlerContext } from "./Session";
import { WsEvent, DrawingState } from "@/lib/SessionData/Enums";

const DrawBoard = React.lazy(() => import("@/components/DrawBoard/DrawBoard"));

const DEFAULT_AVATARS = [
    "/images/users/DefaultImages/default-image-1.png",
    "/images/users/DefaultImages/default-image-3.png",
    "/images/users/DefaultImages/default-image-5.png",
    "/images/users/DefaultImages/default-image-6.png",
    "/images/users/DefaultImages/default-image-8.png",
    "/images/users/DefaultImages/default-image-9.png",
    "/images/users/DefaultImages/default-image-10.png",
    "/images/users/DefaultImages/default-image-7.png",
];

function getAvatarSrc(user: User): string | null {
    if (user.profileImage && user.profileImage.length > 0) {
        return user.profileImage;
    }
    const key = user.userId !== false && user.userId !== null
        ? String(user.userId)
        : user.id || user.name || "guest";
    let hash = 0;
    for (let i = 0; i < key.length; i++) {
        hash = (hash + key.charCodeAt(i) * 17) % 10000;
    }
    const idx = DEFAULT_AVATARS.length ? hash % DEFAULT_AVATARS.length : 0;
    return DEFAULT_AVATARS[idx] ?? null;
}

function Drawing({ sessionId }: { sessionId: string }) {


    const drawboardRef = React.useRef<DrawBoardHandle | null>(null);
    const [isClient, setIsClient] = React.useState(false);

    const sessionHandler = React.useContext(SessionHandlerContext);
    const [time, setTime] = React.useState<number | null>(null);
    const [timeLeft, setTimeLeft] = React.useState<number | null>(null);
    const [topic, setTopic] = React.useState("Themenueberschrift");
    const [goal, setGoal] = React.useState("Beschreibung");
    const [readyCheckEnabled, setReadyCheckEnabled] = React.useState(true);
    const [isReady, setIsReady] = React.useState(false);
    const [users, setUsers] = React.useState<User[]>([]);
    const [freezeTimer, setFreezeTimer] = React.useState(false);
    const [isAdmin, setIsAdmin] = React.useState<boolean>(false);
    const [timerExtendable, setTimerExtendable] = React.useState<boolean>(true);
    const [writingEnabled, setWritingEnabled] = React.useState<boolean>(true);
    const [drawingEnabled, setDrawingEnabled] = React.useState<boolean>(true);
    const [digitalUploadEnabled, setDigitalUploadEnabled] = React.useState<boolean>(true);
    const [creativeSupportEnabled, setCreativeSupportEnabled] = React.useState<boolean>(true);
    const [readyUsers, setReadyUsers] = React.useState<Set<string>>(new Set());
    const [isPaused, setIsPaused] = React.useState(false);
    const freezeTimerRef = React.useRef(false);
    const isReadyRef = React.useRef(false);
    const lastTimeRef = React.useRef<{ time: number | null; timeLeft: number | null }>({
        time: null,
        timeLeft: null,
    });

    React.useEffect(() => {
        freezeTimerRef.current = freezeTimer;
    }, [freezeTimer]);

    React.useEffect(() => {
        isReadyRef.current = isReady;
    }, [isReady]);

    React.useEffect(() => {
        if (!sessionHandler || !sessionHandler.timeHandler) return;
        const initialTime = sessionHandler.timeHandler.getTime();
        const initialTimeLeft = sessionHandler.timeHandler.getTimeLeft();
        setTime(initialTime);
        setTimeLeft(initialTimeLeft);
        lastTimeRef.current = { time: initialTime, timeLeft: initialTimeLeft };
        const cb = (t: number | null, tl: number | null) => {
            if (freezeTimerRef.current) {
                return;
            }
            const lastTimeLeft = lastTimeRef.current.timeLeft;
            if (isReadyRef.current && lastTimeLeft !== null && tl !== null) {
                const drop = lastTimeLeft - tl;
                if (drop > 2) {
                    return;
                }
            }
            setTime(t);
            setTimeLeft(tl);
            lastTimeRef.current = { time: t, timeLeft: tl };
        };
        sessionHandler.timeHandler.onChange(cb);
    }, [sessionHandler]);

    React.useEffect(() => {
        if (!sessionHandler || !sessionHandler.lobbyHandler) return;
        const settings = sessionHandler.lobbyHandler.getSettings();
        if (settings) {
            setTopic(settings.topic ?? "Themenueberschrift");
            setGoal(settings.goal ?? "Beschreibung");
            setReadyCheckEnabled(settings.readyCheck ?? true);
            setTimerExtendable(settings.timerExtendable ?? true);
            setWritingEnabled(settings.writing ?? true);
            setDrawingEnabled(settings.drawing ?? true);
            setDigitalUploadEnabled(settings.digitalUpload ?? true);
            setCreativeSupportEnabled(settings.creativeSupport ?? true);
        }
        const cb = (next: Settings | null) => {
            if (!next) return;
            setTopic(next.topic ?? "Themenueberschrift");
            setGoal(next.goal ?? "Beschreibung");
            setReadyCheckEnabled(next.readyCheck ?? true);
            setTimerExtendable(next.timerExtendable ?? true);
            setWritingEnabled(next.writing ?? true);
            setDrawingEnabled(next.drawing ?? true);
            setDigitalUploadEnabled(next.digitalUpload ?? true);
            setCreativeSupportEnabled(next.creativeSupport ?? true);
        };
        sessionHandler.lobbyHandler.onChange(cb);
    }, [sessionHandler]);

    // initialize socket connection (for join-lobby) but read users via SessionHandler
    useActiveUsers(sessionId);

    React.useEffect(() => {
        setIsClient(true);
    }, []);

    // 🔥 WICHTIG — Nutzer tritt der Session bei
    React.useEffect(() => {
        if (!sessionId || !socket) return;

        socket.emit("join-lobby", {
            code: sessionId,
            name: "Spieler",       // hier ggf. aus deinem User kommen lassen
            isGuest: true,
            userId: null
        });
    }, [sessionId]);

    // subscribe to users from SessionHandler
    React.useEffect(() => {
        if (!sessionHandler || !sessionHandler.userHandler) return;
        setUsers(sessionHandler.userHandler.getUsers());
        const cb = (list: User[]) => setUsers([...list]);
        sessionHandler.userHandler.onChange(cb);
    }, [sessionHandler]);

    // derive isAdmin from current user in SessionHandler
    React.useEffect(() => {
        if (!sessionHandler) return;
        const current = sessionHandler.userHandler?.getUsers()?.find(u => u.id === sessionHandler.getClientId());
        setIsAdmin(current?.isAdmin ?? false);
        const cb = (list: User[]) => {
            const nextCurrent = list.find(u => u.id === sessionHandler.getClientId());
            setIsAdmin(nextCurrent?.isAdmin ?? false);
        };
        sessionHandler.userHandler?.onChange(cb);
    }, [sessionHandler]);

    // Capture canvas and send to server when a round ends. Use a ref to avoid duplicate submissions from same client and reset per NextRound
    React.useEffect(() => {
        if (!sessionHandler) return;
        const submittedRef = { current: false } as { current: boolean };
        const listener = (wsData: WsData) => {
            if (wsData.event === WsEvent.RoundEnd) {
                const update = wsData.data as Update;
                setFreezeTimer(true);
                if (update && update.type === DrawingState.NextRound) {
                    if (submittedRef.current) return;
                    submittedRef.current = true;
                    const image = drawboardRef.current?.getCanvasImageBase64() ?? "";
                    if (image && image.length > 0) {
                        const wsPayload: WsData = {
                            event: WsEvent.DrawingUpdate,
                            data: { type: DrawingState.Image, value: image } as Update,
                            message: null,
                            error: null,
                        };
                        sessionHandler.sendEvent(wsPayload);
                        console.log("Drawing: sent image to server; length=", image.length);
                    } else {
                        console.log("Drawing: no image captured to send");
                    }
                }
            }

            if (wsData.event === WsEvent.DrawingUpdate) {
                const update = wsData.data as Update;
                if (update && update.type === DrawingState.Ready) {
                    const val = update.value as { clientId?: string } | string | boolean | null;
                    const clientId = typeof val === "string" ? val : (val as { clientId?: string })?.clientId;
                    if (clientId) {
                        setReadyUsers((prev) => {
                            const next = new Set(prev);
                            next.add(clientId);
                            return next;
                        });
                    }
                }
                if (update && update.type === DrawingState.NextRound) {
                    // New round started for this client: clear board and reset submitted flag
                    try {
                        drawboardRef.current?.clear();
                        console.log("Drawing: cleared board for new round");
                    } catch (err) {
                        console.error("Drawing: failed to clear board:", err);
                    }
                    submittedRef.current = false;
                    setIsReady(false);
                    setFreezeTimer(false);
                    setReadyUsers(new Set());
                    if (sessionHandler?.timeHandler) {
                        const nextTime = sessionHandler.timeHandler.getTime();
                        const nextTimeLeft = sessionHandler.timeHandler.getTimeLeft();
                        setTime(nextTime);
                        setTimeLeft(nextTimeLeft);
                        lastTimeRef.current = { time: nextTime, timeLeft: nextTimeLeft };
                    }
                }
            }
        };
        sessionHandler.registerListener([WsEvent.RoundEnd, WsEvent.DrawingUpdate], listener);
    }, [sessionHandler]);

    React.useEffect(() => {
        setIsClient(true);
    }, []);

    // helper function: format seconds (number | null) to MM:SS
    function formatTime(seconds: number | null) {
        if (seconds === null || seconds < 0) return "--:--";
        const m = Math.floor(seconds / 60).toString().padStart(2, "0");
        const s = (seconds % 60).toString().padStart(2, "0");
        return `${m}:${s}`;
    }

    function handleReadyClick() {
        if (!sessionHandler || isReady || !readyCheckEnabled) return;
        const clientId = sessionHandler.getClientId();
        const payload: WsData = {
            event: WsEvent.DrawingUpdate,
            data: { type: DrawingState.Ready, value: true } as Update,
            message: null,
            error: null,
        };
        sessionHandler.sendEvent(payload);
        setIsReady(true);
        if (clientId) {
            setReadyUsers((prev) => {
                const next = new Set(prev);
                next.add(clientId);
                return next;
            });
        }
    }

    function handlePauseClick() {
        if (!sessionHandler) return;
        const type = isPaused ? DrawingState.Resume : DrawingState.Pause;
        const payload: WsData = {
            event: WsEvent.DrawingUpdate,
            data: { type, value: true } as Update,
            message: null,
            error: null,
        };
        sessionHandler.sendEvent(payload);
        setIsPaused(!isPaused);
    }

    function handleExtendClick() {
        if (!sessionHandler || !timerExtendable) return;
        const payload: WsData = {
            event: WsEvent.DrawingUpdate,
            data: { type: DrawingState.ExtendTime, value: 30 } as Update,
            message: null,
            error: null,
        };
        sessionHandler.sendEvent(payload);
    }

    const timerProgress = React.useMemo(() => {
        if (time === null || timeLeft === null) return 1;
        const total = time + timeLeft;
        if (total <= 0) return 0;
        const progress = timeLeft / total;
        return Math.max(0, Math.min(1, progress));
    }, [time, timeLeft]);

    return (
        <div className={styles.layout}>
            <div className={styles.leftColumn}>
                <PriorImages sessionId={sessionId} />
            </div>
            <div className={styles.centerColumn}>
                <div className={styles.header}>
                    <div className={styles.titleBlock}>
                        <h1 className={styles.title}>{topic}</h1>
                        <p className={styles.description}>{goal}</p>
                    </div>
                    <div className={styles.timerBox}>
                        {isAdmin && timerExtendable && (
                            <Button
                                variant="secondary"
                                className={styles.extendButton}
                                onClick={handleExtendClick}
                                title="Timer um 30 Sekunden verlängern"
                            >
                                +30s
                            </Button>
                        )}
                        <span className={styles.timerValue}>{formatTime(timeLeft)}</span>
                    </div>
                </div>
                {isClient && (
                    <React.Suspense fallback={null}>
                        <DrawBoard
                            ref={drawboardRef}
                            timerProgress={timerProgress}
                            allowWriting={writingEnabled}
                            allowDrawing={drawingEnabled}
                            allowImageUpload={digitalUploadEnabled}
                        />
                    </React.Suspense>
                )}
                {/*<Button onClick={showCanvas}>Show Canvas</Button>*/}
            </div>
            <div className={styles.rightColumn}>
                <div className={styles.userList}>
                    <ul>
                        {users.map((u, i) => (
                            <li key={i} className={styles.userListItem}>
                                <div className={styles.avatarWrap}>
                                    {(() => {
                                        const src = getAvatarSrc(u);
                                        if (src) {
                                            return (
                                                <Image
                                                    className={styles.avatarImg}
                                                    src={src}
                                                    alt={u.name ?? "User"}
                                                    width={40}
                                                    height={40}
                                                />
                                            );
                                        }
                                        return (
                                            <div className={styles.avatar}>
                                                {(u.name ?? "N").trim().charAt(0).toUpperCase() || "?"}
                                            </div>
                                        );
                                    })()}
                                    {readyUsers.has(u.id) && <span className={styles.readyDot}>✓</span>}
                                </div>
                                <span className={styles.userName}>{u.name}</span>
                            </li>
                        ))}
                    </ul>
                </div>
                {creativeSupportEnabled && (
                    <div className={styles.inspirationCard}>
                        <div className={styles.inspirationText}>Keine Idee? Hol dir Inspirationen.</div>
                        <RandomUnsplash compact />
                    </div>
                )}
                <div className={styles.rightButtons}>
                    {isAdmin && (
                        <Button
                            variant="secondary"
                            className={styles.pauseButton}
                            onClick={handlePauseClick}
                            disabled={isPaused}
                        >
                            {isPaused ? "Timer fortsetzen" : "Timer stoppen"}
                        </Button>
                    )}
                    {readyCheckEnabled && (
                        <Button
                            variant={isReady ? "secondary" : "primary"}
                            className={styles.readyButton}
                            onClick={handleReadyClick}
                            disabled={isReady}
                        >
                            {isReady ? "Warte..." : "Fertig"}
                        </Button>
                    )}
                </div>
            </div>
        </div>
    );
}

export default Drawing;


