import { api, adminApi } from "./api.js";
import { handleAuthError, renderAllSuggestions, renderCounts, renderMySuggestions, renderPhasePill, renderPhaseTitles, renderResults, renderVotes, renderWelcome, setAuthUI, syncVoteScores, updatePhaseNav, openResultsRelockModal, openSuggestionsChangedModal } from "./ui.js";
import { state, clearUserState } from "./state.js";

export async function loadState() {
    const [me, stateData] = await Promise.all([api.me(), api.state()]);
    state.isAuthenticated = true;
    state.me = me;
    state.hasJoker = me.hasJoker ?? false;
    state.prevPhase = state.phase;
    state.phase = stateData.currentPhase;
    state.resultsOpen = stateData.resultsOpen;
    state.votesFinal = stateData.votesFinal ?? me?.votesFinal ?? false;
    state.counts = stateData;
    if (state.prevPhase !== state.phase && state.phase === "Vote") {
        state.votesRendered = false;
    }
    setAuthUI(true);
    renderWelcome();
    renderPhasePill();
    renderCounts();
}

export async function loadSuggestData() {
    if (state.phase !== "Suggest") return;
    state.mySuggestions = await api.mySuggestions();
    renderMySuggestions();
}

export async function loadRevealData() {
    if (state.phase === "Vote" || state.phase === "Results") {
        const prev = state.allSuggestions ?? [];
        const prevById = Object.fromEntries(prev.map((s) => [s.id, s]));
        const latest = await api.allSuggestions();
        const latestSig = signatureSuggestions(latest);
        const changed = latestSig !== state.allSuggestionsSig;
        if (changed && state.phase === "Vote" && state.allSuggestionsSig) {
            const added = latest
                .filter((s) => !prevById[s.id])
                .map((s) => s.name);
            const relinked = latest
                .filter((s) => {
                    const prevItem = prevById[s.id];
                    return (
                        prevItem &&
                        prevItem.parentSuggestionId !== s.parentSuggestionId
                    );
                })
                .map((s) => s.name);
            const names = [...added, ...relinked];
            openSuggestionsChangedModal(names);
        }
        state.allSuggestions = latest;
        state.allSuggestionsSig = latestSig;
        renderAllSuggestions();
        renderPhaseTitles();
        if (state.phase === "Vote" && changed) {
            state.votesRendered = false;
        }
    }
}

export async function loadVoteData() {
    if (state.phase !== "Vote") return;
    const votes = await api.myVotes();
    state.myVotes = votes;
    if (!state.votesRendered) {
        renderVotes();
        state.votesRendered = true;
    } else {
        syncVoteScores();
    }
    updatePhaseNav();
}

export async function loadResults() {
    if (state.phase !== "Results" || !state.resultsOpen) return;
    state.results = await api.results();
    renderResults();
}

export async function refreshPhaseData() {
    try {
        const prevPhase = state.phase;
        const prevResultsOpen = state.resultsOpen;
        await loadState();
        await Promise.all([loadSuggestData(), loadRevealData(), loadResults()]);
        if (state.phase === "Vote") {
            if (!state.votesRendered) await loadVoteData();
        } else {
            state.votesRendered = false;
            await loadVoteData();
        }
        if (state.me?.isAdmin) {
            state.adminVoteStatus = await adminApi.voteStatus();
        }
        if (
            prevPhase === "Results" &&
            state.phase === "Vote" &&
            prevResultsOpen &&
            !state.resultsOpen
        ) {
            openResultsRelockModal();
        }
        updatePhaseNav();
    } catch (err) {
        if (handleAuthError(err, clearUserState)) return;
        throw err;
    }
}

export function signatureSuggestions(list) {
    return JSON.stringify(
        list.map((s) => [
            s.id,
            s.name,
            s.genre,
            s.description,
            s.screenshotUrl,
            s.youtubeUrl,
            s.gameUrl,
            s.minPlayers,
            s.maxPlayers,
            s.parentSuggestionId,
            s.isOwner,
        ]),
    );
}
