import { useState, type ReactNode } from "react";
import {
    AlertTriangle,
    Eye,
    EyeOff,
    Monitor,
    MousePointerClick,
    Plug,
    ShieldCheck,
    Wifi,
    Wrench,
} from "lucide-react";
import { useVncConsole, type VncConnectionState } from "../hooks/useVncConsole";

type ConsolePageProps = {
    theme: "dark" | "light";
};

const RADIUS = "rounded-[5px]";

export function ConsolePage({ theme }: ConsolePageProps) {
    const isDark = theme === "dark";

    const vnc = useVncConsole({
        websocketUrl: "ws://localhost:18450/ws/vnc",
        defaultHost: "198.19.0.176",
        defaultPort: 5900,
    });
    const [passwordVisible, setPasswordVisible] = useState(false);
    const connectionLabel = getConnectionLabel(vnc.state);
    const hasFrame = vnc.frameSize.width > 0 && vnc.frameSize.height > 0;
    const frameAspectRatio = hasFrame
        ? `${vnc.frameSize.width} / ${vnc.frameSize.height}`
        : "800 / 480";

    return (
        <div className={isDark ? "h-full min-h-0 text-slate-100" : "h-full min-h-0 text-slate-950"}>
            <section className="grid h-full min-h-0 gap-4 xl:grid-cols-[300px_minmax(0,1fr)]">
                <aside className={panelClass(isDark)}>
                    <div className="mb-5">
                        <p className="text-xs font-black uppercase tracking-[0.20em] text-slate-500">
                            ACESSO REMOTO
                        </p>
                        <h2 className={panelTitleClass(isDark)}>
                            Controlador
                        </h2>
                    </div>

                    <div className="grid grid-cols-1 gap-2">
                        <StatusCard
                            theme={theme}
                            icon={<Wifi className="h-4 w-4" />}
                            title="Estado da sessão"
                            value={connectionLabel}
                            color={vnc.connected ? "green" : vnc.connecting ? "blue" : "purple"}
                        />
                    </div>

                    <div className="mt-5 space-y-4">
                        <Field
                            theme={theme}
                            label="Host"
                            value={vnc.host}
                            onChange={vnc.setHost}
                            disabled={vnc.connecting || vnc.connected}
                        />

                        <Field
                            theme={theme}
                            label="Porta"
                            value={String(vnc.port)}
                            onChange={(value) => {
                                const parsed = Number(value);
                                vnc.setPort(Number.isFinite(parsed) ? parsed : 5900);
                            }}
                            disabled={vnc.connecting || vnc.connected}
                        />

                        <Field
                            theme={theme}
                            label="Password"
                            type={passwordVisible ? "text" : "password"}
                            value={vnc.password}
                            onChange={vnc.setPassword}
                            disabled={vnc.connecting || vnc.connected}
                            rightElement={
                                <button
                                    type="button"
                                    onClick={() => setPasswordVisible((current) => !current)}
                                    disabled={vnc.connecting || vnc.connected}
                                    className={
                                        isDark
                                            ? "grid h-8 w-8 place-items-center rounded-[5px] text-slate-400 transition hover:bg-white/5 hover:text-slate-100 disabled:cursor-not-allowed disabled:opacity-40"
                                            : "grid h-8 w-8 place-items-center rounded-[5px] text-slate-500 transition hover:bg-slate-100 hover:text-slate-900 disabled:cursor-not-allowed disabled:opacity-40"
                                    }
                                    aria-label={passwordVisible ? "Esconder password" : "Mostrar password"}
                                >
                                    {passwordVisible ? (
                                        <EyeOff className="h-4 w-4" />
                                    ) : (
                                        <Eye className="h-4 w-4" />
                                    )}
                                </button>
                            }
                        />
                    </div>

                    <button
                        type="button"
                        disabled={vnc.connecting}
                        onClick={() => (vnc.connected ? vnc.disconnect() : vnc.connect())}
                        className="mt-5 flex h-11 w-full items-center justify-center gap-2 rounded-[5px] bg-[#4FD1C5] text-sm font-black text-[#031014] transition hover:bg-[#5FE1D5] disabled:cursor-not-allowed disabled:opacity-50"
                    >
                        <Plug className="h-4 w-4" />
                        {vnc.connected ? "Desligar sessão" : vnc.connecting ? "A ligar..." : "Iniciar sessão"}
                    </button>

                    {vnc.error && (
                        <div className="mt-4 flex gap-3 rounded-[5px] border border-red-500/25 bg-red-500/10 p-4 text-xs font-semibold leading-5 text-red-200">
                            <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" />
                            <span>{vnc.error}</span>
                        </div>
                    )}

                    <div className="mt-6 space-y-3">
                        <SmallInfo theme={theme} icon={<ShieldCheck className="h-4 w-4" />} label="Modo" value="LAN direta" />
                        <SmallInfo theme={theme} icon={<Wrench className="h-4 w-4" />} label="Controlador" value={vnc.host} />
                        <SmallInfo theme={theme} icon={<MousePointerClick className="h-4 w-4" />} label="Interação" value="Cliques ativos" />
                    </div>
                </aside>

                <section className={`${panelClass(isDark)} min-w-0 p-0`}>
                    <header className="flex h-14 shrink-0 items-center justify-between border-b border-white/10 px-5">
                        <div>
                            <h2 className={panelTitleClass(isDark)}>
                                Ecrã do controlador
                            </h2>
                            <p className="mt-0.5 text-xs font-semibold text-slate-500">
                                {vnc.lastFrameAt ? `Último frame: ${vnc.lastFrameAt}` : "A aguardar imagem da consola"}
                            </p>
                        </div>
                    </header>

                    <div className="relative flex min-h-0 flex-1 items-center justify-center overflow-hidden bg-black">
                        {!hasFrame && (
                            <div className="flex max-w-md flex-col items-center text-center">
                                <div className="grid h-16 w-16 place-items-center rounded-[5px] border border-sky-400/20 bg-sky-400/10">
                                    <Monitor className="h-8 w-8 text-[#4FD1C5]" />
                                </div>

                                <h3 className="mt-5 text-xl font-black tracking-[-0.04em] text-white">
                                    {vnc.state === "DISCONNECTED" ? "Sessão terminada" : "Consola indisponível"}
                                </h3>
                                <p className="mt-2 text-sm leading-6 text-slate-400">
                                    {vnc.state === "DISCONNECTED"
                                        ? "Inicie uma nova sessão para voltar a aceder ao controlador."
                                        : "Inicie uma sessão VNC para visualizar e controlar o controlador."}
                                </p>
                            </div>
                        )}

                        <div
                            onPointerDown={hasFrame ? vnc.handleCanvasPointerDown : undefined}
                            onContextMenu={(event) => event.preventDefault()}
                            className={
                                hasFrame
                                    ? "flex h-full w-full cursor-crosshair items-center justify-center overflow-hidden bg-black"
                                    : "pointer-events-none absolute h-px w-px overflow-hidden opacity-0"
                            }
                        >
                            <canvas
                                ref={vnc.canvasRef}
                                className="pointer-events-none block max-h-full max-w-full bg-black object-contain [image-rendering:pixelated]"
                                style={{
                                    aspectRatio: frameAspectRatio,
                                    width: "100%",
                                    height: "100%",
                                }}
                            />
                        </div>
                    </div>
                </section>
            </section>
        </div>
    );
}

function panelClass(isDark: boolean) {
    return isDark
        ? `${RADIUS} flex h-full min-h-0 flex-col border border-white/10 bg-[#071421] p-3 shadow-[0_14px_34px_rgba(0,0,0,0.22)]`
        : `${RADIUS} flex h-full min-h-0 flex-col border border-slate-200 bg-white p-3 shadow-[0_10px_26px_rgba(15,23,42,0.06)]`;
}

function panelTitleClass(isDark: boolean) {
    return isDark
        ? "text-base font-black text-slate-100"
        : "text-base font-black text-slate-950";
}

function getConnectionLabel(state: VncConnectionState) {
    switch (state) {
        case "CONNECTING_WS":
            return "A ligar WS";
        case "CONNECTING_VNC":
            return "A ligar VNC";
        case "CONNECTED":
            return "Ligado";
        case "FIRST_FRAME":
            return "Ativo";
        case "DISCONNECTED":
            return "Desconectado";
        case "ERROR":
            return "Erro";
        case "IDLE":
        default:
            return "A aguardar...";
    }
}

function Field({
    theme,
    label,
    value,
    onChange,
    type = "text",
    disabled,
    rightElement,
}: {
    theme: "dark" | "light";
    label: string;
    value: string;
    onChange: (value: string) => void;
    type?: string;
    disabled?: boolean;
    rightElement?: ReactNode;
}) {
    const isDark = theme === "dark";

    return (
        <label className="block">
            <span
                className={
                    isDark
                        ? "text-[11px] font-black uppercase tracking-[0.20em] text-[#7F8CA3]"
                        : "text-[11px] font-black uppercase tracking-[0.20em] text-slate-500"
                }
            >
                {label}
            </span>

            <div className="relative mt-2">
                <input
                    type={type}
                    value={value}
                    disabled={disabled}
                    onChange={(event) => onChange(event.target.value)}
                    className={
                        isDark
                            ? `${RADIUS} h-10 w-full border border-[#263247] bg-[#07101B] px-3 ${rightElement ? "pr-11" : ""} text-sm font-bold text-white outline-none transition placeholder:text-[#526074] focus:border-[#4FD1C5] disabled:cursor-not-allowed disabled:opacity-60`
                            : `${RADIUS} h-10 w-full border border-slate-200 bg-white px-3 ${rightElement ? "pr-11" : ""} text-sm font-bold text-[#0F172A] outline-none transition placeholder:text-slate-400 focus:border-[#0F766E] disabled:cursor-not-allowed disabled:opacity-60`
                    }
                />

                {rightElement && (
                    <div className="absolute right-1 top-1/2 -translate-y-1/2">
                        {rightElement}
                    </div>
                )}
            </div>
        </label>
    );
}

function StatusCard({
    theme,
    icon,
    title,
    value,
    color,
}: {
    theme: "dark" | "light";
    icon: ReactNode;
    title: string;
    value: string;
    color: "green" | "blue" | "purple";
}) {
    const isDark = theme === "dark";

    const colors = {
        green: isDark
            ? "bg-[#13202F] text-[#4FD1C5]"
            : "bg-[#ECFDF5] text-[#0F766E]",

        blue: isDark
            ? "bg-[#13202F] text-[#7DD3FC]"
            : "bg-[#EFF6FF] text-[#0369A1]",

        purple: isDark
            ? "bg-[#171B2B] text-[#A5B4FC]"
            : "bg-[#EEF2FF] text-[#4F46E5]",
    };

    return (
        <div
            className={
                isDark
                    ? `${RADIUS} min-w-0 border border-[#263247] bg-[#111A2B] p-3`
                    : `${RADIUS} min-w-0 border border-[#D7DEE8] bg-[#F8FAFC] p-3`
            }
        >
            <div className="flex min-w-0 items-center gap-3">
                <div
                    className={`grid h-10 w-10 shrink-0 place-items-center ${RADIUS} ${colors[color]}`}
                >
                    {icon}
                </div>

                <div className="min-w-0">
                    <p
                        className={
                            isDark
                                ? "truncate text-[10px] font-bold uppercase tracking-[0.18em] text-[#7F8CA3]"
                                : "truncate text-[10px] font-bold uppercase tracking-[0.18em] text-slate-500"
                        }
                    >
                        {title}
                    </p>

                    <h3
                        className={
                            isDark
                                ? "mt-1 truncate text-sm font-black text-white"
                                : "mt-1 truncate text-sm font-black text-[#0F172A]"
                        }
                    >
                        {value}
                    </h3>
                </div>
            </div>
        </div>
    );
}

function SmallInfo({
    theme,
    icon,
    label,
    value,
}: {
    theme: "dark" | "light";
    icon: ReactNode;
    label: string;
    value: string;
}) {
    const isDark = theme === "dark";

    return (
        <div className="flex min-w-0 items-center gap-3">
            <div
                className={
                    isDark
                        ? `${RADIUS} grid h-9 w-9 shrink-0 place-items-center bg-[#13202F] text-[#4FD1C5]`
                        : `${RADIUS} grid h-9 w-9 shrink-0 place-items-center bg-[#ECFDF5] text-[#0F766E]`
                }
            >
                {icon}
            </div>

            <div className="min-w-0">
                <p
                    className={
                        isDark
                            ? "truncate text-[10px] font-black uppercase tracking-[0.18em] text-[#7F8CA3]"
                            : "truncate text-[10px] font-black uppercase tracking-[0.18em] text-slate-500"
                    }
                >
                    {label}
                </p>
                <p
                    className={
                        isDark
                            ? "mt-1 truncate text-xs font-black text-white"
                            : "mt-1 truncate text-xs font-black text-[#0F172A]"
                    }
                >
                    {value}
                </p>
            </div>
        </div>
    );
}

export default ConsolePage;