/**
 * Claude model string parser utility.
 * Parses model identifiers into friendly display names and metadata.
 */

/** Fallback context window size when a more exact model-specific window is unavailable. */
export const DEFAULT_CONTEXT_WINDOW = 200_000;

/** Known model families with specific styling */
export type KnownModelFamily = 'sonnet' | 'opus' | 'haiku';

/** Model family can be a known family or any arbitrary string for new/unknown models */
export type ModelFamily = KnownModelFamily | (string & Record<never, never>);

export interface ModelInfo {
  /** Friendly name like "sonnet4.5" */
  name: string;
  /** Model family: sonnet, opus, haiku, or any other string for unknown families */
  family: ModelFamily;
  /** Major version like 4 or 3 */
  majorVersion: number;
  /** Minor version like 5 or 1 (null if not present) */
  minorVersion: number | null;
}

const KNOWN_FAMILIES: KnownModelFamily[] = ['sonnet', 'opus', 'haiku'];

/**
 * Parses a Claude model string into friendly display info.
 * Returns null if model string is invalid, synthetic, or empty.
 *
 * Supported formats:
 * - New format: claude-{family}-{major}-{minor}-{date} (e.g., "claude-sonnet-4-5-20250929")
 * - Old format: claude-{major}-{family}-{date} (e.g., "claude-3-opus-20240229")
 * - Old format with minor: claude-{major}-{minor}-{family}-{date} (e.g., "claude-3-5-sonnet-20241022")
 */
export function parseModelString(model: string | undefined): ModelInfo | null {
  // Handle null, undefined, empty, or synthetic models
  if (!model || model.trim() === '' || model === '<synthetic>') {
    return null;
  }

  const normalized = model.toLowerCase().trim();

  // Must start with "claude"
  if (!normalized.startsWith('claude')) {
    return null;
  }

  // Split into parts (e.g., ["claude", "sonnet", "4", "5", "20250929"])
  const parts = normalized.split('-');

  if (parts.length < 3) {
    return null;
  }

  // Detect model family - first check known families, then accept any non-numeric string
  let family: ModelFamily | null = null;
  let familyIndex = -1;

  // First pass: look for known families
  for (let i = 1; i < parts.length; i++) {
    const part = parts[i];
    if (KNOWN_FAMILIES.includes(part as KnownModelFamily)) {
      family = part as KnownModelFamily;
      familyIndex = i;
      break;
    }
  }

  // Second pass: if no known family found, look for any non-numeric, non-date string as family
  if (family === null) {
    for (let i = 1; i < parts.length; i++) {
      const part = parts[i];
      // Skip numeric parts and date-like parts (8 digits)
      if (!/^\d+$/.test(part) && !/^\d{8}$/.test(part) && part.length > 1) {
        family = part;
        familyIndex = i;
        break;
      }
    }
  }

  if (family === null || familyIndex === -1) {
    return null;
  }

  let majorVersion: number;
  let minorVersion: number | null = null;

  // Determine format based on family position
  if (familyIndex === 1) {
    // New format: claude-{family}-{major}-{minor}-{date}
    // e.g., claude-sonnet-4-5-20250929 -> ["claude", "sonnet", "4", "5", "20250929"]
    if (parts.length < 4) {
      return null;
    }

    majorVersion = parseInt(parts[2], 10);
    if (isNaN(majorVersion)) {
      return null;
    }

    // Check if there's a minor version (next part is a number and not a date)
    if (parts.length >= 4 && parts[3].length <= 2) {
      const potentialMinor = parseInt(parts[3], 10);
      if (!isNaN(potentialMinor)) {
        minorVersion = potentialMinor;
      }
    }
  } else {
    // Old format: claude-{major}[-{minor}]-{family}-{date}
    // e.g., claude-3-opus-20240229 -> ["claude", "3", "opus", "20240229"]
    // e.g., claude-3-5-sonnet-20241022 -> ["claude", "3", "5", "sonnet", "20241022"]

    majorVersion = parseInt(parts[1], 10);
    if (isNaN(majorVersion)) {
      return null;
    }

    // Check if there's a minor version between major and family
    if (familyIndex > 2) {
      const potentialMinor = parseInt(parts[2], 10);
      if (!isNaN(potentialMinor)) {
        minorVersion = potentialMinor;
      }
    }
  }

  // Build friendly name
  const versionString =
    minorVersion !== null ? `${majorVersion}.${minorVersion}` : `${majorVersion}`;
  const name = `${family}${versionString}`;

  return {
    name,
    family,
    majorVersion,
    minorVersion,
  };
}

/**
 * Gets the color class for a model family (for Tailwind).
 * Uses consistent neutral gray styling for a clean, Linear-like design.
 * All models use the same muted color for visual consistency.
 */
export function getModelColorClass(family: ModelFamily): string {
  // All families use consistent neutral gray for clean design
  switch (family) {
    case 'opus':
    case 'sonnet':
    case 'haiku':
      return 'text-zinc-400';
    default:
      return 'text-zinc-500';
  }
}
