// ---------------------------------------------------------------------------
// Update-check service
// Polls the Gitea releases API on startup and reports if a newer build exists.
// NOTE: requires the Gitea repo (or at least its releases) to be publicly
// accessible without authentication. On private repos the fetch will silently
// fail and no banner is shown.
// ---------------------------------------------------------------------------

const RELEASES_API =
  'https://git.sal.giize.com/api/v1/repos/mozempk/scopone/releases/latest';

const DISMISS_KEY = 'scopone_update_dismissed';

// Build number embedded by Vite from the VITE_APP_BUILD env var set in CI.
// Defaults to 0 (local / dev builds), which makes every real CI build newer.
export const CURRENT_BUILD = (() => {
  const raw = import.meta.env.VITE_APP_BUILD;
  const n = raw ? parseInt(raw, 10) : 0;
  return Number.isFinite(n) ? n : 0;
})();

export interface UpdateInfo {
  buildNumber: number;
  tagName: string;
  /** URL to the Gitea release page. */
  releaseUrl: string;
  /** Direct download URL for the unsigned release APK, if present in assets. */
  apkUrl: string | null;
}

/**
 * Fetches the latest Gitea release and returns an UpdateInfo if a build
 * newer than `currentBuild` is available.  Returns null on any error or
 * if the app is already up-to-date.
 */
export async function checkForUpdate(currentBuild: number): Promise<UpdateInfo | null> {
  const ac = new AbortController();
  const timer = setTimeout(() => ac.abort(), 5_000);
  try {
    const resp = await fetch(RELEASES_API, { signal: ac.signal });
    if (!resp.ok) return null;

    const data = await resp.json() as Record<string, unknown>;
    const tagName = typeof data.tag_name === 'string' ? data.tag_name : '';
    const match = tagName.match(/^build-(\d+)$/);
    if (!match) return null;

    const remoteBuild = parseInt(match[1], 10);
    if (remoteBuild <= currentBuild) return null;

    const assets = Array.isArray(data.assets)
      ? (data.assets as Array<Record<string, unknown>>)
      : [];
    const releaseAsset = assets.find(
      a => typeof a.name === 'string' && a.name === 'app-release-unsigned.apk',
    );

    return {
      buildNumber: remoteBuild,
      tagName,
      releaseUrl: typeof data.html_url === 'string' ? data.html_url : '',
      apkUrl: releaseAsset && typeof releaseAsset.browser_download_url === 'string'
        ? releaseAsset.browser_download_url
        : null,
    };
  } catch {
    return null;
  } finally {
    clearTimeout(timer);
  }
}

/** Returns true if the user already dismissed this build's update notification. */
export function isDismissed(buildNumber: number): boolean {
  try {
    return localStorage.getItem(DISMISS_KEY) === String(buildNumber);
  } catch {
    return false;
  }
}

/** Persists the dismiss decision so the banner won't reappear for this build. */
export function dismissUpdate(buildNumber: number): void {
  try {
    localStorage.setItem(DISMISS_KEY, String(buildNumber));
  } catch { /* localStorage unavailable — ignore */ }
}
