"use client";

import { createContext, useContext, useEffect, useState } from "react";
import { api, SesionVencida, type Sesion } from "@/lib/api";
import { capturarTokenDeLaUrl } from "@/lib/sesion";

type Estado =
  | { fase: "cargando" }
  | { fase: "sin-sesion"; motivo: string }
  | { fase: "lista"; sesion: Sesion };

const Contexto = createContext<Estado>({ fase: "cargando" });

export function useSesion(): Estado {
  return useContext(Contexto);
}

/**
 * Permiso del usuario. Sirve para decidir qué se MUESTRA.
 *
 * ⚠️ No es una defensa: el servidor vuelve a verificar el permiso en cada operación, y
 * por línea de producción. Esconder un botón evita que alguien pierda el tiempo con algo
 * que no va a poder hacer; no evita que alguien llame la ruta a mano.
 */
export function usePuede(permiso: string): boolean {
  const estado = useSesion();
  if (estado.fase !== "lista") return false;
  return estado.sesion.administrador || estado.sesion.permisos.includes(permiso);
}

export function ProveedorDeSesion({ children }: { children: React.ReactNode }) {
  const [estado, setEstado] = useState<Estado>({ fase: "cargando" });

  useEffect(() => {
    const token = capturarTokenDeLaUrl();

    if (!token) {
      setEstado({
        fase: "sin-sesion",
        motivo:
          "Esta pantalla se abre desde el Back Office, que es el que entrega la sesión.",
      });
      return;
    }

    api<Sesion>("/api/sesion/yo")
      .then((sesion) => setEstado({ fase: "lista", sesion }))
      .catch((error: unknown) => {
        setEstado({
          fase: "sin-sesion",
          motivo:
            error instanceof SesionVencida || error instanceof Error
              ? error.message
              : "No se pudo verificar la sesión.",
        });
      });
  }, []);

  return <Contexto.Provider value={estado}>{children}</Contexto.Provider>;
}
