'use client';

import {
    createContext,
    useCallback,
    useContext,
    useLayoutEffect,
    useMemo,
    useState,
    type ReactNode,
} from 'react';

/**
 * Shell de solicitações: o layout filho regista título/ações no header do provider.
 *
 * Importante — dois contextos:
 * - **Setters** (estável): usado por `useSolicitacoesChrome` / presença do shell.
 * - **State** (muda): consumido só por `SolicitacoesLayoutInner`.
 *
 * Se o registante (ex. `FeiraListScreenLayout`) subscrever o mesmo value que inclui
 * `headerAction`, cada `setHeaderAction(<Toolbar novo />)` re-renderiza o filho,
 * cria outro elemento e dispara "Maximum update depth exceeded".
 */

type SolicitacoesChromeSetters = {
    setPageTitle: (title: string) => void;
    setHeaderAction: (action: ReactNode | null) => void;
};

type SolicitacoesChromeState = {
    pageTitle: string;
    headerAction: ReactNode | null;
};

const SolicitacoesChromeSettersContext = createContext<SolicitacoesChromeSetters | null>(null);
const SolicitacoesChromeStateContext = createContext<SolicitacoesChromeState | null>(null);

export function SolicitacoesChromeProvider({ children }: { children: ReactNode }) {
    const [pageTitle, setPageTitleState] = useState('');
    const [headerAction, setHeaderActionState] = useState<ReactNode | null>(null);

    const setPageTitle = useCallback((title: string) => {
        setPageTitleState((prev) => (prev === title ? prev : title));
    }, []);

    const setHeaderAction = useCallback((action: ReactNode | null) => {
        setHeaderActionState(action);
    }, []);

    const setters = useMemo(
        () => ({ setPageTitle, setHeaderAction }),
        [setPageTitle, setHeaderAction],
    );

    const state = useMemo(
        () => ({ pageTitle, headerAction }),
        [pageTitle, headerAction],
    );

    return (
        <SolicitacoesChromeSettersContext.Provider value={setters}>
            <SolicitacoesChromeStateContext.Provider value={state}>
                {children}
            </SolicitacoesChromeStateContext.Provider>
        </SolicitacoesChromeSettersContext.Provider>
    );
}

export function useSolicitacoesShellActive(): boolean {
    return useContext(SolicitacoesChromeSettersContext) !== null;
}

export function useSolicitacoesPageTitle(): string {
    return useContext(SolicitacoesChromeStateContext)?.pageTitle ?? 'Solicitações';
}

export function useSolicitacoesHeaderAction(): ReactNode | null {
    return useContext(SolicitacoesChromeStateContext)?.headerAction ?? null;
}

/**
 * Define título e ações do header no shell partilhado de solicitações.
 * Fora do provider, não faz nada (telas fora de `/feira/solicitacoes/*`).
 */
export function useSolicitacoesChrome(meta: {
    pageTitle: string;
    headerAction?: ReactNode | null;
}): void {
    const setters = useContext(SolicitacoesChromeSettersContext);
    const title = meta.pageTitle;
    const headerAction = meta.headerAction ?? null;

    useLayoutEffect(() => {
        if (!setters) return;
        setters.setPageTitle(title);
    }, [setters, title]);

    useLayoutEffect(() => {
        if (!setters) return;
        setters.setHeaderAction(headerAction);
        return () => {
            setters.setHeaderAction(null);
        };
    }, [setters, headerAction]);
}
