import {Config, useBrowseConfig} from '@tryghost/admin-x-framework/api/config';
import {ReactNode, createContext, useContext, useState} from 'react';
import {STATS_DEFAULT_RANGE_KEY, STATS_RANGE_OPTIONS} from '@src/utils/constants';
import {Setting, useBrowseSettings} from '@tryghost/admin-x-framework/api/settings';
import {StatsConfig, useTinybirdToken} from '@tryghost/admin-x-framework';
import {useBrowseSite} from '@tryghost/admin-x-framework/api/site';

interface GlobalData {
    data: Config | undefined;
    site: {
        url?: string;
        icon?: string;
        title?: string;
    };
    statsConfig: StatsConfig | undefined;
    tinybirdToken: string | undefined;
    isLoading: boolean;
    range: number;
    audience: number;
    setAudience: (value: number) => void;
    setRange: (value: number) => void;
    settings: Setting[];
    selectedNewsletterId: string | null;
    setSelectedNewsletterId: (id: string | null) => void;
}

const GlobalDataContext = createContext<GlobalData | undefined>(undefined);

export const useGlobalData = () => {
    const context = useContext(GlobalDataContext);
    if (context === undefined) {
        throw new Error('useGlobalData must be used within a GlobalDataProvider');
    }
    return context;
};

const GlobalDataProvider = ({children}: { children: ReactNode }) => {
    const settings = useBrowseSettings();
    const site = useBrowseSite();
    const config = useBrowseConfig() as unknown as { data: Config & { config: { stats?: StatsConfig } } | null, isLoading: boolean, error: Error | null };
    // Only fetch Tinybird token if stats config is present
    const hasStatsConfig = Boolean(config.data?.config?.stats);
    const tinybirdTokenQuery = useTinybirdToken({enabled: hasStatsConfig});
    const [range, setRange] = useState(STATS_RANGE_OPTIONS[STATS_DEFAULT_RANGE_KEY].value);
    // Initialize with all audiences selected (binary 111 = 7)
    const [audience, setAudience] = useState(7);
    const [selectedNewsletterId, setSelectedNewsletterId] = useState<string | null>(null);

    // Only include tinybirdTokenQuery in requests if stats config is present
    const requests = hasStatsConfig ? [config, settings, site, tinybirdTokenQuery] : [config, settings, site];
    const error = requests.map(request => request.error).find(Boolean);
    const isLoading = requests.some(request => request.isLoading);

    if (error) {
        throw error;
    }

    // Extract site data
    const siteData = {
        url: site.data?.site.url,
        icon: site.data?.site.icon,
        title: site.data?.site.title
    };

    return <GlobalDataContext.Provider value={{
        data: config.data || undefined,
        site: siteData,
        statsConfig: config.data?.config?.stats,
        tinybirdToken: tinybirdTokenQuery.token,
        isLoading,
        range,
        setRange,
        audience,
        setAudience,
        settings: settings.data?.settings || [],
        selectedNewsletterId,
        setSelectedNewsletterId
    }}>
        {children}
    </GlobalDataContext.Provider>;
};

export default GlobalDataProvider;
