import {
    createContext,
    type ReactNode,
    useCallback,
    useContext,
    useEffect,
    useMemo,
    useState,
    useTransition,
} from 'react';
import {workspaceList, workspaceInfo, type WorkspaceListResponse, type WorkspaceInfoResponse} from '@/client';

interface WorkspaceContextValue {
    workspaceSlug: string | null;
    workspaces: WorkspaceListResponse | null;
    currentWorkspace: WorkspaceInfoResponse | null;
    isLoading: boolean;
    isPending: boolean;
    error: Error | null;
    refetch: () => Promise<void>;
}

const WorkspaceContext = createContext<WorkspaceContextValue | null>(null);

interface WorkspaceProviderProps {
    workspaceSlug: string | null;
    children: ReactNode;
}

export function WorkspaceProvider({workspaceSlug, children}: WorkspaceProviderProps) {
    const [currentWorkspace, setCurrentWorkspace] = useState<WorkspaceInfoResponse | null>(null);
    const [workspaces, setWorkspaces] = useState<WorkspaceListResponse | null>(null);
    const [error, setError] = useState<Error | null>(null);
    const [isLoading, setIsLoading] = useState(false);
    const [isPending, startTransition] = useTransition();

    const fetchWorkspaces = useCallback(async () => {
        try {
            const resp = await workspaceList();
            setWorkspaces(resp.data?.data ?? null);
        } catch {
            // non-critical, ignore
        }
    }, []);

    const fetchCurrentWorkspace = useCallback(async () => {
        if (!workspaceSlug) {
            setCurrentWorkspace(null);
            setError(null);
            return;
        }
        setIsLoading(true);
        setError(null);
        try {
            const resp = await workspaceInfo({path: {slug: workspaceSlug}});
            setCurrentWorkspace(resp.data?.data ?? null);
        } catch (err) {
            setCurrentWorkspace(null);
            setError(err instanceof Error ? err : new Error('Failed to load workspace'));
        } finally {
            setIsLoading(false);
        }
    }, [workspaceSlug]);

    useEffect(() => {
        fetchWorkspaces();
        fetchCurrentWorkspace();
    }, [fetchWorkspaces, fetchCurrentWorkspace]);

    const refetch = useCallback(async () => {
        startTransition(async () => {
            await fetchCurrentWorkspace();
            await fetchWorkspaces();
        });
    }, [fetchCurrentWorkspace, fetchWorkspaces]);

    const value = useMemo<WorkspaceContextValue>(() => ({
        workspaceSlug,
        workspaces,
        currentWorkspace,
        isLoading: isLoading || isPending,
        isPending,
        error,
        refetch,
    }), [workspaceSlug, workspaces, currentWorkspace, isLoading, isPending, error, refetch]);

    return (
        <WorkspaceContext.Provider value={value}>
            {children}
        </WorkspaceContext.Provider>
    );
}

export function useWorkspace() {
    const ctx = useContext(WorkspaceContext);
    if (!ctx) throw new Error('useWorkspace must be used within WorkspaceProvider');
    return ctx;
}

/** Returns null when used outside WorkspaceProvider (safe for use in shared components). */
export function tryUseWorkspace(): WorkspaceContextValue | null {
    const ctx = useContext(WorkspaceContext);
    return ctx;
}
