import React, { createContext, useContext, useEffect, useState, useMemo, useCallback } from 'react';
import { useAuth } from './AuthContext';
import { secureApi } from '../services/secureApi';

interface UserOrganization {
    orgId: string;
    name: string;
    role: 'owner' | 'admin' | 'employee';
    onboardingCompleted: boolean;
    joinedAt: number;
}

interface UserOrganizationsContextType {
    organizations: UserOrganization[];
    selectedOrgId: string | null;
    loading: boolean;
    selectOrganization: (orgId: string) => void;
    createOrganization: (name: string) => Promise<{ orgId: string; requiresSubscription?: boolean }>;
    joinOrganization: (inviteCode: string) => Promise<string>;
    refreshOrganizations: () => Promise<void>;
    createCheckoutSession: (userEmail: string) => Promise<{ sessionUrl: string; sessionId: string }>;
    getSubscriptionStatus: () => Promise<any>;
}

const UserOrganizationsContext = createContext<UserOrganizationsContextType | undefined>(undefined);

export const UserOrganizationsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const { user } = useAuth();
    const [organizations, setOrganizations] = useState<UserOrganization[]>([]);
    const [selectedOrgId, setSelectedOrgId] = useState<string | null>(null);
    const [loading, setLoading] = useState(true);

    // Load user's organizations - memoized to prevent recreation
    const loadOrganizations = useCallback(async () => {
        if (!user) {
            setOrganizations([]);
            setLoading(false);
            return;
        }

        try {
            // Use secure API for organizations
            const data = await secureApi.getUserOrganizations();
            setOrganizations(data.organizations || []);
        } catch (error) {
            console.error('Failed to load organizations:', error);
            setOrganizations([]);
        } finally {
            setLoading(false);
        }
    }, [user]);

    // Initialize selected org from localStorage (persistent across sessions)
    useEffect(() => {
        const savedOrgId = localStorage.getItem('auditly_selected_org');
        if (savedOrgId) {
            setSelectedOrgId(savedOrgId);
        }
    }, []);

    // Load organizations when user changes
    useEffect(() => {
        loadOrganizations();
    }, [loadOrganizations]);

    // Listen for organization updates (e.g., onboarding completion)
    useEffect(() => {
        const handleOrgUpdate = (event: CustomEvent) => {
            const { orgId, onboardingCompleted } = event.detail;
            console.log('UserOrganizationsContext received org update:', { orgId, onboardingCompleted });

            if (onboardingCompleted && orgId) {
                // Update the specific organization in the list to reflect onboarding completion
                setOrganizations(prev => {
                    const updated = prev.map(org =>
                        org.orgId === orgId
                            ? { ...org, onboardingCompleted: true }
                            : org
                    );
                    console.log('Updated organizations after onboarding completion:', updated);
                    return updated;
                });
            }
        };

        window.addEventListener('organizationUpdated', handleOrgUpdate as EventListener);

        return () => {
            window.removeEventListener('organizationUpdated', handleOrgUpdate as EventListener);
        };
    }, []);

    const selectOrganization = useCallback((orgId: string) => {
        console.log('Switching to organization:', orgId);

        // Clear any cached data when switching organizations for security
        sessionStorage.removeItem('auditly_cached_employees');
        sessionStorage.removeItem('auditly_cached_submissions');
        sessionStorage.removeItem('auditly_cached_reports');

        setSelectedOrgId(orgId);
        localStorage.setItem('auditly_selected_org', orgId);

        // Dispatch event to notify other contexts about the org switch
        window.dispatchEvent(new CustomEvent('organizationChanged', {
            detail: { newOrgId: orgId }
        }));
    }, []);

    const createOrganization = useCallback(async (name: string): Promise<{ orgId: string; requiresSubscription?: boolean }> => {
        if (!user) throw new Error('User not authenticated');

        try {
            let newOrg: UserOrganization;
            let requiresSubscription = false;

            // Use secure API for organization creation
            const data = await secureApi.createOrganization(name);

            newOrg = {
                orgId: data.orgId,
                name: data.name,
                role: data.role,
                onboardingCompleted: data.onboardingCompleted,
                joinedAt: data.joinedAt
            };

            requiresSubscription = data.requiresSubscription || false;
            setOrganizations(prev => [...prev, newOrg]);

            return { orgId: newOrg.orgId, requiresSubscription };
        } catch (error) {
            console.error('Failed to create organization:', error);
            throw error;
        }
    }, [user]);

    const joinOrganization = useCallback(async (inviteCode: string): Promise<string> => {
        if (!user) throw new Error('User not authenticated');

        try {
            // Use secure API for joining organization
            const data = await secureApi.joinOrganization(inviteCode);

            const userOrg: UserOrganization = {
                orgId: data.orgId,
                name: data.name,
                role: data.role,
                onboardingCompleted: data.onboardingCompleted,
                joinedAt: data.joinedAt
            };

            setOrganizations(prev => [...prev, userOrg]);
            return data.orgId;
        } catch (error) {
            console.error('Failed to join organization:', error);
            throw error;
        }
    }, [user]);

    const refreshOrganizations = useCallback(async () => {
        setLoading(true);
        await loadOrganizations();
    }, [loadOrganizations]);

    const createCheckoutSession = useCallback(async (userEmail: string): Promise<{ sessionUrl: string; sessionId: string }> => {
        if (!user) throw new Error('User not authenticated');

        try {
            const data = await secureApi.createCheckoutSession(userEmail);
            return {
                sessionUrl: data.sessionUrl,
                sessionId: data.sessionId
            };
        } catch (error) {
            console.error('Failed to create checkout session:', error);
            throw error;
        }
    }, [user]);

    const getSubscriptionStatus = useCallback(async () => {
        try {
            const data = await secureApi.getSubscriptionStatus();
            return data;
        } catch (error) {
            console.error('Failed to get subscription status:', error);
            throw error;
        }
    }, []);

    // Memoize the context value to prevent unnecessary re-renders
    const contextValue = useMemo(() => ({
        organizations,
        selectedOrgId,
        loading,
        selectOrganization,
        createOrganization,
        joinOrganization,
        refreshOrganizations,
        createCheckoutSession,
        getSubscriptionStatus
    }), [
        organizations,
        selectedOrgId,
        loading,
        selectOrganization,
        createOrganization,
        joinOrganization,
        refreshOrganizations,
        createCheckoutSession,
        getSubscriptionStatus
    ]);

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

export const useUserOrganizations = () => {
    const context = useContext(UserOrganizationsContext);
    if (!context) {
        throw new Error('useUserOrganizations must be used within UserOrganizationsProvider');
    }
    return context;
};