import {
    createContext,
    useCallback,
    useContext,
    useEffect,
    useMemo,
    useState,
    type ReactNode,
} from 'react';
import api from '../services/api';

const STORAGE_KEY = 'app-locale';

export type AppLocale = 'es' | 'en';

export type TranslationNamespaces =
    | 'settings'
    | 'app'
    | 'dash'
    | 'accounts'
    | 'cloud'
    | 'cdr'
    | 'compliance'
    | 'compliance-detail'
    | 'transcriptions'
    | 'indicators'
    | 'training';

type Bundles = {
    settings: Record<string, string>;
    app: Record<string, string>;
    dash: Record<string, string>;
    accounts: Record<string, string>;
    cloud: Record<string, string>;
    cdr: Record<string, string>;
    compliance: Record<string, string>;
    'compliance-detail': Record<string, string>;
    transcriptions: Record<string, string>;
    indicators: Record<string, string>;
    training: Record<string, string>;
};

const emptyBundles: Bundles = {
    settings: {},
    app: {},
    dash: {},
    accounts: {},
    cloud: {},
    cdr: {},
    compliance: {},
    'compliance-detail': {},
    transcriptions: {},
    indicators: {},
    training: {},
};

function readStoredLocale(): AppLocale | null {
    if (typeof window === 'undefined') {
        return null;
    }
    const v = localStorage.getItem(STORAGE_KEY);
    if (v === 'es' || v === 'en') {
        return v;
    }
    return null;
}

export type LocaleContextValue = {
    locale: AppLocale;
    setLocale: (locale: AppLocale) => void;
    ready: boolean;
    t: (namespace: TranslationNamespaces, key: string) => string;
};

const LocaleContext = createContext<LocaleContextValue | null>(null);

type Props = {
    children: ReactNode;
};

export default function LocaleProvider({ children }: Props) {
    const [locale, setLocaleState] = useState<AppLocale>(
        () => readStoredLocale() ?? 'es',
    );
    const [bundles, setBundles] = useState<Bundles>(emptyBundles);
    const [ready, setReady] = useState(false);

    useEffect(() => {
        let cancelled = false;
        setReady(false);
        (async () => {
            try {
                const { data } = await api.get<{
                    settings: Record<string, string>;
                    app: Record<string, string>;
                    dash: Record<string, string>;
                    accounts: Record<string, string>;
                    cloud: Record<string, string>;
                    cdr: Record<string, string>;
                    transcriptions: Record<string, string>;
                    compliance: Record<string, string>;
                    'compliance-detail': Record<string, string>;
                    indicators: Record<string, string>;
                    training: Record<string, string>;
                }>('/api/translations', {
                    params: { locale },
                });
                if (cancelled) {
                    return;
                }
                setBundles({
                    settings: data.settings ?? {},
                    app: data.app ?? {},
                    dash: data.dash ?? {},
                    accounts: data.accounts ?? {},
                    cloud: data.cloud ?? {},
                    cdr: data.cdr ?? {},
                    compliance: data.compliance ?? {},
                    'compliance-detail': data['compliance-detail'] ?? {},
                    transcriptions: data.transcriptions ?? {},
                    indicators: data.indicators ?? {},
                    training: data.training ?? {},
                });
                localStorage.setItem(STORAGE_KEY, locale);
            } catch {
                if (!cancelled) {
                    setBundles(emptyBundles);
                }
            } finally {
                if (!cancelled) {
                    setReady(true);
                }
            }
        })();
        return () => {
            cancelled = true;
        };
    }, [locale]);

    const setLocale = useCallback((loc: AppLocale) => {
        setLocaleState(loc);
    }, []);

    const t = useCallback(
        (namespace: TranslationNamespaces, key: string) => {
            const map = bundles[namespace];
            return map?.[key] ?? key;
        },
        [bundles],
    );

    const value = useMemo<LocaleContextValue>(
        () => ({
            locale,
            setLocale,
            ready,
            t,
        }),
        [locale, setLocale, ready, t],
    );

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

export function useLocale(): LocaleContextValue {
    const ctx = useContext(LocaleContext);
    if (!ctx) {
        throw new Error('useLocale debe usarse dentro de LocaleProvider');
    }
    return ctx;
}
