/**
 * Tezos address validation utilities.
 * Validates tz1, tz2, tz3, tz4 (implicit) and KT1 (originated/contract) addresses.
 *
 * Format: Base58Check, 36 chars total (prefix 3-4 chars + 33 chars payload).
 * Regex provides structural validation; full checksum requires @taquito/utils.
 */

/** Originated/contract account prefix */
const CONTRACT_PREFIX = 'KT1';

/** Base58 character class for regex (excludes 0, O, I, l) */
const BASE58_CHARS = '[1-9A-HJ-NP-Za-km-z]';

/** Implicit address: tz1/tz2/tz3/tz4 + 33 base58 chars */
const IMPLICIT_REGEX = new RegExp(`^tz[1-4]${BASE58_CHARS}{33}$`);

/** Contract address: KT1 + 33 base58 chars */
const CONTRACT_REGEX = new RegExp(`^${CONTRACT_PREFIX}${BASE58_CHARS}{33}$`);

export type TezosAddressType = 'implicit' | 'contract';

export interface TezosAddressValidation {
  valid: boolean;
  address?: string;
  type?: TezosAddressType;
  error?: string;
}

/**
 * Validate a Tezos address (tz1, tz2, tz3, tz4, or KT1).
 * Uses regex for structural validation. For full base58check verification, use @taquito/utils.
 */
export function validateTezosAddress(address: string): TezosAddressValidation {
  if (!address || typeof address !== 'string') {
    return { valid: false, error: 'Address is required' };
  }

  const trimmed = address.trim();
  if (trimmed.length !== 36) {
    return {
      valid: false,
      error: `Invalid length: expected 36 chars, got ${trimmed.length}`,
    };
  }

  if (IMPLICIT_REGEX.test(trimmed)) {
    return {
      valid: true,
      address: trimmed,
      type: 'implicit',
    };
  }

  if (CONTRACT_REGEX.test(trimmed)) {
    return {
      valid: true,
      address: trimmed,
      type: 'contract',
    };
  }

  return {
    valid: false,
    error: 'Invalid format: must be tz1, tz2, tz3, tz4, or KT1 prefix with 33 base58 characters',
  };
}

/**
 * Check if string is a valid Tezos implicit (wallet) address.
 */
export function isImplicitAddress(address: string): boolean {
  const r = validateTezosAddress(address);
  return r.valid && r.type === 'implicit';
}

/**
 * Check if string is a valid Tezos contract (KT1) address.
 */
export function isContractAddress(address: string): boolean {
  const r = validateTezosAddress(address);
  return r.valid && r.type === 'contract';
}

/**
 * Check if string is any valid Tezos address (implicit or contract).
 */
export function isValidTezosAddress(address: string): boolean {
  return validateTezosAddress(address).valid;
}

/**
 * Validate destination for USDtz delivery - accepts implicit and contract addresses.
 */
export function validateUsdtzDestination(address: string): TezosAddressValidation {
  const result = validateTezosAddress(address);
  if (!result.valid) return result;
  return result;
}
