import { isDeterministicPlaceholderAddress } from './deterministic-placeholder-address';

const HUB_COMPLIANT_WATCH_SYMBOLS = new Set(['cUSDC', 'cUSDT']);
const HUB_COMPLIANT_WATCH_CHAIN_IDS = new Set([138, 651940]);

export type WalletWatchAssetSpec = {
  symbol: string;
  addresses: Partial<Record<number, string>>;
  deploymentStatus?: string;
  deploymentVersion?: string;
  familySymbol?: string;
};

export function isStagedWalletWatchAssetSpec(spec: WalletWatchAssetSpec): boolean {
  const status = String(spec.deploymentStatus || '').trim().toLowerCase();
  const version = String(spec.deploymentVersion || '').trim().toLowerCase();
  return status === 'staged' || (version === 'v2' && Boolean(spec.familySymbol));
}

export function isWalletWatchAssetEligible(spec: WalletWatchAssetSpec, chainId: number): boolean {
  if (HUB_COMPLIANT_WATCH_SYMBOLS.has(spec.symbol) && !HUB_COMPLIANT_WATCH_CHAIN_IDS.has(chainId)) {
    return false;
  }
  if (isStagedWalletWatchAssetSpec(spec)) {
    return false;
  }
  const address = spec.addresses[chainId];
  if (address && isDeterministicPlaceholderAddress(address)) {
    return false;
  }
  return true;
}

export function isWalletWatchEligibleTokenAddress(address: string | undefined | null): boolean {
  if (!address) return false;
  return !isDeterministicPlaceholderAddress(address);
}

export type WalletWatchAssetEntryLike = {
  options: { symbol: string; address: string };
  metadata?: {
    deploymentStatus?: string;
    deploymentVersion?: string;
    catalogSymbol?: string;
  };
};

/** MetaMask keeps one custom token row per symbol — keep the live deployment when duplicates exist. */
export function dedupeWatchAssetEntriesBySymbol<T extends WalletWatchAssetEntryLike>(entries: T[]): T[] {
  const rank = (entry: T): number => {
    let score = 0;
    const status = String(entry.metadata?.deploymentStatus || '').toLowerCase();
    const version = String(entry.metadata?.deploymentVersion || '').toLowerCase();
    if (status === 'staged') score += 100;
    if (version === 'v2') score += 50;
    return score;
  };

  const bySymbol = new Map<string, T>();
  for (const entry of entries) {
    const key = entry.options.symbol.trim().toLowerCase();
    const existing = bySymbol.get(key);
    if (!existing || rank(entry) < rank(existing)) {
      bySymbol.set(key, entry);
    }
  }
  return Array.from(bySymbol.values());
}
