// i18n 모듈 — 로케일 감지, t() 함수, 포맷터.
// 로케일 우선순위:
//   1. URL ?lang=xx        (링크 공유로 명시 지정)
//   2. localStorage        (스위처로 선택한 사용자 명시 선호)
//   3. navigator 언어 감지 (디바이스 언어에 따른 자동)
//   4. 'ko' 폴백           (위 모두 실패 시)
// 지원: 'ko' (한국어), 'en' (영어), 'zh-TW' (繁體中文 / 타이완)

(function () {
  const SUPPORTED = ['ko', 'en', 'zh-TW'];
  const DEFAULT_LOCALE = 'ko';
  const STORAGE_KEY = 'modi-calc-locale';

  // navigator의 언어 목록을 우리 SUPPORTED 로케일로 매핑.
  // - ko*           → ko
  // - zh-TW/HK/Hant → zh-TW (繁體)
  // - zh-CN/Hans/zh → en (簡體는 미지원 → 국제 폴백)
  // - en*           → en
  // - 기타          → en (의료관광 기본)
  // - 정보 없음     → null (호출 측에서 DEFAULT_LOCALE 처리)
  function detectFromNavigator() {
    if (typeof navigator === 'undefined') return null;
    const rawList = (navigator.languages && navigator.languages.length)
      ? navigator.languages
      : (navigator.language ? [navigator.language] : []);
    if (rawList.length === 0) return null;
    const langs = rawList.map(l => (l || '').toLowerCase());
    for (const l of langs) {
      if (!l) continue;
      if (l.startsWith('ko')) return 'ko';
      if (l === 'zh-tw' || l === 'zh-hk' || l.startsWith('zh-hant')) return 'zh-TW';
      if (l === 'zh-cn' || l.startsWith('zh-hans') || l === 'zh') return 'en';
      if (l.startsWith('en')) return 'en';
    }
    // 한·중·영 어디에도 매치 안 되는 경우 (일본어, 베트남어 등) → 영어 폴백
    return 'en';
  }

  function detectLocale() {
    try {
      const params = new URLSearchParams(window.location.search);
      const fromUrl = params.get('lang');
      if (fromUrl && SUPPORTED.includes(fromUrl)) return fromUrl;
    } catch (e) {}
    try {
      const fromStorage = localStorage.getItem(STORAGE_KEY);
      if (fromStorage && SUPPORTED.includes(fromStorage)) return fromStorage;
    } catch (e) {}
    // navigator 감지 — 결과는 localStorage에 저장하지 않음(디바이스 언어 변경 시 재감지).
    try {
      const detected = detectFromNavigator();
      if (detected && SUPPORTED.includes(detected)) return detected;
    } catch (e) {}
    return DEFAULT_LOCALE;
  }

  window.currentLocale = detectLocale();
  window.SUPPORTED_LOCALES = SUPPORTED;

  function getDict(locale) {
    if (locale === 'en') return window.LOCALE_EN || window.LOCALE_KO || {};
    if (locale === 'zh-TW') return window.LOCALE_ZH_TW || window.LOCALE_KO || {};
    return window.LOCALE_KO || {};
  }

  // 점 표기 키 해석. 누락 시 키 그대로 반환(개발 중 누락 감지용).
  function resolveKey(dict, key) {
    const parts = key.split('.');
    let cur = dict;
    for (const p of parts) {
      if (cur == null) return null;
      cur = cur[p];
    }
    return cur;
  }

  function interpolate(str, params) {
    if (!params || typeof str !== 'string') return str;
    return str.replace(/\{(\w+)\}/g, (_, k) => (params[k] != null ? params[k] : '{' + k + '}'));
  }

  window.t = function t(key, params) {
    const locale = window.currentLocale || DEFAULT_LOCALE;
    let val = resolveKey(getDict(locale), key);
    if (val == null && locale !== DEFAULT_LOCALE) {
      // 누락 시 한국어로 폴백
      val = resolveKey(getDict(DEFAULT_LOCALE), key);
    }
    if (val == null) {
      if (typeof console !== 'undefined') console.warn('[i18n] missing key:', key);
      return key;
    }
    if (typeof val === 'string') return interpolate(val, params);
    return val; // 배열/객체는 그대로 (예: consent items 배열)
  };

  // tKo: 항상 한국어 반환. 서버로 보내는 라벨은 admin이 한국어이므로
  // 사용자 로케일과 무관하게 한국어로 직렬화해 DB에 저장.
  window.tKo = function tKo(key, params) {
    let val = resolveKey(getDict(DEFAULT_LOCALE), key);
    if (val == null) return key;
    if (typeof val === 'string') return interpolate(val, params);
    return val;
  };

  // 로케일 → html lang 속성 매핑
  function htmlLangFor(loc) {
    if (loc === 'en') return 'en';
    if (loc === 'zh-TW') return 'zh-Hant-TW';
    return 'ko';
  }

  window.setLocale = function setLocale(loc) {
    if (!SUPPORTED.includes(loc)) return;
    window.currentLocale = loc;
    try { localStorage.setItem(STORAGE_KEY, loc); } catch (e) {}
    try { document.documentElement.lang = htmlLangFor(loc); } catch (e) {}
    try {
      const dict = getDict(loc).meta || {};
      if (dict.title) document.title = dict.title;
      const desc = document.querySelector('meta[name="description"]');
      if (desc && dict.description) desc.setAttribute('content', dict.description);
    } catch (e) {}
    try {
      const url = new URL(window.location.href);
      url.searchParams.set('lang', loc);
      window.location.href = url.toString();
    } catch (e) {
      window.location.reload();
    }
  };

  // ────────── 포맷터 ──────────
  // 환율은 정적. 분기별 수동 갱신 권장.
  // 기준: 1 USD ≈ 1330 KRW, 1 USD ≈ 30 TWD → 1 TWD ≈ 44.3 KRW.
  const USD_PER_KRW = 1 / 1330;
  const TWD_PER_KRW = 1 / 44.3;

  function fmtKrwLocal(n) { return n.toLocaleString('ko-KR'); }
  function fmtUsd(n) { return '$' + Math.round(n).toLocaleString('en-US'); }
  function fmtTwd(n) {
    // 100단위 반올림으로 깔끔하게
    const rounded = Math.round(n / 100) * 100;
    return 'NT$' + rounded.toLocaleString('en-US');
  }

  // 큰 금액 (총 수가, 항목 합계 등) — 로케일별 표시.
  // ko: "3,762,000원" / en: "₩3,762,000 (~$2,829)" / zh-TW: "NT$84,900 (約 ₩3,762,000)"
  window.wonFmtI18n = function (manwon) {
    const won = Math.round(manwon * 10000);
    const loc = window.currentLocale;
    if (loc === 'en') {
      return '₩' + won.toLocaleString('en-US') + ' (~' + fmtUsd(won * USD_PER_KRW) + ')';
    }
    if (loc === 'zh-TW') {
      return fmtTwd(won * TWD_PER_KRW) + ' (約 ₩' + fmtKrwLocal(won) + ')';
    }
    return fmtKrwLocal(won) + '원';
  };

  // 작은 영역 표시 (breakdown 명세 등). 외국어판은 현지 통화 단독.
  window.manwonFmtI18n = function (manwon) {
    const loc = window.currentLocale;
    if (manwon === 0) {
      if (loc === 'en') return '+0';
      if (loc === 'zh-TW') return '+0';
      return '0원';
    }
    if (loc === 'en') return fmtUsd(manwon * 10000 * USD_PER_KRW);
    if (loc === 'zh-TW') return fmtTwd(manwon * 10000 * TWD_PER_KRW);
    return manwon.toLocaleString('ko-KR') + '만원';
  };

  // 1모당 단가 (원 단위 정수) → 로케일별
  window.perGraftFmt = function (wonPerGraft) {
    const loc = window.currentLocale;
    if (loc === 'en') return '$' + (wonPerGraft * USD_PER_KRW).toFixed(2);
    if (loc === 'zh-TW') {
      const twd = wonPerGraft * TWD_PER_KRW;
      return 'NT$' + (twd < 10 ? twd.toFixed(1) : Math.round(twd).toString());
    }
    return wonPerGraft.toLocaleString('ko-KR') + '원';
  };

  // 모수(가닥 수) 표시. ko: "1,900모", en: "1,900 hairs", zh-TW: "1,900 根"
  // 주: 1모 = 1가닥(hair) — 사장님 클리닉 기준. 영문 "graft"는 모낭단위(1~4가닥)이라 부적합.
  window.graftCountFmt = function (n) {
    const loc = window.currentLocale;
    const num = n.toLocaleString(loc === 'ko' ? 'ko-KR' : 'en-US');
    if (loc === 'en') return num + ' hairs';
    if (loc === 'zh-TW') return num + ' 根';
    return num + '모';
  };

  // 모수 단순 숫자 (단위 별도 처리)
  window.numberFmt = function (n) {
    const loc = window.currentLocale;
    return n.toLocaleString(loc === 'ko' ? 'ko-KR' : 'en-US');
  };

  // 초기 lang 속성 동기화 (locale.js 로드 직후 적용)
  try { document.documentElement.lang = htmlLangFor(window.currentLocale); } catch (e) {}
  try {
    const dict = getDict(window.currentLocale).meta || {};
    if (dict.title) document.title = dict.title;
    const desc = document.querySelector('meta[name="description"]');
    if (desc && dict.description) desc.setAttribute('content', dict.description);
  } catch (e) {}
})();
