/**
 * Shared address-form bits used by both the storefront checkout
 * (Screens2.jsx) and the user-center address book (UserCenter.jsx),
 * plus a server-side geo lookup that the admin can also consume.
 *
 * Exports on `window`:
 *   YY_COUNTRIES   : ordered list of supported countries with division data.
 *   YY_GEO.find(code) : returns the country entry by 2-letter code or name.
 *   AddressFields  : <AddressFields value={form} onChange={set} lang errs touched onTouch /> component
 *   YY_ADDR.validate(form, lang)     : returns map { fieldName: errorMsg }
 *   YY_ADDR.empty()                  : returns a fresh empty form state
 *   YY_ADDR.fmt(addr, lang)          : human-readable single-line summary
 *
 * Country divisions carry a `type` so we can render them properly:
 *   - 'province'      regular province / 省 — has its own cities below
 *   - 'autonomous'    autonomous region / 自治区 (treated like province)
 *   - 'sar'           special admin region / 特别行政区 (Hong Kong / Macau / Taiwan)
 *                      → "city" concept doesn't apply; user fills district instead
 *   - 'municipality'  direct-administered municipality / 直辖市 (BJ/SH/TJ/CQ)
 *                      → city = same as province (auto / hidden); user fills district
 *   - 'state'         non-CN top-level (US / Australia)
 */

(function () {
  // ------------------------------------------------------------------ data
  const CN_DIVS = [
    // Direct-administered municipalities — no separate "city" level
    { code: '北京', en: 'Beijing',         type: 'municipality' },
    { code: '上海', en: 'Shanghai',        type: 'municipality' },
    { code: '天津', en: 'Tianjin',         type: 'municipality' },
    { code: '重庆', en: 'Chongqing',       type: 'municipality' },
    // Provinces
    { code: '河北', en: 'Hebei',           type: 'province' },
    { code: '山西', en: 'Shanxi',          type: 'province' },
    { code: '辽宁', en: 'Liaoning',        type: 'province' },
    { code: '吉林', en: 'Jilin',           type: 'province' },
    { code: '黑龙江', en: 'Heilongjiang',  type: 'province' },
    { code: '江苏', en: 'Jiangsu',         type: 'province' },
    { code: '浙江', en: 'Zhejiang',        type: 'province' },
    { code: '安徽', en: 'Anhui',           type: 'province' },
    { code: '福建', en: 'Fujian',          type: 'province' },
    { code: '江西', en: 'Jiangxi',         type: 'province' },
    { code: '山东', en: 'Shandong',        type: 'province' },
    { code: '河南', en: 'Henan',           type: 'province' },
    { code: '湖北', en: 'Hubei',           type: 'province' },
    { code: '湖南', en: 'Hunan',           type: 'province' },
    { code: '广东', en: 'Guangdong',       type: 'province' },
    { code: '海南', en: 'Hainan',          type: 'province' },
    { code: '四川', en: 'Sichuan',         type: 'province' },
    { code: '贵州', en: 'Guizhou',         type: 'province' },
    { code: '云南', en: 'Yunnan',          type: 'province' },
    { code: '陕西', en: 'Shaanxi',         type: 'province' },
    { code: '甘肃', en: 'Gansu',           type: 'province' },
    { code: '青海', en: 'Qinghai',         type: 'province' },
    // Autonomous regions — treated like provinces
    { code: '内蒙古', en: 'Inner Mongolia',type: 'autonomous' },
    { code: '广西', en: 'Guangxi',         type: 'autonomous' },
    { code: '西藏', en: 'Tibet',           type: 'autonomous' },
    { code: '宁夏', en: 'Ningxia',         type: 'autonomous' },
    { code: '新疆', en: 'Xinjiang',        type: 'autonomous' },
    // Special administrative regions (city-states)
    { code: '香港', en: 'Hong Kong',       type: 'sar' },
    { code: '澳门', en: 'Macau',           type: 'sar' },
    { code: '台湾', en: 'Taiwan',          type: 'sar' },
  ];

  const US_STATES = [
    'AL','AK','AZ','AR','CA','CO','CT','DE','FL','GA','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT','VT','VA','WA','WV','WI','WY','DC',
  ].map(code => ({ code, en: code, type: 'state' }));

  const COUNTRIES = [
    { code:'CN', zh:'中国',         en:'China',          dial:'+86',  postal: /^\d{6}$/,         divisions: CN_DIVS },
    { code:'US', zh:'美国',         en:'United States',  dial:'+1',   postal: /^\d{5}(-\d{4})?$/, divisions: US_STATES },
    { code:'JP', zh:'日本',         en:'Japan',          dial:'+81',  postal: /^\d{3}-?\d{4}$/ },
    { code:'KR', zh:'韩国',         en:'South Korea',    dial:'+82',  postal: /^\d{5}$/ },
    { code:'GB', zh:'英国',         en:'United Kingdom', dial:'+44',  postal: /^[A-Z]{1,2}\d[A-Z\d]?\s*\d[A-Z]{2}$/i },
    { code:'DE', zh:'德国',         en:'Germany',        dial:'+49',  postal: /^\d{5}$/ },
    { code:'FR', zh:'法国',         en:'France',         dial:'+33',  postal: /^\d{5}$/ },
    { code:'CA', zh:'加拿大',       en:'Canada',         dial:'+1',   postal: /^[A-Z]\d[A-Z]\s*\d[A-Z]\d$/i },
    { code:'AU', zh:'澳大利亚',     en:'Australia',      dial:'+61',  postal: /^\d{4}$/ },
    { code:'SG', zh:'新加坡',       en:'Singapore',      dial:'+65',  postal: /^\d{6}$/ },
    { code:'HK', zh:'中国香港',     en:'Hong Kong',      dial:'+852' },
    { code:'TW', zh:'中国台湾',     en:'Taiwan',         dial:'+886', postal: /^\d{3,5}$/ },
    { code:'MY', zh:'马来西亚',     en:'Malaysia',       dial:'+60',  postal: /^\d{5}$/ },
    { code:'TH', zh:'泰国',         en:'Thailand',       dial:'+66',  postal: /^\d{5}$/ },
  ];

  // Country lookup tolerant of code OR localized name OR English name.
  function findCountry(needle) {
    const v = String(needle || '').trim();
    if (!v) return null;
    return COUNTRIES.find(c =>
      c.code === v.toUpperCase() ||
      c.zh === v ||
      c.en.toLowerCase() === v.toLowerCase()
    ) || null;
  }
  function findDivision(country, name) {
    if (!country || !country.divisions || !name) return null;
    return country.divisions.find(d => d.code === name || d.en.toLowerCase() === String(name).toLowerCase()) || null;
  }

  // The selected division's type tells us how to label/require city + district.
  //   Regular province / state → city REQUIRED, district optional
  //   Municipality / SAR       → city HIDDEN  (auto = province), district REQUIRED
  function divisionShape(country, divName) {
    const d = findDivision(country, divName);
    const t = d?.type;
    if (t === 'municipality' || t === 'sar') {
      return { kind: 'municipality', cityRequired: false, cityVisible: false, districtRequired: true };
    }
    return { kind: 'province', cityRequired: true, cityVisible: true, districtRequired: false };
  }

  // Empty form. Uses CN as the default for Chinese visitors, US otherwise.
  function emptyForm(defaultCountry) {
    return {
      recipient_name: '', phone: '',
      country: defaultCountry || 'CN',
      province: '', city: '', district: '',
      street: '', postal_code: '',
      is_default: false,
    };
  }

  function fmt(a, lang) {
    if (!a) return '';
    const co = findCountry(a.country);
    const ctry = co ? (lang === 'zh' ? co.zh : co.en) : (a.country || '');
    const parts = [a.street, a.district, a.city, a.province, a.postal_code, ctry].filter(Boolean);
    return parts.join(', ');
  }

  // -------------------------------------------------------------- validate
  function validate(f, lang) {
    const e = {};
    const tx = (zh, en) => lang === 'zh' ? zh : en;
    const req = tx('必填', 'Required');

    if (!String(f.recipient_name || '').trim()) e.recipient_name = req;
    // phone optional — but if given, must look like a phone
    if (f.phone && !/^[+()\-\s\d]{6,20}$/.test(String(f.phone))) {
      e.phone = tx('电话格式不正确', 'Invalid phone');
    }

    const co = findCountry(f.country);
    if (!co) e.country = req;

    if (co?.divisions && co.divisions.length) {
      if (!f.province) e.province = req;
    }

    if (co) {
      const shape = divisionShape(co, f.province);
      if (shape.cityRequired && !String(f.city || '').trim()) e.city = req;
      if (shape.districtRequired && !String(f.district || '').trim()) e.district = req;
    } else {
      if (!String(f.city || '').trim()) e.city = req;
    }

    if (!String(f.street || '').trim()) e.street = req;

    if (co?.postal) {
      if (!String(f.postal_code || '').trim()) e.postal_code = req;
      else if (!co.postal.test(String(f.postal_code).trim())) e.postal_code = tx('邮编格式不正确', 'Invalid postal code');
    } // countries without a postal regex (e.g. HK) allow it to be blank

    return e;
  }

  window.YY_COUNTRIES = COUNTRIES;
  window.YY_GEO = { findCountry, findDivision, divisionShape };
  window.YY_ADDR = { validate, empty: emptyForm, fmt };
})();

// ---------------------------------------------------------------- component
// AddressFields is a Babel-transpiled JSX component shared across screens.
// Props:
//   value      : form object  { recipient_name, phone, country, province, city, district, street, postal_code }
//   onChange   : (field, value) => void
//   lang       : 'zh' | 'en' | …  (controls labels)
//   errs       : optional { field: msg } map (renders inline error chips)
//   touched    : optional { field: true } map (gates whether a chip shows)
//   onTouch    : optional (field) => void (called on blur)
//   showRecipient   : default true — toggle recipient_name + phone block (checkout uses email/phone elsewhere)
//   showDefault     : default false — render "set as default" checkbox
//   compact         : default false — denser modal styling
window.AddressFields = function AddressFields({
  value, onChange, lang, errs, touched, onTouch,
  showRecipient = true, showDefault = false, compact = false,
}) {
  const f      = value || {};
  const errors = errs || {};
  const touch  = touched || {};
  const L = lang || 'zh';
  const tx = (zh, en) => L === 'zh' ? zh : en;
  const country = window.YY_GEO.findCountry(f.country);
  const shape   = country ? window.YY_GEO.divisionShape(country, f.province) : { cityRequired: true, cityVisible: true, districtRequired: false };
  const reqStar = <span style={{ color:'#e3324f', marginLeft: 2 }}>*</span>;
  const errChip = (k) => (errors[k] && touch[k])
    ? <div style={{ color:'#e3324f', fontSize: 11, marginTop: 4 }}>{errors[k]}</div>
    : null;
  const errBorder = (k) => ({ border: errors[k] && touch[k] ? '1px solid #e3324f' : undefined });
  const blur = (k) => () => onTouch && onTouch(k);

  // Province label adapts to country.
  const provLabel = country
    ? (L === 'zh'
        ? (country.code === 'US' ? '州' : '省 / 直辖市')
        : (country.code === 'US' ? 'State' : 'Province / Region'))
    : (L === 'zh' ? '省 / 州' : 'Province / State');

  // City label: in CN, when a municipality is selected we auto-fill city
  // and hide it. Otherwise show normally.
  const cityLabel = L === 'zh' ? '城市' : 'City';
  const distLabel = country?.code === 'CN' ? (L === 'zh' ? '区 / 县' : 'District')
                    : (L === 'zh' ? '区 / 行政区' : 'District / Borough');

  const onCountry = (v) => {
    onChange('country', v);
    // Clear province/city/district on country switch so we don't mix maps.
    onChange('province', '');
    onChange('city', '');
    onChange('district', '');
  };
  const onProvince = (v) => {
    onChange('province', v);
    // For municipalities, mirror province → city automatically so backend
    // and admin display still see a valid city value.
    const sh = country ? window.YY_GEO.divisionShape(country, v) : null;
    if (sh && !sh.cityVisible) {
      onChange('city', v);  // auto-fill municipality as its own city
    } else if (sh && sh.cityVisible) {
      // user just switched from a municipality → clear the auto-set city
      const prevSh = country ? window.YY_GEO.divisionShape(country, f.province) : null;
      if (prevSh && !prevSh.cityVisible) onChange('city', '');
    }
  };

  return (
    <div style={{
      display: 'grid',
      gridTemplateColumns: compact ? '1fr 1fr' : 'repeat(2, minmax(0,1fr))',
      gap: compact ? 10 : 14,
    }}>
      {showRecipient && (
        <React.Fragment>
          <div className="form-field" data-yy-field="recipient_name">
            <label>{tx('收件人', 'Recipient')}{reqStar}</label>
            <input value={f.recipient_name || ''}
                   onChange={e => onChange('recipient_name', e.target.value)}
                   onBlur={blur('recipient_name')} style={errBorder('recipient_name')}/>
            {errChip('recipient_name')}
          </div>
          <div className="form-field" data-yy-field="phone">
            <label>{tx('手机号', 'Phone')}</label>
            <input type="tel" value={f.phone || ''}
                   placeholder={country ? country.dial + ' …' : ''}
                   onChange={e => onChange('phone', e.target.value)}
                   onBlur={blur('phone')} style={errBorder('phone')}/>
            {errChip('phone')}
          </div>
        </React.Fragment>
      )}

      <div className="form-field" data-yy-field="country">
        <label>{tx('国家 / 地区', 'Country / Region')}{reqStar}</label>
        <select value={f.country || ''}
                onChange={e => onCountry(e.target.value)}
                onBlur={blur('country')} style={errBorder('country')}>
          {window.YY_COUNTRIES.map(c => (
            <option key={c.code} value={c.code}>{L === 'zh' ? c.zh : c.en}</option>
          ))}
        </select>
        {errChip('country')}
      </div>

      <div className="form-field" data-yy-field="province">
        <label>{provLabel}{country?.divisions && reqStar}</label>
        {country?.divisions ? (
          <select value={f.province || ''}
                  onChange={e => onProvince(e.target.value)}
                  onBlur={blur('province')} style={errBorder('province')}>
            <option value="">{tx('请选择', 'Select…')}</option>
            {country.divisions.map(d => (
              <option key={d.code} value={d.code}>
                {L === 'zh' ? d.code : d.en}
                {d.type === 'municipality' ? (L === 'zh' ? ' · 直辖市' : ' (Municipality)')
                 : d.type === 'sar'         ? (L === 'zh' ? ' · 特别行政区' : ' (SAR)')
                 : d.type === 'autonomous'  ? (L === 'zh' ? ' · 自治区' : ' (Autonomous)')
                 : ''}
              </option>
            ))}
          </select>
        ) : (
          <input value={f.province || ''} onChange={e => onChange('province', e.target.value)}
                 onBlur={blur('province')} style={errBorder('province')}
                 placeholder={tx('选填', 'Optional')}/>
        )}
        {errChip('province')}
      </div>

      {/* City — hidden for municipalities/SAR (we auto-fill it = province). */}
      {shape.cityVisible && (
        <div className="form-field" data-yy-field="city">
          <label>{cityLabel}{shape.cityRequired && reqStar}</label>
          <input value={f.city || ''} onChange={e => onChange('city', e.target.value)}
                 onBlur={blur('city')} style={errBorder('city')}
                 placeholder={tx('如:杭州、广州', 'e.g. Hangzhou')}/>
          {errChip('city')}
        </div>
      )}

      {/* District — required for municipalities/SAR; optional otherwise. */}
      {(country?.code === 'CN' || country?.code === 'HK' || country?.code === 'JP' || shape.districtRequired) && (
        <div className="form-field" data-yy-field="district">
          <label>{distLabel}{shape.districtRequired && reqStar}</label>
          <input value={f.district || ''} onChange={e => onChange('district', e.target.value)}
                 onBlur={blur('district')} style={errBorder('district')}
                 placeholder={shape.districtRequired
                   ? tx('如:朝阳区、铜锣湾', 'e.g. Chaoyang, Causeway Bay')
                   : tx('选填', 'Optional')}/>
          {errChip('district')}
        </div>
      )}

      <div className="form-field full" data-yy-field="street" style={{ gridColumn: '1 / -1' }}>
        <label>{tx('详细地址', 'Street address')}{reqStar}</label>
        <input value={f.street || ''} onChange={e => onChange('street', e.target.value)}
               onBlur={blur('street')} style={errBorder('street')}
               placeholder={tx('街道、楼号、单元、门牌号', 'Street, building, apt #')}/>
        {errChip('street')}
      </div>

      <div className="form-field" data-yy-field="postal_code">
        <label>{tx('邮编', 'Postal code')}{country?.postal && reqStar}</label>
        <input value={f.postal_code || ''} onChange={e => onChange('postal_code', e.target.value)}
               onBlur={blur('postal_code')} style={errBorder('postal_code')}
               placeholder={country?.code === 'CN' ? '6 位'
                 : country?.code === 'US' ? '5 digits'
                 : (country && !country.postal ? tx('该地区无需邮编', 'Not required for this region') : '')}/>
        {errChip('postal_code')}
      </div>

      {showDefault && (
        <label style={{
          gridColumn: '1 / -1',
          display:'inline-flex', alignItems:'center', gap: 6,
          fontSize: 13, cursor:'pointer', marginTop: 2,
        }}>
          <input type="checkbox" checked={!!f.is_default}
                 onChange={e => onChange('is_default', e.target.checked)}/>
          {tx('设为默认地址', 'Set as default address')}
        </label>
      )}
    </div>
  );
};
