import { apiJSON } from "../../net/api";

// ICE servers used by every WebRTC RTCPeerConnection.
//
// Backend (/api/calls/credentials) returns either:
//   - a Cloudflare Realtime TURN bundle (TLS-capable, has username/credential), or
//   - a STUN-only fallback when CDROP_CF_TURN_* isn't configured.
//
// We fetch on login, cache the result, and refresh ahead of credential expiry.

interface ICEServer
{
    urls: string | string[];
    username?: string;
    credential?: string;
}

interface ICEResp
{
    iceServers: ICEServer[];
}

const FALLBACK: RTCIceServer[] = [
    { urls: "stun:stun.cloudflare.com:3478" },
];

let cached: RTCIceServer[] = FALLBACK;
let refreshTimer: number | null = null;

export function getICEServers(): RTCIceServer[]
{
    return cached;
}

// refreshICEServers fetches a fresh bundle from the backend. Call on login;
// it self-schedules a refresh ahead of credential TTL so long-lived sessions
// keep working. Falls back silently to STUN if the call fails.
export async function refreshICEServers(): Promise<void>
{
    try
    {
        const r = await apiJSON<ICEResp>("/api/calls/credentials");
        if (r?.iceServers && r.iceServers.length > 0)
        {
            cached = r.iceServers.map((s) => ({
                urls:       s.urls,
                username:   s.username,
                credential: s.credential,
            }));
        }
    }
    catch (e)
    {
        // eslint-disable-next-line no-console
        console.warn("iceServers fetch failed; using fallback", e);
        cached = FALLBACK;
    }

    if (refreshTimer !== null)
    {
        window.clearTimeout(refreshTimer);
    }
    // Refresh every ~22h to stay well clear of the 24h Cloudflare TTL.
    refreshTimer = window.setTimeout(() => { void refreshICEServers(); }, 22 * 60 * 60 * 1000);
}

export function stopICEServerRefresh(): void
{
    if (refreshTimer !== null)
    {
        window.clearTimeout(refreshTimer);
        refreshTimer = null;
    }
    cached = FALLBACK;
}
