import { SIM_PLAN_CODES, SIM_PLAN_LABELS, SIM_STATUS } from "./contract.js";
import type { SimStatus, SimFeaturesUpdateRequest } from "./schema.js";

export function canManageActiveSim(status: SimStatus): boolean {
  return status === SIM_STATUS.ACTIVE;
}

export function canReissueEsim(status: SimStatus): boolean {
  return canManageActiveSim(status);
}

export function canCancelSim(status: SimStatus): boolean {
  return canManageActiveSim(status);
}

export function canTopUpSim(status: SimStatus): boolean {
  return canManageActiveSim(status);
}

export function formatSimPlanShort(planCode?: string): string {
  if (!planCode) return "—";
  const normalized = planCode.trim();
  const matchPrimary = normalized.match(/(?:^|[_-])(\d+(?:\.\d+)?)\s*G(?:B)?\b/i);
  if (matchPrimary?.[1]) {
    return `${matchPrimary[1]}G`;
  }
  const matchFallback = normalized.match(/(\d+(?:\.\d+)?)\s*G(?:B)?\b/i);
  if (matchFallback?.[1]) {
    return `${matchFallback[1]}G`;
  }
  return normalized;
}

export type SimPlanOption = {
  code: (typeof SIM_PLAN_CODES)[number];
  label: string;
  shortLabel: string;
};

export const SIM_PLAN_OPTIONS: SimPlanOption[] = SIM_PLAN_CODES.map(code => ({
  code,
  label: SIM_PLAN_LABELS[code],
  shortLabel: formatSimPlanShort(code),
}));

export function getSimPlanLabel(planCode?: string): string {
  if (!planCode) return "Unknown plan";
  if (planCode in SIM_PLAN_LABELS) {
    return SIM_PLAN_LABELS[planCode as keyof typeof SIM_PLAN_LABELS];
  }
  return formatSimPlanShort(planCode);
}

export type SimFeatureToggleSnapshot = {
  voiceMailEnabled: boolean;
  callWaitingEnabled: boolean;
  internationalRoamingEnabled: boolean;
  networkType: "4G" | "5G";
};

export function buildSimFeaturesUpdatePayload(
  current: SimFeatureToggleSnapshot,
  next: SimFeatureToggleSnapshot
): SimFeaturesUpdateRequest | null {
  const payload: SimFeaturesUpdateRequest = {};

  if (current.voiceMailEnabled !== next.voiceMailEnabled) {
    payload.voiceMailEnabled = next.voiceMailEnabled;
  }

  if (current.callWaitingEnabled !== next.callWaitingEnabled) {
    payload.callWaitingEnabled = next.callWaitingEnabled;
  }

  if (current.internationalRoamingEnabled !== next.internationalRoamingEnabled) {
    payload.internationalRoamingEnabled = next.internationalRoamingEnabled;
  }

  if (current.networkType !== next.networkType) {
    payload.networkType = next.networkType;
  }

  return Object.keys(payload).length > 0 ? payload : null;
}

/**
 * Plan code mapping from product SKU/name to Freebit plan code
 * Maps common data tiers: 5GB, 10GB, 25GB, 50GB
 */
const PLAN_CODE_MAPPING: Record<string, string> = {
  "5": "PASI_5G",
  "10": "PASI_10G",
  "25": "PASI_25G",
  "50": "PASI_50G",
};

/**
 * Maps a product SKU or name to the corresponding Freebit plan code.
 *
 * Extracts the data tier (e.g., "50" from "SIM Data+Voice 50GB" or "sim-50gb")
 * and maps it to the appropriate PASI plan code.
 *
 * @param productSku - The product SKU (e.g., "sim-data-voice-50gb")
 * @param productName - The product name (e.g., "SIM Data+Voice 50GB")
 * @returns The Freebit plan code (e.g., "PASI_50G") or null if not mappable
 */
export function mapProductToFreebitPlanCode(
  productSku?: string,
  productName?: string
): string | null {
  // Try to extract data tier from SKU or name
  const source = productSku || productName || "";

  // Match patterns like "50GB", "50G", "50gb", or just "50" in context of GB
  const gbMatch = source.match(/(\d+)\s*G(?:B)?/i);
  if (gbMatch?.[1]) {
    const tier = gbMatch[1];
    const planCode = PLAN_CODE_MAPPING[tier];
    if (planCode) {
      return planCode;
    }
  }

  // Try matching standalone numbers in SKU patterns like "sim-50gb"
  const skuMatch = source.match(/[-_](\d+)[-_]?(?:gb|g)?/i);
  if (skuMatch?.[1]) {
    const tier = skuMatch[1];
    const planCode = PLAN_CODE_MAPPING[tier];
    if (planCode) {
      return planCode;
    }
  }

  return null;
}
