import { useCallback, useEffect, useRef, useState } from "react";
import type { CmsPageData } from "@/components/CmsPageContent";
import { useAuth } from "@/contexts/AuthContext";
import { cmsPageFetch } from "@/lib/siteApi";

type UseCmsPageResult = {
  page: CmsPageData | null;
  loading: boolean;
  notFound: boolean;
  unauthorized: boolean;
  error: boolean;
  retry: () => void;
};

type SettledResult =
  | { status: "success"; page: CmsPageData }
  | { status: "not_found" }
  | { status: "unauthorized" }
  | { status: "error" };

/** Fetch a published CMS page only after site session is verified. */
export function useCmsPage(apiPath: string | null): UseCmsPageResult {
  const { isAuthenticated, loading: authLoading } = useAuth();
  const [page, setPage] = useState<CmsPageData | null>(null);
  const [loading, setLoading] = useState(true);
  const [notFound, setNotFound] = useState(false);
  const [unauthorized, setUnauthorized] = useState(false);
  const [error, setError] = useState(false);
  const [retryToken, setRetryToken] = useState(0);

  const requestIdRef = useRef(0);
  const settledPathRef = useRef<string | null>(null);
  const settledResultRef = useRef<{ path: string; result: SettledResult } | null>(null);

  const applySettledResult = useCallback((result: SettledResult) => {
    setPage(result.status === "success" ? result.page : null);
    setNotFound(result.status === "not_found");
    setUnauthorized(result.status === "unauthorized");
    setError(result.status === "error");
  }, []);

  const retry = useCallback(() => {
    settledPathRef.current = null;
    settledResultRef.current = null;
    setRetryToken((value) => value + 1);
  }, []);

  useEffect(() => {
    if (authLoading) {
      return;
    }

    if (!isAuthenticated) {
      settledPathRef.current = null;
      settledResultRef.current = null;
      setPage(null);
      setNotFound(false);
      setUnauthorized(true);
      setError(false);
      setLoading(false);
      return;
    }

    if (!apiPath) {
      settledPathRef.current = null;
      settledResultRef.current = null;
      setPage(null);
      setNotFound(true);
      setUnauthorized(false);
      setError(false);
      setLoading(false);
      return;
    }

    if (
      settledPathRef.current === apiPath &&
      settledResultRef.current?.path === apiPath
    ) {
      applySettledResult(settledResultRef.current.result);
      setLoading(false);
      return;
    }

    const requestId = ++requestIdRef.current;
    settledPathRef.current = apiPath;
    setLoading(true);
    setNotFound(false);
    setUnauthorized(false);
    setError(false);
    setPage(null);

    const loadPage = async () => {
      try {
        const res = await cmsPageFetch(apiPath);

        if (requestId !== requestIdRef.current) {
          return;
        }

        if (res.status === 401) {
          const result: SettledResult = { status: "unauthorized" };
          settledResultRef.current = { path: apiPath, result };
          applySettledResult(result);
          return;
        }

        if (res.status === 404) {
          console.error(`[useCmsPage] Page not found (404): ${apiPath}`);
          const result: SettledResult = { status: "not_found" };
          settledResultRef.current = { path: apiPath, result };
          applySettledResult(result);
          return;
        }

        if (!res.ok) {
          console.error(`[useCmsPage] Failed to load page (${res.status}): ${apiPath}`);
          const result: SettledResult = { status: "error" };
          settledResultRef.current = { path: apiPath, result };
          applySettledResult(result);
          return;
        }

        const data = (await res.json()) as { page?: CmsPageData };
        if (requestId !== requestIdRef.current) {
          return;
        }

        if (!data.page) {
          console.error(`[useCmsPage] Missing page payload: ${apiPath}`);
          const result: SettledResult = { status: "error" };
          settledResultRef.current = { path: apiPath, result };
          applySettledResult(result);
          return;
        }

        const result: SettledResult = { status: "success", page: data.page };
        settledResultRef.current = { path: apiPath, result };
        applySettledResult(result);
      } catch (err) {
        if (requestId !== requestIdRef.current) {
          return;
        }
        console.error(`[useCmsPage] Error fetching page: ${apiPath}`, err);
        const result: SettledResult = { status: "error" };
        settledResultRef.current = { path: apiPath, result };
        applySettledResult(result);
      } finally {
        if (requestId === requestIdRef.current) {
          setLoading(false);
        }
      }
    };

    void loadPage();

    return () => {
      requestIdRef.current += 1;
    };
  }, [apiPath, authLoading, isAuthenticated, retryToken, applySettledResult]);

  return { page, loading, notFound, unauthorized, error, retry };
}
