// src/features/calls/ui/phone-input.jsx
//
// window.PhoneInput — a country-aware phone entry field used by the admin
// Add/Edit Student modals. It renders a country selector (defaults to the
// United States, +1) plus a national-number box that auto-formats with
// dashes as the admin types (US: 347-233-2748). Whatever the admin sees,
// the component emits a clean E.164 string ("+13472332748") up to the
// parent via onChange — so the existing required-field validation and the
// masked-call mirror (which both consume the E.164 form value) keep working
// untouched.
//
// Why a separate file: admin-students-modals.jsx is already at its LOC
// budget, and this is a reusable input primitive. Plain Babel script; it
// attaches PhoneInput to window and is referenced at render time, so its
// position in index.html relative to the admin modals doesn't matter.

// Country dial codes. US is first so it is the default and wins the +1
// longest-prefix tie when parsing an existing number. The handful Joe is
// most likely to use are pinned to the top; the rest are alphabetical.
// Type-ahead works because each option label starts with the country name.
const PHONE_COUNTRIES = [
  { c:'US', n:'United States',        d:'1'   },
  { c:'CA', n:'Canada',               d:'1'   },
  { c:'GB', n:'United Kingdom',       d:'44'  },
  { c:'LB', n:'Lebanon',              d:'961' },
  { c:'AE', n:'United Arab Emirates', d:'971' },
  { c:'SA', n:'Saudi Arabia',         d:'966' },
  // ── alphabetical ──
  { c:'AF', n:'Afghanistan',          d:'93'  },
  { c:'AL', n:'Albania',              d:'355' },
  { c:'DZ', n:'Algeria',              d:'213' },
  { c:'AR', n:'Argentina',            d:'54'  },
  { c:'AM', n:'Armenia',              d:'374' },
  { c:'AU', n:'Australia',            d:'61'  },
  { c:'AT', n:'Austria',              d:'43'  },
  { c:'AZ', n:'Azerbaijan',           d:'994' },
  { c:'BH', n:'Bahrain',              d:'973' },
  { c:'BD', n:'Bangladesh',           d:'880' },
  { c:'BE', n:'Belgium',              d:'32'  },
  { c:'BO', n:'Bolivia',              d:'591' },
  { c:'BR', n:'Brazil',               d:'55'  },
  { c:'BG', n:'Bulgaria',             d:'359' },
  { c:'KH', n:'Cambodia',             d:'855' },
  { c:'CM', n:'Cameroon',             d:'237' },
  { c:'CL', n:'Chile',                d:'56'  },
  { c:'CN', n:'China',                d:'86'  },
  { c:'CO', n:'Colombia',             d:'57'  },
  { c:'CR', n:'Costa Rica',           d:'506' },
  { c:'HR', n:'Croatia',              d:'385' },
  { c:'CY', n:'Cyprus',               d:'357' },
  { c:'CZ', n:'Czech Republic',       d:'420' },
  { c:'DK', n:'Denmark',              d:'45'  },
  { c:'EC', n:'Ecuador',              d:'593' },
  { c:'EG', n:'Egypt',                d:'20'  },
  { c:'SV', n:'El Salvador',          d:'503' },
  { c:'EE', n:'Estonia',              d:'372' },
  { c:'ET', n:'Ethiopia',             d:'251' },
  { c:'FI', n:'Finland',              d:'358' },
  { c:'FR', n:'France',               d:'33'  },
  { c:'GE', n:'Georgia',              d:'995' },
  { c:'DE', n:'Germany',              d:'49'  },
  { c:'GH', n:'Ghana',                d:'233' },
  { c:'GR', n:'Greece',               d:'30'  },
  { c:'GT', n:'Guatemala',            d:'502' },
  { c:'HN', n:'Honduras',             d:'504' },
  { c:'HK', n:'Hong Kong',            d:'852' },
  { c:'HU', n:'Hungary',              d:'36'  },
  { c:'IS', n:'Iceland',              d:'354' },
  { c:'IN', n:'India',                d:'91'  },
  { c:'ID', n:'Indonesia',            d:'62'  },
  { c:'IR', n:'Iran',                 d:'98'  },
  { c:'IQ', n:'Iraq',                 d:'964' },
  { c:'IE', n:'Ireland',              d:'353' },
  { c:'IL', n:'Israel',               d:'972' },
  { c:'IT', n:'Italy',                d:'39'  },
  { c:'JP', n:'Japan',                d:'81'  },
  { c:'JO', n:'Jordan',               d:'962' },
  { c:'KZ', n:'Kazakhstan',           d:'7'   },
  { c:'KE', n:'Kenya',                d:'254' },
  { c:'KW', n:'Kuwait',               d:'965' },
  { c:'LV', n:'Latvia',               d:'371' },
  { c:'LY', n:'Libya',                d:'218' },
  { c:'LT', n:'Lithuania',            d:'370' },
  { c:'LU', n:'Luxembourg',           d:'352' },
  { c:'MY', n:'Malaysia',             d:'60'  },
  { c:'MV', n:'Maldives',             d:'960' },
  { c:'MT', n:'Malta',                d:'356' },
  { c:'MX', n:'Mexico',               d:'52'  },
  { c:'MA', n:'Morocco',              d:'212' },
  { c:'NP', n:'Nepal',                d:'977' },
  { c:'NL', n:'Netherlands',          d:'31'  },
  { c:'NZ', n:'New Zealand',          d:'64'  },
  { c:'NG', n:'Nigeria',              d:'234' },
  { c:'NO', n:'Norway',               d:'47'  },
  { c:'OM', n:'Oman',                 d:'968' },
  { c:'PK', n:'Pakistan',             d:'92'  },
  { c:'PS', n:'Palestine',            d:'970' },
  { c:'PA', n:'Panama',               d:'507' },
  { c:'PY', n:'Paraguay',             d:'595' },
  { c:'PE', n:'Peru',                 d:'51'  },
  { c:'PH', n:'Philippines',          d:'63'  },
  { c:'PL', n:'Poland',               d:'48'  },
  { c:'PT', n:'Portugal',             d:'351' },
  { c:'QA', n:'Qatar',                d:'974' },
  { c:'RO', n:'Romania',              d:'40'  },
  { c:'RU', n:'Russia',               d:'7'   },
  { c:'SN', n:'Senegal',              d:'221' },
  { c:'RS', n:'Serbia',               d:'381' },
  { c:'SG', n:'Singapore',            d:'65'  },
  { c:'SK', n:'Slovakia',             d:'421' },
  { c:'SI', n:'Slovenia',             d:'386' },
  { c:'ZA', n:'South Africa',         d:'27'  },
  { c:'KR', n:'South Korea',          d:'82'  },
  { c:'ES', n:'Spain',                d:'34'  },
  { c:'LK', n:'Sri Lanka',            d:'94'  },
  { c:'SE', n:'Sweden',               d:'46'  },
  { c:'CH', n:'Switzerland',          d:'41'  },
  { c:'SY', n:'Syria',                d:'963' },
  { c:'TW', n:'Taiwan',               d:'886' },
  { c:'TZ', n:'Tanzania',             d:'255' },
  { c:'TH', n:'Thailand',             d:'66'  },
  { c:'TN', n:'Tunisia',              d:'216' },
  { c:'TR', n:'Turkey',               d:'90'  },
  { c:'UG', n:'Uganda',               d:'256' },
  { c:'UA', n:'Ukraine',              d:'380' },
  { c:'UY', n:'Uruguay',              d:'598' },
  { c:'UZ', n:'Uzbekistan',           d:'998' },
  { c:'VE', n:'Venezuela',            d:'58'  },
  { c:'VN', n:'Vietnam',              d:'84'  },
  { c:'YE', n:'Yemen',                d:'967' },
];

const _phoneDigits = (s) => String(s || '').replace(/\D/g, '');

// Group the national digits for display. NANP (+1) gets the familiar
// XXX-XXX-XXXX. Everything else gets a readable right-anchored grouping
// (last two groups of three, the remainder as a leading group). The exact
// grouping for non-US numbers is cosmetic — only the digits matter for the
// E.164 we emit.
const _formatNational = (input, dial) => {
  let digits = _phoneDigits(input);
  if (dial === '1') {
    digits = digits.slice(0, 10);
    const a = digits.slice(0, 3), b = digits.slice(3, 6), c = digits.slice(6, 10);
    return [a, b, c].filter(Boolean).join('-');
  }
  // E.164 allows up to 15 total digits incl. country code; cap national so a
  // fat-fingered paste can't overflow.
  digits = digits.slice(0, 15 - dial.length);
  if (digits.length <= 4) return digits;
  const tail = digits.slice(-6);
  const head = digits.slice(0, -6);
  const groups = [];
  if (head) groups.push(head);
  groups.push(tail.slice(0, 3));
  if (tail.length > 3) groups.push(tail.slice(3));
  return groups.join('-');
};

// Turn an existing value (E.164 like "+96170123456", or a legacy
// "(212) 555-0123") into { iso2, national-digits }. With a leading +, we
// match the longest dial-code prefix (US wins +1 ties). Without one, we
// assume the admin's default country (US) and treat it as a national number.
const _parseValue = (value) => {
  const raw = String(value || '').trim();
  const digits = _phoneDigits(raw);
  if (!digits) return { iso2: 'US', national: '' };
  if (raw.startsWith('+')) {
    let best = null;
    for (const co of PHONE_COUNTRIES) {
      if (digits.startsWith(co.d) && (!best || co.d.length > best.d.length)) best = co;
    }
    if (best) return { iso2: best.d === '1' ? 'US' : best.c, national: digits.slice(best.d.length) };
    return { iso2: 'US', national: digits };
  }
  return { iso2: 'US', national: digits };
};

const PhoneInput = ({ value, onChange, fieldStyle, autoFocus }) => {
  // Parse the incoming value ONCE on mount. After that this component owns
  // the editing state and is the sole writer of the parent's value, so there
  // is no controlled/uncontrolled feedback loop.
  const init = React.useMemo(() => _parseValue(value), []);
  const [iso2, setIso2] = React.useState(init.iso2);
  const [national, setNational] = React.useState(() => {
    const co = PHONE_COUNTRIES.find(x => x.c === init.iso2) || PHONE_COUNTRIES[0];
    return _formatNational(init.national, co.d);
  });

  const country = PHONE_COUNTRIES.find(x => x.c === iso2) || PHONE_COUNTRIES[0];

  const emit = (dial, displayOrDigits) => {
    const d = _phoneDigits(displayOrDigits);
    onChange(d ? ('+' + dial + d) : '');
  };

  // Normalize on mount: if we were handed a legacy value (or any value at
  // all), push the clean E.164 up immediately so saving without touching the
  // field still stores a proper number. Empty stays empty.
  React.useEffect(() => { emit(country.d, national); }, []); // eslint-disable-line

  const onCountry = (e) => {
    const co = PHONE_COUNTRIES.find(x => x.c === e.target.value) || PHONE_COUNTRIES[0];
    setIso2(co.c);
    const reformatted = _formatNational(national, co.d);
    setNational(reformatted);
    emit(co.d, reformatted);
  };

  const onNational = (e) => {
    const formatted = _formatNational(e.target.value, country.d);
    setNational(formatted);
    emit(country.d, formatted);
  };

  const selStyle = { ...(fieldStyle || {}), cursor: 'pointer' };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <select
        value={iso2}
        onChange={onCountry}
        aria-label="Country code"
        style={selStyle}
      >
        {PHONE_COUNTRIES.map(co => (
          <option key={co.c} value={co.c}>{co.n} (+{co.d})</option>
        ))}
      </select>
      <input
        type="tel"
        inputMode="tel"
        autoComplete="tel-national"
        autoFocus={autoFocus}
        value={national}
        onChange={onNational}
        placeholder={country.d === '1' ? '347-233-2748' : 'phone number'}
        aria-label="Phone number"
        style={fieldStyle}
      />
    </div>
  );
};

window.PhoneInput = PhoneInput;
