'use client';

import React, { createContext, useContext, useState, useCallback, ReactNode, useEffect } from 'react';
import en from '@/i18n/en.json';
import es from '@/i18n/es.json';
import ptBR from '@/i18n/pt-BR.json';

type Locale = 'en' | 'es' | 'pt-BR';

interface I18nContextType {
    locale: Locale;
    setLocale: (locale: Locale) => void;
    t: (key: string, params?: Record<string, string | number>) => string;
}

const dictionaries: Record<Locale, Record<string, unknown>> = {
    en: en as Record<string, unknown>,
    es: es as Record<string, unknown>,
    'pt-BR': ptBR as Record<string, unknown>,
};

const VALID_LOCALES: Locale[] = ['en', 'es', 'pt-BR'];

const I18nContext = createContext<I18nContextType | null>(null);

const localeStorageKey = 'locale';

const normalizeLocale = (language: string): Locale => {
    if (language.startsWith('pt')) return 'pt-BR';
    if (language.startsWith('es')) return 'es';
    return 'en';
};

const getInitialLocale = (): Locale => {
    if (typeof window === 'undefined') return 'pt-BR';
    try {
        const storedLocale = localStorage.getItem(localeStorageKey);
        if (storedLocale && VALID_LOCALES.includes(storedLocale as Locale)) {
            return storedLocale as Locale;
        }
    } catch {
        // localStorage might be blocked
    }
    if (typeof navigator !== 'undefined' && navigator.language) {
        return normalizeLocale(navigator.language);
    }
    return 'pt-BR';
};

function resolveKey(dict: Record<string, unknown>, key: string): string | undefined {
    const keys = key.split('.');
    let value: unknown = dict;

    for (const k of keys) {
        if (value && typeof value === 'object' && value !== null && k in value) {
            value = (value as Record<string, unknown>)[k];
        } else {
            return undefined;
        }
    }

    return typeof value === 'string' ? value : undefined;
}

export function I18nProvider({ children }: { children: ReactNode }) {
    const [locale, setLocaleState] = useState<Locale>('pt-BR');

    useEffect(() => {
        let initialLocale: Locale = 'pt-BR';
        try {
            const storedLocale = localStorage.getItem(localeStorageKey);
            if (storedLocale && VALID_LOCALES.includes(storedLocale as Locale)) {
                initialLocale = storedLocale as Locale;
            } else if (navigator.language) {
                initialLocale = normalizeLocale(navigator.language);
            }
        } catch {
            // localStorage might be blocked
        }
        setLocaleState(initialLocale);
    }, []);

    const setLocale = (newLocale: Locale) => {
        setLocaleState(newLocale);
    };

    const t = useCallback((key: string, params?: Record<string, string | number>) => {
        // Try current locale first, then fallback to pt-BR, then en
        const dict = dictionaries[locale] || dictionaries['pt-BR'];
        let result = resolveKey(dict, key);

        // Fallback chain: try pt-BR if not found, then en
        if (result === undefined && locale !== 'pt-BR') {
            result = resolveKey(dictionaries['pt-BR'], key);
        }
        if (result === undefined && locale !== 'en') {
            result = resolveKey(dictionaries['en'], key);
        }

        if (result === undefined) {
            return key;
        }

        if (params) {
            return Object.entries(params).reduce(
                (str, [paramKey, paramValue]) => str.replace(new RegExp(`\\{${paramKey}\\}`, 'g'), String(paramValue)),
                result
            );
        }

        return result;
    }, [locale]);

    useEffect(() => {
        if (typeof window === 'undefined') return;
        try {
            localStorage.setItem(localeStorageKey, locale);
        } catch {
            // localStorage might be blocked
        }
        document.documentElement.lang = locale;
    }, [locale]);

    return (
        <I18nContext.Provider value={{ locale, setLocale, t }}>
            {children}
        </I18nContext.Provider>
    );
}

export function useI18n() {
    const context = useContext(I18nContext);
    if (!context) {
        throw new Error('useI18n must be used within an I18nProvider');
    }
    return context;
}

export function useTranslation() {
    const { t, locale, setLocale } = useI18n();
    return { t, locale, setLocale };
}

export const locales: { code: Locale; name: string; flag: string }[] = [
    { code: 'en', name: 'English', flag: '🇺🇸' },
    { code: 'es', name: 'Español', flag: '🇪🇸' },
    { code: 'pt-BR', name: 'Português', flag: '🇧🇷' },
];
