import { AxiosError } from "axios";
import type { TermixAlert } from "@/types";
import {
  authApi,
  handleApiError,
  markUserAuthenticated,
  type AuthResponse,
} from "@/main-axios";

// ALERTS
// ============================================================================

export async function setupTOTP(): Promise<{
  secret: string;
  qr_code: string;
}> {
  try {
    const response = await authApi.post("/users/totp/setup");
    return response.data;
  } catch (error) {
    handleApiError(error as AxiosError, "setup TOTP");
    throw error;
  }
}

export async function enableTOTP(
  totp_code: string,
): Promise<{ message: string; backup_codes: string[] }> {
  try {
    const response = await authApi.post("/users/totp/enable", { totp_code });
    return response.data;
  } catch (error) {
    handleApiError(error as AxiosError, "enable TOTP");
    throw error;
  }
}

export async function disableTOTP(
  password?: string,
  totp_code?: string,
): Promise<{ message: string }> {
  try {
    const response = await authApi.post("/users/totp/disable", {
      password,
      totp_code,
    });
    return response.data;
  } catch (error) {
    handleApiError(error as AxiosError, "disable TOTP");
    throw error;
  }
}

export async function verifyTOTPLogin(
  temp_token: string,
  totp_code: string,
  rememberMe: boolean = false,
): Promise<AuthResponse> {
  try {
    const response = await authApi.post("/users/totp/verify-login", {
      temp_token,
      totp_code,
      rememberMe,
    });

    if (response.data.success) {
      markUserAuthenticated();
    }

    return response.data;
  } catch (error) {
    handleApiError(error as AxiosError, "verify TOTP login");
    throw error;
  }
}

export async function generateBackupCodes(
  password?: string,
  totp_code?: string,
): Promise<{ backup_codes: string[] }> {
  try {
    const response = await authApi.post("/users/totp/backup-codes", {
      password,
      totp_code,
    });
    return response.data;
  } catch (error) {
    handleApiError(error as AxiosError, "generate backup codes");
    throw error;
  }
}

export async function getUserAlerts(): Promise<{
  alerts: TermixAlert[];
}> {
  try {
    const response = await authApi.get(`/alerts`);
    return response.data;
  } catch (error) {
    handleApiError(error, "fetch user alerts");
    throw error;
  }
}

export async function dismissAlert(
  alertId: string,
): Promise<Record<string, unknown>> {
  try {
    const response = await authApi.post("/alerts/dismiss", { alertId });
    return response.data;
  } catch (error) {
    handleApiError(error, "dismiss alert");
    throw error;
  }
}

// ============================================================================
// UPDATES & RELEASES
// ============================================================================

export interface ReleaseItem {
  id: number;
  title: string;
  description: string;
  link: string;
  pubDate: string;
  version: string;
  isPrerelease: boolean;
  isDraft: boolean;
  assets: Array<{
    name: string;
    size: number;
    download_count: number;
    download_url: string;
  }>;
}

export interface ReleasesRSSResponse {
  feed: { title: string; description: string; link: string; updated: string };
  items: ReleaseItem[];
  total_count: number;
  cached: boolean;
  cache_age?: number;
}

export async function getReleasesRSS(
  perPage: number = 100,
): Promise<ReleasesRSSResponse> {
  try {
    const response = await authApi.get(`/releases/rss?per_page=${perPage}`);
    return response.data;
  } catch (error) {
    handleApiError(error, "fetch releases RSS");
  }
}

export interface VersionInfo {
  status?: "up_to_date" | "requires_update" | "beta";
  /** Same value as remoteVersion; the endpoint sends both. */
  version?: string;
  localVersion?: string;
  remoteVersion?: string;
  latest_release?: {
    tag_name?: string;
    name?: string;
    published_at?: string;
    html_url?: string;
    body?: string;
  };
  cached?: boolean;
  cache_age?: number;
  // Callers reach for fields beyond the ones above -- SystemOverviewWidget
  // reads `updateAvailable`, which this endpoint does not in fact return --
  // so keep the index signature the previous `Record<string, unknown>` gave
  // them. Typing those reads out of existence is a separate change.
  [key: string]: unknown;
}

// Where the release page lives inside a version response. Both surfaces that
// render a version badge read it, and an empty string is what they treat as
// "no link to offer", so keep the shape in one place rather than repeating the
// optional chain at each call site.
export function releaseUrlFrom(info: VersionInfo | null | undefined): string {
  return info?.latest_release?.html_url ?? "";
}

export async function getVersionInfo(checkRemote = true): Promise<VersionInfo> {
  try {
    const response = await authApi.get(
      `/version${checkRemote ? "" : "?checkRemote=false"}`,
    );
    return response.data;
  } catch (error) {
    handleApiError(error, "fetch version info");
  }
}

// ============================================================================
// DATABASE HEALTH
// ============================================================================

export async function getDatabaseHealth(): Promise<Record<string, unknown>> {
  try {
    const response = await authApi.get("/health");
    return response.data;
  } catch (error) {
    handleApiError(error, "check database health");
  }
}

// ============================================================================
