import { getClaudeProfile, type ClaudeAccountUsage } from './claude-usage.js';
import type { StatusSnapshot } from './status-dashboard.js';

export type UsageRow = {
  name: string;
  h5pct: number;
  h5reset: string;
  d7pct: number;
  d7reset: string;
  /** When set, the renderer shows this text (e.g. "429") in place of the bars. */
  error?: string;
};

export function formatResetRemaining(value: string | number): string {
  if (value === '' || value == null) return '';
  try {
    const date =
      typeof value === 'number' ? new Date(value * 1000) : new Date(value);
    if (Number.isNaN(date.getTime())) return '';
    const diffMs = date.getTime() - Date.now();
    if (diffMs <= 0) return ' reset';
    const hours = Math.floor(diffMs / 3_600_000);
    const minutes = Math.floor((diffMs % 3_600_000) / 60_000);
    if (hours >= 24) {
      const days = Math.floor(hours / 24);
      const remH = hours % 24;
      return `${String(days).padStart(2)}d ${String(remH).padStart(2)}h`;
    }
    return `${String(hours).padStart(2)}h ${String(minutes).padStart(2)}m`;
  } catch {
    return String(value).padStart(6);
  }
}

export function mergeClaudeDashboardAccounts(
  liveAccounts: ClaudeAccountUsage[] | null | undefined,
  cachedAccounts: ClaudeAccountUsage[],
): ClaudeAccountUsage[] {
  if (!liveAccounts) return cachedAccounts;

  const cachedByIndex = new Map(
    cachedAccounts.map((account) => [account.index, account]),
  );

  return liveAccounts.map((account) => ({
    ...account,
    // On a 429 we deliberately do NOT fall back to the last cached value —
    // the dashboard surfaces a "429" indicator instead.
    usage: account.usageRateLimited
      ? null
      : account.usage || cachedByIndex.get(account.index)?.usage || null,
  }));
}

export function buildClaudeUsageRows(
  claudeAccounts: ClaudeAccountUsage[],
): UsageRow[] {
  const isMultiAccount = claudeAccounts.length > 1;

  return claudeAccounts.map((account) => {
    const usage = account.usage;
    const h5 = usage?.five_hour;
    const d7 = usage?.seven_day;
    const profile = getClaudeProfile(account.index);
    const planSuffix = profile ? ` ${profile.planType}` : '';
    const label = isMultiAccount
      ? `Claude${account.index + 1}${account.isActive ? '*' : ''}${account.isRateLimited ? '!' : ''}${planSuffix}`
      : `Claude${account.isActive ? '*' : ''}${account.isRateLimited ? '!' : ''}${planSuffix}`;

    return {
      name: label,
      h5pct: h5
        ? h5.utilization > 1
          ? Math.round(h5.utilization)
          : Math.round(h5.utilization * 100)
        : -1,
      h5reset: h5 ? formatResetRemaining(h5.resets_at) : '',
      d7pct: d7
        ? d7.utilization > 1
          ? Math.round(d7.utilization)
          : Math.round(d7.utilization * 100)
        : -1,
      d7reset: d7 ? formatResetRemaining(d7.resets_at) : '',
      error: account.usageRateLimited ? '429' : undefined,
    };
  });
}

/**
 * Extract Codex usage rows from a snapshot, applying staleness check.
 * Returns real rows if usageRowsFetchedAt is within maxAgeMs, otherwise a
 * single degraded row. Returns empty array if no usage data present.
 */
export function extractCodexUsageRows(
  snapshot: StatusSnapshot | undefined,
  maxAgeMs: number,
  now: number = Date.now(),
): UsageRow[] {
  if (!snapshot?.usageRows || snapshot.usageRows.length === 0) return [];

  const fetchedAt = snapshot.usageRowsFetchedAt
    ? new Date(snapshot.usageRowsFetchedAt).getTime()
    : 0;
  const usageAge = now - fetchedAt;
  if (usageAge <= maxAgeMs) {
    return [...snapshot.usageRows];
  }
  // Usage data is stale — return degraded indicator
  return [{ name: 'Codex', h5pct: -1, h5reset: '', d7pct: -1, d7reset: '' }];
}
