import type { ReactNode } from 'react';
import { createContext, useCallback, useContext, useEffect, useState } from 'react';

export type Role = 'executive' | 'admin' | 'cc-agent';

type User = {
    id?: string;
    name: string;
    initials: string;
    role: Role;
    email: string;
    avatarUrl?: string;
    platformRoles?: string[];
};

type AuthContextType = {
    user: User;
    isAdmin: boolean;
    isCCAgent: boolean;
    isAuthenticated: boolean;
    loading: boolean;
    loginWithUser: (userData: User) => void;
    login: () => void;
    logout: () => void;
    setRole: (role: Role) => void;
};

const DEFAULT_USER: User = {
    name: '',
    initials: '',
    role: 'executive',
    email: '',
};

const getInitials = (firstName: string, lastName: string): string =>
    `${firstName[0] ?? ''}${lastName[0] ?? ''}`.toUpperCase();

const STORAGE_KEY = 'helix_user';

const loadPersistedUser = (): User | null => {
    try {
        const token = localStorage.getItem('helix_access_token');
        const stored = localStorage.getItem(STORAGE_KEY);
        if (token && stored) {
            return JSON.parse(stored) as User;
        }
    } catch {
        // corrupt data
    }
    return null;
};

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export const useAuth = (): AuthContextType => {
    const context = useContext(AuthContext);
    if (context === undefined) {
        throw new Error('useAuth must be used within an AuthProvider');
    }
    return context;
};

interface AuthProviderProps {
    children: ReactNode;
}

export const AuthProvider = ({ children }: AuthProviderProps) => {
    const persisted = loadPersistedUser();
    const [user, setUser] = useState<User>(persisted ?? DEFAULT_USER);
    const [isAuthenticated, setIsAuthenticated] = useState(!!persisted);
    const [loading, setLoading] = useState(!persisted && !!localStorage.getItem('helix_access_token'));

    // If we have a token but no persisted user, try to restore session
    useEffect(() => {
        if (!isAuthenticated && localStorage.getItem('helix_access_token') && !persisted) {
            // Token exists but no user data — could re-fetch profile here
            // For now, just clear stale token
            localStorage.removeItem('helix_access_token');
            localStorage.removeItem('helix_refresh_token');
            localStorage.removeItem(STORAGE_KEY);
            setLoading(false);
        }
    }, [isAuthenticated, persisted]);

    const isAdmin = user.role === 'admin';
    const isCCAgent = user.role === 'cc-agent';

    const loginWithUser = useCallback((userData: User) => {
        setUser(userData);
        setIsAuthenticated(true);
        localStorage.setItem(STORAGE_KEY, JSON.stringify(userData));
    }, []);

    const login = useCallback(() => {
        setIsAuthenticated(true);
    }, []);

    const logout = useCallback(async () => {
        // Block logout during active call
        const { isOutboundPending, disconnectSip } = await import('@/state/sip-manager');
        const activeUcid = localStorage.getItem('helix_active_ucid');
        if (isOutboundPending() || activeUcid) {
            const confirmed = window.confirm(
                'You have an active call. Logging out will disconnect the call. Are you sure?',
            );
            if (!confirmed) return;
        }

        // Disconnect SIP before logout
        try {
            disconnectSip(true);
        } catch {}

        // Notify sidecar to unlock Redis session + Ozonetel logout — await before clearing tokens
        const token = localStorage.getItem('helix_access_token');
        if (token) {
            const apiUrl = import.meta.env.VITE_API_URL ?? 'http://localhost:4100';
            try {
                await fetch(`${apiUrl}/auth/logout`, {
                    method: 'POST',
                    headers: { Authorization: `Bearer ${token}` },
                    signal: AbortSignal.timeout(5000),
                });
            } catch (err) {
                console.warn('Logout cleanup failed:', err);
            }
        }

        setUser(DEFAULT_USER);
        setIsAuthenticated(false);
        localStorage.removeItem('helix_access_token');
        localStorage.removeItem('helix_refresh_token');
        localStorage.removeItem('helix_agent_config');
        localStorage.removeItem(STORAGE_KEY);
    }, []);

    const setRole = useCallback((role: Role) => {
        setUser(prev => {
            const updated = { ...prev, role };
            localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
            return updated;
        });
    }, []);

    return (
        <AuthContext.Provider value={{ user, isAdmin, isCCAgent, isAuthenticated, loading, loginWithUser, login, logout, setRole }}>
            {children}
        </AuthContext.Provider>
    );
};

export { getInitials };
