import * as SecureStore from "expo-secure-store";
import type { ClaudeUsageResponse } from "@/types/claude";
import type { CodexUsageResponse } from "@/types/codex";

const KEYS = {
  CODEX_AUTH: "codexbar_codex_auth",
  CLAUDE_SESSION_KEY: "codexbar_claude_session_key",
  CLAUDE_LAST_ACTIVE_ORG: "codexbar_claude_last_active_org",
  CODEX_USAGE_CACHE: "codexbar_codex_usage_cache",
  CLAUDE_USAGE_CACHE: "codexbar_claude_usage_cache",
  NOTIF_DAILY_ENABLED: "notifDailyEnabled",
  NOTIF_DAILY_HOUR: "notifDailyHour",
  NOTIF_DAILY_MINUTE: "notifDailyMinute",
  NOTIF_THRESHOLD_ENABLED: "notifThresholdEnabled",
  NOTIF_THRESHOLD_PCT: "notifThresholdPct",
  NOTIF_THRESHOLD_LAST_FIRED: "notifThresholdLastFired",
} as const;

export interface UsageCache<T> {
  data: T;
  lastFetchedAt: number;
}

async function loadJson<T>(key: string): Promise<T | null> {
  const raw = await SecureStore.getItemAsync(key);
  if (!raw) return null;

  try {
    return JSON.parse(raw) as T;
  } catch {
    await SecureStore.deleteItemAsync(key);
    return null;
  }
}

async function saveJson(key: string, value: unknown): Promise<void> {
  await SecureStore.setItemAsync(key, JSON.stringify(value));
}

export interface NotifSettings {
  dailyEnabled: boolean;
  dailyHour: number;
  dailyMinute: number;
  thresholdEnabled: boolean;
  /** Alert when remaining quota falls below this % (e.g. 20 = fire when < 20% left) */
  thresholdPct: number;
}

export async function loadNotifSettings(): Promise<NotifSettings> {
  const [de, dh, dm, te, tp] = await Promise.all([
    SecureStore.getItemAsync(KEYS.NOTIF_DAILY_ENABLED),
    SecureStore.getItemAsync(KEYS.NOTIF_DAILY_HOUR),
    SecureStore.getItemAsync(KEYS.NOTIF_DAILY_MINUTE),
    SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_ENABLED),
    SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_PCT),
  ]);
  return {
    dailyEnabled: de === "true",
    dailyHour: dh !== null ? parseInt(dh, 10) : 9,
    dailyMinute: dm !== null ? parseInt(dm, 10) : 0,
    thresholdEnabled: te === "true",
    thresholdPct: tp !== null ? parseInt(tp, 10) : 20,
  };
}

export async function saveNotifSettings(s: NotifSettings): Promise<void> {
  await Promise.all([
    SecureStore.setItemAsync(KEYS.NOTIF_DAILY_ENABLED, String(s.dailyEnabled)),
    SecureStore.setItemAsync(KEYS.NOTIF_DAILY_HOUR, String(s.dailyHour)),
    SecureStore.setItemAsync(KEYS.NOTIF_DAILY_MINUTE, String(s.dailyMinute)),
    SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_ENABLED, String(s.thresholdEnabled)),
    SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_PCT, String(s.thresholdPct)),
  ]);
}

export async function loadNotifThresholdLastFired(): Promise<string | null> {
  return SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_LAST_FIRED);
}

export async function saveNotifThresholdLastFired(date: string): Promise<void> {
  await SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_LAST_FIRED, date);
}

export async function saveCodexAuth(auth: {
  accessToken: string;
  accountId?: string;
}): Promise<void> {
  await saveJson(KEYS.CODEX_AUTH, auth);
}

export async function loadCodexAuth(): Promise<{
  accessToken: string;
  accountId?: string;
} | null> {
  return loadJson(KEYS.CODEX_AUTH);
}

export function loadCodexUsageCache(): Promise<UsageCache<CodexUsageResponse> | null> {
  return loadJson(KEYS.CODEX_USAGE_CACHE);
}

export function saveCodexUsageCache(
  cache: UsageCache<CodexUsageResponse>
): Promise<void> {
  return saveJson(KEYS.CODEX_USAGE_CACHE, cache);
}

export function clearCodexUsageCache(): Promise<void> {
  return SecureStore.deleteItemAsync(KEYS.CODEX_USAGE_CACHE);
}

export function loadClaudeUsageCache(): Promise<UsageCache<ClaudeUsageResponse> | null> {
  return loadJson(KEYS.CLAUDE_USAGE_CACHE);
}

export function saveClaudeUsageCache(
  cache: UsageCache<ClaudeUsageResponse>
): Promise<void> {
  return saveJson(KEYS.CLAUDE_USAGE_CACHE, cache);
}

export function clearClaudeUsageCache(): Promise<void> {
  return SecureStore.deleteItemAsync(KEYS.CLAUDE_USAGE_CACHE);
}

export async function saveClaudeSessionKey(key: string): Promise<void> {
  await SecureStore.setItemAsync(KEYS.CLAUDE_SESSION_KEY, key.trim());
}

export async function loadClaudeSessionKey(): Promise<string | null> {
  return SecureStore.getItemAsync(KEYS.CLAUDE_SESSION_KEY);
}

export async function saveClaudeLastActiveOrg(orgId: string): Promise<void> {
  await SecureStore.setItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG, orgId.trim());
}

export async function loadClaudeLastActiveOrg(): Promise<string | null> {
  return SecureStore.getItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG);
}

export async function clearClaudeLastActiveOrg(): Promise<void> {
  await SecureStore.deleteItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG);
}

export async function clearCodexAuth(): Promise<void> {
  await Promise.all([
    SecureStore.deleteItemAsync(KEYS.CODEX_AUTH),
    clearCodexUsageCache(),
  ]);
}

export async function clearClaudeSessionKey(): Promise<void> {
  await Promise.all([
    SecureStore.deleteItemAsync(KEYS.CLAUDE_SESSION_KEY),
    SecureStore.deleteItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG),
    clearClaudeUsageCache(),
  ]);
}
