import { normalizeLocale } from './api-errors';
import dialCodesJson from './phone-dial-codes.json';

type PhoneLocale = 'zh-CN' | 'ms-MY' | 'en-US';

export interface PhoneCountry {
  iso: string;
  dial: string;
  nameEn: string;
  nameLocal: string;
  flag: string;
  region: string;
}

/** 平台开放注册/短信的国家（ISO 3166-1 alpha-2），顺序即下拉展示顺序 */
export const ALLOWED_PHONE_ISO = ['MY', 'SG', 'IN', 'AU', 'TH', 'VN', 'BD', 'TW'] as const;

export type AllowedPhoneIso = (typeof ALLOWED_PHONE_ISO)[number];

const ALLOWED_SET = new Set<string>(ALLOWED_PHONE_ISO);

const ZH_LABELS: Record<AllowedPhoneIso, string> = {
  MY: '马来西亚',
  SG: '新加坡',
  IN: '印度',
  AU: '澳洲',
  TH: '泰国',
  VN: '越南',
  BD: '孟加拉国',
  TW: '台湾',
};

const allCountries = dialCodesJson as PhoneCountry[];

/** 开放国家列表（从 ITU 全量数据中筛选） */
export const PHONE_COUNTRIES: PhoneCountry[] = ALLOWED_PHONE_ISO.map((iso) => {
  const found = allCountries.find((c) => c.iso === iso);
  if (!found) {
    throw new Error(`Missing phone country data for ISO: ${iso}`);
  }
  return found;
});

const DIAL_SET = new Set(PHONE_COUNTRIES.map((c) => c.dial));

export function isSupportedPhoneDial(dial: string): boolean {
  return DIAL_SET.has(dial.replace(/\D/g, ''));
}

export function isAllowedPhoneIso(iso: string): boolean {
  return ALLOWED_SET.has(iso.toUpperCase());
}

export function defaultPhoneDialForLocale(localeInput?: string | null): string {
  return findPhoneCountryByIso(defaultPhoneIsoForLocale(localeInput))?.dial ?? '60';
}

export function defaultPhoneIsoForLocale(localeInput?: string | null): string {
  const locale = normalizeLocale(localeInput);
  if (locale === 'zh-CN') return 'TW';
  if (locale === 'ms-MY') return 'MY';
  return 'SG';
}

export function getPhoneDialFromIso(iso: string): string {
  return findPhoneCountryByIso(iso)?.dial ?? '';
}

export function getPhoneCountryLabel(country: PhoneCountry, localeInput?: string | null): string {
  const locale = normalizeLocale(localeInput);
  if (locale === 'zh-CN' && isAllowedPhoneIso(country.iso)) {
    return ZH_LABELS[country.iso as AllowedPhoneIso];
  }
  if (locale === 'zh-CN') {
    return country.nameLocal || country.nameEn;
  }
  return country.nameEn;
}

export function findPhoneCountryByDial(dial: string): PhoneCountry | undefined {
  const normalized = dial.replace(/\D/g, '');
  return PHONE_COUNTRIES.find((c) => c.dial === normalized);
}

export function findPhoneCountryByIso(iso: string): PhoneCountry | undefined {
  const upper = iso.toUpperCase();
  if (!isAllowedPhoneIso(upper)) return undefined;
  return PHONE_COUNTRIES.find((c) => c.iso === upper);
}

export function searchPhoneCountries(query: string, localeInput?: string | null): PhoneCountry[] {
  const q = query.trim().toLowerCase();
  if (!q) return PHONE_COUNTRIES;
  return PHONE_COUNTRIES.filter((country) => {
    const label = getPhoneCountryLabel(country, localeInput).toLowerCase();
    return (
      country.iso.toLowerCase().includes(q)
      || country.dial.includes(q.replace(/^\+/, ''))
      || country.nameEn.toLowerCase().includes(q)
      || label.includes(q)
      || `+${country.dial}`.includes(q)
    );
  });
}
