import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { useTranslation } from 'react-i18next';

export interface UserPreferences {
    theme: 'light' | 'dark' | 'system';
    language: 'en' | 'es';
    fontSize: 'normal' | 'large' | 'xlarge';
    highContrast: boolean;
    reducedMotion: boolean;
    soundEnabled: boolean;
    notificationsEnabled: boolean;
    compactMode: boolean;
}

const defaultPreferences: UserPreferences = {
    theme: 'system',
    language: 'en',
    fontSize: 'normal',
    highContrast: false,
    reducedMotion: false,
    soundEnabled: true,
    notificationsEnabled: true,
    compactMode: false,
};

interface PreferencesContextType {
    preferences: UserPreferences;
    setPreference: <K extends keyof UserPreferences>(key: K, value: UserPreferences[K]) => void;
    resetPreferences: () => void;
    isLoading: boolean;
}

const PreferencesContext = createContext<PreferencesContextType | null>(null);

const STORAGE_KEY = 'user-preferences';

export function PreferencesProvider({ children }: { children: React.ReactNode }) {
    const { i18n } = useTranslation();
    const [preferences, setPreferences] = useState<UserPreferences>(defaultPreferences);
    const [isLoading, setIsLoading] = useState(true);

    // Load preferences from localStorage on mount
    useEffect(() => {
        try {
            const stored = localStorage.getItem(STORAGE_KEY);
            if (stored) {
                const parsed = JSON.parse(stored);
                setPreferences({ ...defaultPreferences, ...parsed });
            }
        } catch (e) {
            console.error('Failed to load preferences:', e);
        }
        setIsLoading(false);
    }, []);

    // Apply theme preference
    useEffect(() => {
        const html = document.documentElement;

        if (preferences.theme === 'system') {
            const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
            html.classList.toggle('dark', prefersDark);
        } else {
            html.classList.toggle('dark', preferences.theme === 'dark');
        }
    }, [preferences.theme]);

    // Apply language preference
    useEffect(() => {
        i18n.changeLanguage(preferences.language);
    }, [preferences.language, i18n]);

    // Apply font size preference
    useEffect(() => {
        const html = document.documentElement;
        html.classList.remove('font-normal', 'font-large', 'font-xlarge');

        switch (preferences.fontSize) {
            case 'large':
                html.style.fontSize = '112.5%'; // 18px
                break;
            case 'xlarge':
                html.style.fontSize = '125%'; // 20px
                break;
            default:
                html.style.fontSize = '100%'; // 16px
        }
    }, [preferences.fontSize]);

    // Apply high contrast preference
    useEffect(() => {
        document.documentElement.classList.toggle('high-contrast', preferences.highContrast);
    }, [preferences.highContrast]);

    // Apply reduced motion preference
    useEffect(() => {
        document.documentElement.classList.toggle('reduce-motion', preferences.reducedMotion);
    }, [preferences.reducedMotion]);

    // Apply compact mode
    useEffect(() => {
        document.documentElement.classList.toggle('compact', preferences.compactMode);
    }, [preferences.compactMode]);

    const setPreference = useCallback(<K extends keyof UserPreferences>(
        key: K,
        value: UserPreferences[K]
    ) => {
        setPreferences(prev => {
            const updated = { ...prev, [key]: value };
            localStorage.setItem(STORAGE_KEY, JSON.stringify(updated));
            return updated;
        });
    }, []);

    const resetPreferences = useCallback(() => {
        localStorage.removeItem(STORAGE_KEY);
        setPreferences(defaultPreferences);
    }, []);

    return (
        <PreferencesContext.Provider value={{ preferences, setPreference, resetPreferences, isLoading }}>
            {children}
        </PreferencesContext.Provider>
    );
}

export function usePreferences(): PreferencesContextType {
    const context = useContext(PreferencesContext);
    if (!context) {
        throw new Error('usePreferences must be used within PreferencesProvider');
    }
    return context;
}
