import type { ReactNode } from 'react';
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { apiClient } from '@/lib/api-client';
import {
    LEADS_QUERY,
    CAMPAIGNS_QUERY,
    ADS_QUERY,
    FOLLOW_UPS_QUERY,
    LEAD_ACTIVITIES_QUERY,
    CALLS_QUERY,
} from '@/lib/queries';
import {
    transformLeads,
    transformCampaigns,
    transformAds,
    transformFollowUps,
    transformLeadActivities,
    transformCalls,
} from '@/lib/transforms';

import type { Lead, Campaign, Ad, LeadActivity, FollowUp, WhatsAppTemplate, Agent, Call, LeadIngestionSource } from '@/types/entities';

type DataContextType = {
    leads: Lead[];
    campaigns: Campaign[];
    ads: Ad[];
    followUps: FollowUp[];
    leadActivities: LeadActivity[];
    templates: WhatsAppTemplate[];
    agents: Agent[];
    calls: Call[];
    ingestionSources: LeadIngestionSource[];
    loading: boolean;
    error: string | null;
    updateLead: (id: string, updates: Partial<Lead>) => void;
    addCall: (call: Call) => void;
    refresh: () => void;
};

const DataContext = createContext<DataContextType | undefined>(undefined);

export const useData = (): DataContextType => {
    const context = useContext(DataContext);

    if (context === undefined) {
        throw new Error('useData must be used within a DataProvider');
    }

    return context;
};

interface DataProviderProps {
    children: ReactNode;
}

export const DataProvider = ({ children }: DataProviderProps) => {
    const [leads, setLeads] = useState<Lead[]>([]);
    const [campaigns, setCampaigns] = useState<Campaign[]>([]);
    const [ads, setAds] = useState<Ad[]>([]);
    const [followUps, setFollowUps] = useState<FollowUp[]>([]);
    const [leadActivities, setLeadActivities] = useState<LeadActivity[]>([]);
    const [calls, setCalls] = useState<Call[]>([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);

    // These don't have platform entities yet — empty for now
    const [templates] = useState<WhatsAppTemplate[]>([]);
    const [agents] = useState<Agent[]>([]);
    const [ingestionSources] = useState<LeadIngestionSource[]>([]);

    const fetchData = useCallback(async () => {
        if (!apiClient.isAuthenticated()) {
            setLoading(false);
            return;
        }

        setLoading(true);
        setError(null);

        try {
            const [leadsData, campaignsData, adsData, followUpsData, activitiesData, callsData] = await Promise.all([
                apiClient.graphql<any>(LEADS_QUERY),
                apiClient.graphql<any>(CAMPAIGNS_QUERY),
                apiClient.graphql<any>(ADS_QUERY),
                apiClient.graphql<any>(FOLLOW_UPS_QUERY),
                apiClient.graphql<any>(LEAD_ACTIVITIES_QUERY),
                apiClient.graphql<any>(CALLS_QUERY),
            ]);

            setLeads(transformLeads(leadsData));
            setCampaigns(transformCampaigns(campaignsData));
            setAds(transformAds(adsData));
            setFollowUps(transformFollowUps(followUpsData));
            setLeadActivities(transformLeadActivities(activitiesData));
            setCalls(transformCalls(callsData));
        } catch (err: any) {
            console.error('Failed to fetch platform data:', err);
            setError(err.message ?? 'Failed to load data');
        } finally {
            setLoading(false);
        }
    }, []);

    useEffect(() => {
        fetchData();
    }, [fetchData]);

    const updateLead = (id: string, updates: Partial<Lead>) => {
        setLeads((prev) => prev.map((lead) => (lead.id === id ? { ...lead, ...updates } : lead)));
    };

    const addCall = (call: Call) => {
        setCalls((prev) => [call, ...prev]);
    };

    return (
        <DataContext.Provider value={{
            leads, campaigns, ads, followUps, leadActivities, templates, agents, calls, ingestionSources,
            loading, error,
            updateLead, addCall, refresh: fetchData,
        }}>
            {children}
        </DataContext.Provider>
    );
};
