/**
 * Phone-number helpers built on libphonenumber-js.
 *
 * Uses the default `min` build (~110 KB gz). The `/mobile` build
 * rejects landlines and reserved-range numbers, which is wrong for
 * a marina CRM where clients commonly give office numbers.
 * The `/max` build adds carrier/geocoding we don't need.
 */

import {
  AsYouType,
  parsePhoneNumberFromString,
  isValidPhoneNumber as libIsValid,
  getCountryCallingCode,
  type CountryCode as LibCountryCode,
} from 'libphonenumber-js';

import type { CountryCode } from './countries';

export interface ParsedPhone {
  /** E.164 form, e.g. '+442079460958'. Null when the input isn't parseable. */
  e164: string | null;
  /** ISO alpha-2 of the country the number was parsed against. */
  country: CountryCode | null;
  /** Display-friendly national format, e.g. '020 7946 0958'. */
  national: string | null;
  /** Display-friendly international format, e.g. '+44 20 7946 0958'. */
  international: string | null;
  isValid: boolean;
}

const EMPTY: ParsedPhone = {
  e164: null,
  country: null,
  national: null,
  international: null,
  isValid: false,
};

/**
 * Parse a raw user-typed phone string into a normalized record.
 * `defaultCountry` provides context when the input lacks a +country prefix.
 */
export function parsePhone(raw: string, defaultCountry?: CountryCode): ParsedPhone {
  const trimmed = raw.trim();
  if (!trimmed) return EMPTY;
  try {
    const parsed = parsePhoneNumberFromString(trimmed, defaultCountry as LibCountryCode);
    if (!parsed) return EMPTY;
    return {
      e164: parsed.number,
      country: (parsed.country ?? null) as CountryCode | null,
      national: parsed.formatNational(),
      international: parsed.formatInternational(),
      isValid: parsed.isValid(),
    };
  } catch {
    return EMPTY;
  }
}

/**
 * Format the in-progress digits with `AsYouType` for live typing.
 * Returns the formatted string in the country's national style.
 */
export function formatAsYouType(raw: string, country: CountryCode): string {
  const formatter = new AsYouType(country as LibCountryCode);
  return formatter.input(raw);
}

/**
 * Strict validation for zod / form layer. Accepts E.164 only.
 */
export function isValidE164(value: string): boolean {
  return libIsValid(value);
}

export function callingCodeFor(country: CountryCode): string {
  return `+${getCountryCallingCode(country as LibCountryCode)}`;
}
