import { createContext, useContext, useEffect, useState, useRef, ReactNode, useMemo, useCallback } from 'react';
import { usePathname, useRouter } from 'next/navigation';
import { useQueryClient } from '@tanstack/react-query';
import { useSelector } from 'react-redux';
import type { AppStore } from '@/lib/store';
import Cookies from 'js-cookie';
import CustomFetch from '../APIRequest/AxiosInstance';
import { ChangeLanguageAPI } from '../APIRequest/Endpoints';

type Locale = 'en' | 'hk' | 'kr';
type Messages = Record<string, string>;

interface TranslationContextType {
    locale: Locale;
    translations: Messages;
    setLanguage: (next: Locale) => Promise<void>;
    t: (key: string, fallback?: string) => string;
    available: { code: Locale; label: string; dir: 'ltr' | 'rtl' }[];
}

const AVAILABLE: TranslationContextType['available'] = [
    { code: 'en', label: 'English', dir: 'ltr' },
    { code: 'hk', label: '中文', dir: 'ltr' },
    { code: 'kr', label: '한국어', dir: 'ltr' },
];

const TranslationContext = createContext<TranslationContextType | null>(null);

export const TranslationProvider = ({ children }: { children: ReactNode }) => {
    const route = useRouter();
    const pathname = usePathname();
    const queryClient = useQueryClient();
    const isInitialMount = useRef(true);
    const userDetails: any = useSelector((state: AppStore) => state.userDetailSlice?.userDetails);

    // Check if user is admin
    const isAdmin = () => {
        return (userDetails?.role === 'admin' && !pathname?.includes('/admin/category') && !pathname?.includes('/admin/keywords'));
    };

    const [locale, setLocale] = useState<Locale>(() => {
        // Check user_info cookie for admin role on initial load
        try {
            const userInfo = Cookies.get('user_info');
            if (userInfo) {
                const parsed = JSON.parse(userInfo);
                if (parsed?.role === 'admin') {
                    Cookies.set('NEXT_LOCALE', 'en', { expires: 365, path: '/' });
                    return 'en';
                }
            }
        } catch (e) {
            // Ignore parse errors
        }

        const fromCookie = Cookies.get('NEXT_LOCALE') as Locale | undefined;
        return fromCookie ?? 'en';
    });
    const [translations, setTranslations] = useState<Messages>({});

    useEffect(() => {
        const meta = AVAILABLE.find(l => l.code === locale);
        document.documentElement.lang = locale;
        document.documentElement.dir = meta?.dir ?? 'ltr';

        import(`./../../../public/locales/${locale}/common.json`)
            .then(m => setTranslations(m.default ?? {}))
            .catch(() => setTranslations({}));
    }, [locale]);

    // Ensure admin always uses 'en' locale
    useEffect(() => {
        if (isAdmin() && locale !== 'en') {
            setLocale('en');
            Cookies.set('NEXT_LOCALE', 'en', { expires: 365, path: '/' });
        }
    }, [locale, userDetails, pathname]);

    useEffect(() => {
        // Only check cookie when userDetails is available
        if (!userDetails) return;

        const saved = Cookies.get('NEXT_LOCALE') as Locale | undefined;
        if (saved && saved !== locale) {
            setLocale(saved);
        }
    }, [userDetails, locale]);

    const refreshQueriesForLocale = useCallback(async () => {
        const authToken = Cookies.get('aat') || Cookies.get('bat') || Cookies.get('iat') || Cookies.get('verifyUAT');
        // Logged out (e.g. login page): don't refetch cached dashboard/campaign queries → 401s
        if (!authToken) return;

        await queryClient.cancelQueries();
        // Only remounted/active queries — avoid waking inactive queries from a previous session
        await queryClient.invalidateQueries({ refetchType: 'active' });
    }, [queryClient]);

    // Refetch all queries when locale changes (skip initial mount)
    useEffect(() => {
        if (isInitialMount.current) {
            isInitialMount.current = false;
            return;
        }
        void refreshQueriesForLocale();
    }, [locale, refreshQueriesForLocale]);

    const setLanguage = async (next: Locale) => {
        if (next === locale) return;

        Cookies.set('NEXT_LOCALE', next, { expires: 365, path: '/' });

        const authToken = Cookies.get('aat') || Cookies.get('bat') || Cookies.get('iat') || Cookies.get('verifyUAT');
        if (authToken) {
            try {
                await CustomFetch(
                    {
                        url: ChangeLanguageAPI,
                        data: { language_code: next },
                        method: 'post'
                    },
                    null,
                    false,
                    true
                );
            } catch (error) {
                console.error('Failed to update language preference:', error);
            }
        }

        setLocale(next);
    };

    const t = useMemo(
        () => (key: string, fallback?: string) => translations[key] ?? fallback ?? key,
        [translations]
    );

    const value: TranslationContextType = { locale, translations, setLanguage, t, available: AVAILABLE };

    return <TranslationContext.Provider value={value}>{children}</TranslationContext.Provider>;
};

export function useTranslation() {
    const ctx = useContext(TranslationContext);
    if (!ctx) throw new Error('useTranslation must be used within TranslationProvider');
    return ctx;
}

