import { useState, useEffect, createContext, useMemo } from 'react';
import { IntlProvider } from 'react-intl';
import enBase from '../translations/en.json';
import cnBase from '../translations/zh-CN.json';
import hkBase from '../translations/zh-HK.json';

import { GET_COMBO, GET_CONTENT } from "utils/ApiPathConst";
import { get } from "utils/HttpUtils";

const LocaleContext = createContext();

export const I18nProvider = ({ children }) => {
  const [locale, setLocale] = useState('en');

  // keep base messages immutable
  const [systemMessages, setSystemMessages] = useState({
    en: { ...enBase },
    zh: { ...hkBase },
    'zh-HK': { ...hkBase },
    'zh-CN': { ...cnBase }
  });

  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    const saved = localStorage.getItem('locale');
    if (!saved) localStorage.setItem('locale', 'en');
    else setLocale(saved);
  }, []);

  useEffect(() => {
    let alive = true;

    const loadTermsAndConditions = () => {
      // load both endpoints then merge into state
      const p1 = new Promise((resolve) => {
        get({
          url: GET_CONTENT,
          onSuccess: (resp) => resolve(resp || {}),
          onError: () => resolve({})
        });
      });

      const p2 = new Promise((resolve) => {
        get({
          url: GET_COMBO,
          onSuccess: (resp) => resolve(resp || []),
          onError: () => resolve([])
        });
      });

      Promise.all([p1, p2]).then(([contentMap, comboList]) => {
        if (!alive) return;

        setSystemMessages((prev) => {
          // clone prev first (immutably)
          const next = {
            ...prev,
            en: { ...prev.en },
            'zh-CN': { ...prev['zh-CN'] },
            'zh-HK': { ...prev['zh-HK'] },
            zh: { ...prev.zh }
          };

          // merge GET_CONTENT (object)
          for (const key in contentMap) {
            const v = contentMap[key] || {};
            next.en[key] = v.en ?? "";
            next['zh-CN'][key] = v.cn ?? "";
            next['zh-HK'][key] = v.zh ?? "";
            next.zh[key] = v.zh ?? "";
          }

          // merge GET_COMBO (array)
          for (const item of comboList) {
            if (!item?.key) continue;
            next.en[item.key] = item.en ?? "";
            next['zh-CN'][item.key] = item.cn ?? "";
            next['zh-HK'][item.key] = item.zh ?? "";
            next.zh[item.key] = item.zh ?? "";
          }

          return next;
        });

        setLoaded(true);
      });
    };

    loadTermsAndConditions();

    return () => {
      alive = false;
    };
  }, []);

  const messages = useMemo(() => {
    return systemMessages[locale] || systemMessages.en;
  }, [systemMessages, locale]);

  return (
    <LocaleContext.Provider value={{ locale, setLocale }}>
      <IntlProvider
        key={locale}
        locale={locale}
        messages={messages}
        defaultLocale="en"
      >
        {loaded ? children : <div />}
      </IntlProvider>
    </LocaleContext.Provider>
  );
};

export default LocaleContext;
