"use client";

import { type ReactNode, useEffect, useRef, useState } from "react";
import {
  type AuthDebugTrace,
  type AuthDiagnostics,
  type CapsearchSession,
  getCapsearchAuthDiagnostics,
  getCapsearchSession,
  legacyUrl,
  logoutCapsearchSession,
} from "../lib/capsearchAuth";

type SessionControlsProps = {
  developmentClients: string[];
  children?: ReactNode;
};

const primaryMenuItems = [
  "Organisatie",
  "Mijn gegevens",
  "Financieringscheck",
  "Demo Financieringscheck",
  "Wissel van account",
  "Quickscan dashboard",
];

export function SessionControls({ developmentClients, children }: SessionControlsProps) {
  const [session, setSession] = useState<CapsearchSession | null>(null);
  const [diagnostics, setDiagnostics] = useState<AuthDiagnostics | null>(null);
  const [debugTrace, setDebugTrace] = useState<AuthDebugTrace | null>(null);
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const menuContainerRef = useRef<HTMLDivElement | null>(null);
  const isJwtSessionActive = session !== null;

  useEffect(() => {
    const syncSession = () => {
      void getCapsearchSession().then((data) => setSession(data));
      void getCapsearchAuthDiagnostics().then((data) => setDiagnostics(data));
    };

    syncSession();
    window.addEventListener("capsearch-session-updated", syncSession);

    return () => {
      window.removeEventListener("capsearch-session-updated", syncSession);
    };
  }, []);

  useEffect(() => {
    const onDebug = (event: Event) => {
      const customEvent = event as CustomEvent<AuthDebugTrace>;
      if (customEvent.detail) {
        setDebugTrace(customEvent.detail);
      }
    };

    window.addEventListener("capsearch-auth-debug", onDebug);

    return () => {
      window.removeEventListener("capsearch-auth-debug", onDebug);
    };
  }, []);

  useEffect(() => {
    if (!isMenuOpen) {
      return;
    }

    const handlePointerDown = (event: PointerEvent) => {
      if (!menuContainerRef.current?.contains(event.target as Node)) {
        setIsMenuOpen(false);
      }
    };

    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape") {
        setIsMenuOpen(false);
      }
    };

    window.addEventListener("pointerdown", handlePointerDown);
    window.addEventListener("keydown", handleKeyDown);

    return () => {
      window.removeEventListener("pointerdown", handlePointerDown);
      window.removeEventListener("keydown", handleKeyDown);
    };
  }, [isMenuOpen]);

  const handleLogout = async () => {
    setIsMenuOpen(false);
    await logoutCapsearchSession();
    window.location.href = legacyUrl("logout");
  };

  return (
    <>
      <div
        className={`flex items-center gap-2 rounded-full border px-3 py-1 text-[12px] font-semibold ${
          isJwtSessionActive
            ? "border-emerald-300 bg-emerald-50 text-emerald-700"
            : "border-slate-300 bg-slate-100 text-slate-600"
        }`}
        title={
          diagnostics
            ? `me:${diagnostics.meBefore} session-token:${diagnostics.sessionToken} me2:${diagnostics.meAfterSessionToken} refresh:${diagnostics.refresh} me3:${diagnostics.meAfterRefresh}`
            : isJwtSessionActive
              ? "JWT session actief"
              : "JWT session niet actief"
        }
      >
        <span
          className={`inline-block h-2 w-2 rounded-full ${
            isJwtSessionActive ? "bg-emerald-500" : "bg-slate-400"
          }`}
        />
        {isJwtSessionActive ? "JWT actief" : "JWT inactief"}
      </div>
      <div className="max-w-[260px] truncate text-[12px] font-medium text-slate-600">
        {session?.user?.name ? `Ingelogd als: ${session.user.name}` : "Ingelogd als: -"}
      </div>

      <label htmlFor="development-role-select" className="sr-only">
        Selecteer test client
      </label>
      <select
        id="development-role-select"
        defaultValue=""
        className="h-[38px] w-[220px] rounded-md border border-[#df6a6a] bg-white px-4 text-[14px] text-[#222] shadow-none outline-none transition focus:border-[#c95252]"
      >
        <option value="" disabled>
          Selecteer test client
        </option>
        {developmentClients.map((client) => (
          <option key={client} value={client}>
            {client}
          </option>
        ))}
      </select>
      {children}

      <div ref={menuContainerRef} className="relative">
        <button
          type="button"
          aria-label="Open personal menu"
          aria-expanded={isMenuOpen}
          aria-haspopup="menu"
          onClick={() => setIsMenuOpen((open) => !open)}
          className="flex h-11 w-11 items-center justify-center rounded-full bg-[#53c2b4] text-[16px] font-semibold text-white transition hover:bg-[#43b2a4]"
        >
          {session?.user?.initials ?? "JL"}
        </button>

        {isMenuOpen ? (
          <div
            aria-label="Persoonlijk menu"
            className="absolute right-0 top-[calc(100%+8px)] z-20 w-[205px] overflow-hidden rounded-[4px] border border-[#d2d2d2] bg-white text-[13px] text-[#4f4f4f] shadow-[0_3px_12px_rgba(0,0,0,0.12)]"
          >
            <div className="px-0 py-1.5">
              {primaryMenuItems.map((item) => (
                <div key={item} className="px-[20px] py-[5px]">
                  {item}
                </div>
              ))}
            </div>

            <div className="border-t border-[#d8d8d8] px-0 py-1.5">
              <div className="px-[20px] py-[5px]">Admin</div>
            </div>

            <div className="border-t border-[#d8d8d8] px-0 py-1.5">
              <button
                type="button"
                onClick={() => void handleLogout()}
                className="block w-full px-[20px] py-[5px] text-left transition hover:bg-slate-50"
              >
                Uitloggen
              </button>
            </div>
          </div>
        ) : null}
      </div>

      {process.env.NODE_ENV !== "production" && debugTrace ? (
        <pre className="max-w-[900px] overflow-auto rounded border border-slate-300 bg-slate-50 p-2 text-[11px] text-slate-700">
          {JSON.stringify(debugTrace, null, 2)}
        </pre>
      ) : null}
    </>
  );
}
