import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { WorkoutSession, WorkoutPlan } from '../types';
import { useAuth } from './AuthContext';
import { getSessions, saveSession, deleteSession as apiDeleteSession } from '../services/sessions';
import { getPlans, savePlan as apiSavePlan, deletePlan as apiDeletePlan } from '../services/plans';

interface SessionContextType {
    sessions: WorkoutSession[];
    plans: WorkoutPlan[];
    isLoading: boolean;
    refreshData: () => Promise<void>;
    updateSession: (session: WorkoutSession) => Promise<void>;
    deleteSession: (id: string) => Promise<void>;
    savePlan: (plan: WorkoutPlan) => Promise<void>;
    deletePlan: (id: string) => Promise<void>;
}

const SessionContext = createContext<SessionContextType | undefined>(undefined);

export const SessionProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const { currentUser } = useAuth();
    const [sessions, setSessions] = useState<WorkoutSession[]>([]);
    const [plans, setPlans] = useState<WorkoutPlan[]>([]);
    const [isLoading, setIsLoading] = useState<boolean>(true);

    const refreshData = useCallback(async () => {
        if (!currentUser) {
            setSessions([]);
            setPlans([]);
            setIsLoading(false);
            return;
        }

        try {
            setIsLoading(true);
            const [fetchedSessions, fetchedPlans] = await Promise.all([
                getSessions(currentUser.id),
                getPlans(currentUser.id)
            ]);
            setSessions(fetchedSessions);
            setPlans(fetchedPlans);
        } catch (error) {
            console.error('Failed to fetch data', error);
        } finally {
            setIsLoading(false);
        }
    }, [currentUser]);

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

    const updateSession = async (session: WorkoutSession) => {
        if (!currentUser) return;
        try {
            await saveSession(currentUser.id, session);
            setSessions(prev => {
                const existing = prev.find(s => s.id === session.id);
                if (existing) {
                    return prev.map(s => s.id === session.id ? session : s);
                } else {
                    return [session, ...prev];
                }
            });
        } catch (error) {
            console.error('Failed to update session', error);
            throw error;
        }
    };

    const deleteSession = async (id: string) => {
        if (!currentUser) return;
        try {
            await apiDeleteSession(currentUser.id, id);
            setSessions(prev => prev.filter(s => s.id !== id));
        } catch (error) {
            console.error('Failed to delete session', error);
            throw error;
        }
    };

    const savePlan = async (plan: WorkoutPlan) => {
        if (!currentUser) return;
        try {
            await apiSavePlan(currentUser.id, plan);
            setPlans(prev => {
                const existing = prev.find(p => p.id === plan.id);
                if (existing) {
                    return prev.map(p => p.id === plan.id ? plan : p);
                } else {
                    return [...prev, plan];
                }
            });
        } catch (error) {
            console.error('Failed to save plan', error);
            throw error;
        }
    };

    const deletePlan = async (id: string) => {
        if (!currentUser) return;
        try {
            await apiDeletePlan(currentUser.id, id);
            setPlans(prev => prev.filter(p => p.id !== id));
        } catch (error) {
            console.error('Failed to delete plan', error);
            throw error;
        }
    };

    return (
        <SessionContext.Provider value={{
            sessions,
            plans,
            isLoading,
            refreshData,
            updateSession,
            deleteSession,
            savePlan,
            deletePlan
        }}>
            {children}
        </SessionContext.Provider>
    );
};

export const useSession = () => {
    const context = useContext(SessionContext);
    if (context === undefined) {
        throw new Error('useSession must be used within a SessionProvider');
    }
    return context;
};
