import React from "react";
import { View } from "react-native";
import { Text, Chip, Menu, Button } from "react-native-paper";
import API from "../API.js";
import i18n from "../i18nMessages.js";

const POLL_MS = 1800;
const CAPTION_META_KEYS = new Set(["sequence", "createdAt", "sourceLang", "original", "translations"]);

const toLangLabel = (lang = "") => {
    const normalized = String(lang || "").toLowerCase();
    if (!normalized || normalized === "original") return i18n.t("message.originalLanguage");
    if (normalized === "en") return i18n.t("message.languageEnglish");
    if (normalized === "es") return i18n.t("message.languageSpanish");
    if (normalized === "fr") return i18n.t("message.languageFrench");
    if (normalized === "da") return i18n.t("message.languageDanish");
    return normalized.toUpperCase();
};

const inferSourceLang = (item) => {
    if (!item || typeof item !== "object") return "";
    if (item.sourceLang) return String(item.sourceLang).toLowerCase();
    const original = typeof item.original === "string" ? item.original.trim() : "";
    if (!original) return "";
    const direct = Object.entries(item).find(([key, value]) => !CAPTION_META_KEYS.has(key) && typeof value === "string" && value.trim() === original);
    if (direct?.[0]) return String(direct[0]).toLowerCase();
    const nested = Object.entries(item.translations || {}).find(([_, value]) => typeof value === "string" && value.trim() === original);
    return nested?.[0] ? String(nested[0]).toLowerCase() : "";
};

const getTextForLang = (item, lang) => {
    if (!item || typeof item !== "object") return "";
    const normalizedLang = String(lang || "").toLowerCase();
    if (!normalizedLang || normalizedLang === "original") return item.original || "";
    const direct = typeof item[normalizedLang] === "string" ? item[normalizedLang].trim() : "";
    if (direct) return direct;
    const nested = typeof item?.translations?.[normalizedLang] === "string" ? item.translations[normalizedLang].trim() : "";
    if (nested) return nested;
    return "";
};

const CaptionRow = ({ item, selectedLang }) => {
    const translation = getTextForLang(item, selectedLang);
    const sourceLang = inferSourceLang(item);
    const displayTranslation = translation || item?.original || "";
    const isFallback = !translation && selectedLang && selectedLang !== "original" && selectedLang !== sourceLang;
    return (
        <View style={{ flex: 1, backgroundColor: "#fff", borderRadius: 14, padding: 18, borderWidth: 1, borderColor: "#e5e7eb" }}>
            <Text style={{ color: "#6b7280", fontSize: 11, marginBottom: 4 }}>
                {sourceLang ? `${i18n.t("message.originalLanguage")}: ${toLangLabel(sourceLang)}` : i18n.t("message.originalLanguage")}
            </Text>
            <Text style={{ fontSize: 28, fontWeight: "700", color: "#111827", lineHeight: 36 }}>
                {item?.original || ""}
            </Text>
            <Text style={{ color: "#6b7280", fontSize: 11, marginTop: 8, marginBottom: 4 }}>
                {i18n.t("message.selectedTranslation")}: {toLangLabel(selectedLang)}
            </Text>
            <Text style={{ fontSize: 24, color: "#1f2937", lineHeight: 32 }}>
                {displayTranslation}
            </Text>
            {isFallback ? (
                <Text style={{ fontSize: 11, color: "#6b7280", marginTop: 6 }}>
                    {i18n.t("message.translationFallback")}
                </Text>
            ) : <></>}
        </View>
    );
};

const LiveCaptions = () => {
    const [captions, setCaptions] = React.useState([]);
    const [availableLanguages, setAvailableLanguages] = React.useState([]);
    const [selectedLang, setSelectedLang] = React.useState((i18n?.locale || "en").toLowerCase());
    const [isLoading, setIsLoading] = React.useState(true);
    const [langMenuVisible, setLangMenuVisible] = React.useState(false);
    const latestSequenceRef = React.useRef(0);

    const refresh = React.useCallback(async (initial = false) => {
        const sinceSequence = initial ? undefined : latestSequenceRef.current;
        const response = await API.getLiveCaptions(sinceSequence, 50);
        const incoming = Array.isArray(response?.captions) ? response.captions : [];
        const languages = Array.isArray(response?.availableLanguages) ? response.availableLanguages : [];

        if (initial) {
            setCaptions(incoming);
        } else if (incoming.length > 0) {
            setCaptions((prev) => {
                const bySequence = new Map(prev.map((item) => [item.sequence, item]));
                incoming.forEach((item) => {
                    if (!item || !Number.isFinite(item.sequence)) return;
                    bySequence.set(item.sequence, item);
                });
                return Array.from(bySequence.values()).sort((a, b) => (a.sequence || 0) - (b.sequence || 0)).slice(-150);
            });
        }

        if (Number.isFinite(response?.latestSequence)) {
            latestSequenceRef.current = response.latestSequence;
        } else if (incoming.length) {
            const maxSeq = incoming.reduce((acc, item) => Math.max(acc, Number(item?.sequence) || 0), latestSequenceRef.current);
            latestSequenceRef.current = maxSeq;
        }

        setAvailableLanguages(languages);
        setIsLoading(false);
    }, []);

    React.useEffect(() => {
        refresh(true);
        const interval = setInterval(() => {
            refresh(false);
        }, POLL_MS);
        return () => clearInterval(interval);
    }, [refresh]);

    const latestCaption = captions.length ? captions[captions.length - 1] : null;

    const extractLangsFromCaption = React.useCallback((caption) => {
        const langs = new Set();
        if (!caption || typeof caption !== "object") return langs;
        if (caption.sourceLang) langs.add(String(caption.sourceLang).toLowerCase());

        const map = caption.translations;
        if (map && typeof map === "object" && !Array.isArray(map)) {
            Object.keys(map).forEach((lang) => {
                if (lang) langs.add(String(lang).toLowerCase());
            });
        }

        // Backward/alternate payload support: languages at top-level (en, fr, es, etc.)
        Object.entries(caption).forEach(([key, value]) => {
            if (CAPTION_META_KEYS.has(key)) return;
            if (typeof value !== "string" || !value.trim()) return;
            const lang = String(key || "").toLowerCase().trim();
            if (!lang) return;
            langs.add(lang);
        });

        return langs;
    }, []);

    const languageOptions = React.useMemo(() => {
        const unique = new Set(["original", ...availableLanguages]);
        captions.forEach((caption) => {
            const langs = extractLangsFromCaption(caption);
            langs.forEach((lang) => unique.add(lang));
        });
        return Array.from(unique).filter((lang) => !!lang && lang !== "sourceLang" && lang !== "translations");
    }, [availableLanguages, captions, extractLangsFromCaption]);

    React.useEffect(() => {
        if (languageOptions.includes(selectedLang)) return;
        const appLang = (i18n?.locale || "en").toLowerCase();
        if (languageOptions.includes(appLang)) {
            setSelectedLang(appLang);
            return;
        }
        if (languageOptions.includes("en")) {
            setSelectedLang("en");
            return;
        }
        if (languageOptions.length) setSelectedLang(languageOptions[0]);
    }, [languageOptions, selectedLang]);

    return (
        <View style={{ flex: 1, padding: 14 }}>
            <View style={{ flexDirection: "row", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
                <View>
                    <Text style={{ fontSize: 24, fontWeight: "700" }}>{i18n.t("message.liveCaptions")}</Text>
                    <Text style={{ color: "#6b7280" }}>{i18n.t("message.liveCaptionsSubtitle")}</Text>
                </View>
                <Chip icon="circle" compact style={{ backgroundColor: "#ecfdf5" }} textStyle={{ color: "#047857" }}>
                    {i18n.t("message.liveNow")}
                </Chip>
            </View>

            <View style={{ marginBottom: 12 }}>
                <Text style={{ marginBottom: 6 }}>{i18n.t("message.translationLanguage")}</Text>
                <Menu
                    visible={langMenuVisible}
                    onDismiss={() => setLangMenuVisible(false)}
                    anchor={
                        <Button mode="outlined" onPress={() => setLangMenuVisible(true)}>
                            {toLangLabel(selectedLang)}
                        </Button>
                    }
                >
                    {languageOptions.map((lang) => (
                        <Menu.Item
                            key={lang}
                            title={toLangLabel(lang)}
                            onPress={() => {
                                setSelectedLang(lang);
                                setLangMenuVisible(false);
                            }}
                        />
                    ))}
                </Menu>
            </View>

            {isLoading ? <Text>{i18n.t("message.loadingLiveCaptions")}</Text> : <></>}
            {!isLoading && !latestCaption ? <Text>{i18n.t("message.awaitingLiveCaptions")}</Text> : <></>}
            {!isLoading && latestCaption ? <CaptionRow item={latestCaption} selectedLang={selectedLang} /> : <></>}
        </View>
    );
};

export default LiveCaptions;
