"use client";

import { BrivenAuthProvider } from "@briven/auth/react";
import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from "react";

import { getBrivenAuth } from "@/lib/auth";
import type { DemoSession } from "@/lib/auth-config";
import {
  clearDemoSession,
  readDemoSession,
  writeDemoSession,
} from "@/lib/demo-session";

type PortalAuthContextValue = {
  brivenConfigured: boolean;
  demoSession: DemoSession | null;
  setDemoSession: (s: DemoSession) => void;
  clearDemo: () => void;
  refreshDemo: () => void;
};

const PortalAuthContext = createContext<PortalAuthContextValue | null>(null);

function readInitialDemo(): DemoSession | null {
  if (typeof window === "undefined") return null;
  return readDemoSession();
}

export function PortalAuthProvider({ children }: { children: ReactNode }) {
  const client = useMemo(() => getBrivenAuth(), []);
  const [demoSession, setDemo] = useState<DemoSession | null>(readInitialDemo);

  const refreshDemo = useCallback(() => {
    setDemo(readDemoSession());
  }, []);

  useEffect(() => {
    const onChange = () => setDemo(readDemoSession());
    window.addEventListener("krypco-auth-change", onChange);
    window.addEventListener("storage", onChange);
    return () => {
      window.removeEventListener("krypco-auth-change", onChange);
      window.removeEventListener("storage", onChange);
    };
  }, []);

  const value: PortalAuthContextValue = {
    brivenConfigured: Boolean(client),
    demoSession,
    setDemoSession: (s) => {
      writeDemoSession(s);
      setDemo(s);
    },
    clearDemo: () => {
      clearDemoSession();
      setDemo(null);
    },
    refreshDemo,
  };

  const tree = (
    <PortalAuthContext.Provider value={value}>
      {children}
    </PortalAuthContext.Provider>
  );

  if (client) {
    return <BrivenAuthProvider value={client}>{tree}</BrivenAuthProvider>;
  }
  return tree;
}

export function usePortalAuth(): PortalAuthContextValue {
  const ctx = useContext(PortalAuthContext);
  if (!ctx) {
    throw new Error("usePortalAuth must be used inside PortalAuthProvider");
  }
  return ctx;
}
