// i18n.jsx — minimal, dependency-free translation layer.
//
// Only English (`en`) and Chinese Simplified (`zh`) have real translations.
// Malay and Tamil are intentionally NOT in this file — the language picker
// (LanguagePanel in screen-you.jsx) shows them as "Unavailable" and disables
// them rather than silently falling back to English, so residents never
// think they picked Bahasa Melayu and got English by mistake.
//
// Usage in any screen component:
//   const tr = useT();
//   <div>{tr('home.rightNow')}</div>
//
// Keep keys namespaced by screen ("home.*", "play.*", ...) so two screens can
// reuse a word ("Save", "Cancel") under "common.*" without collisions.

const LANG_STORAGE_KEY = 'savehor_lang';
const SUPPORTED_LANGS = ['en', 'zh'];

const STRINGS = {
  en: {
    'nav.home': 'Home',
    'nav.play': 'Play',
    'nav.analysis': 'Analysis',
    'nav.you': 'You',

    'common.preview': 'Preview',
    'common.cancel': 'Cancel',
    'common.confirm': 'Confirm',
    'common.done': 'Done',
    'common.save': 'Save',
    'common.close': 'Close',
    'common.on': 'On',
    'common.off': 'Off',
    'common.loading': 'Loading…',

    'login.title': 'Welcome back',
    'login.sub': "Log in to see today's energy use.",
    'login.email': 'Email',
    'login.password': 'Password',
    'login.submit': 'Log in',
    'login.working': 'Logging in…',
    'login.error.generic': "That didn't work — check your email and password.",
    'login.noAccount': "Don't have an account?",
    'login.signup': 'Sign up',

    'signup.title': 'Create your account',
    'signup.sub': 'Join your household to start saving.',
    'signup.name': 'Full name',
    'signup.namePlaceholder': 'e.g. Felicia Chia',
    'signup.email': 'Email',
    'signup.emailPlaceholder': 'you@savehor.com',
    'signup.unit': 'Unit name',
    'signup.unitPlaceholder': 'e.g. Block 123 #04-12',
    'signup.unitHelper': 'Use the unit name your SaveHor admin registered.',
    'signup.password': 'Password',
    'signup.passwordPlaceholder': 'Must be 6 characters or more',
    'signup.confirm': 'Confirm password',
    'signup.terms': 'I agree to the Terms of Service and Privacy Policy',
    'signup.submit': 'Create account',
    'signup.working': 'Creating account…',
    'signup.loggingIn': 'Logging in…',
    'signup.haveAccount': 'Already have an account?',
    'signup.login': 'Log in',
    'signup.err.fillAll': 'Please fill in all fields.',
    'signup.err.pwLen': 'Password must be 6 characters or more.',
    'signup.err.pwMatch': 'Passwords do not match.',
    'signup.err.terms': 'Please agree to the Terms of Service and Privacy Policy.',

    'addDevice.title': 'Add an appliance',
    'addDevice.sub': 'Register a new device to your home.',
    'addDevice.back': 'Back',
    'addDevice.kind': 'Device type',
    'addDevice.kindPlug': 'Smart plug (Shelly)',
    'addDevice.kindAircon': 'Air conditioner (Spacemate module)',
    'addDevice.kindClamp': 'Whole-home CT clamp (AmpoCloud)',
    'addDevice.name': 'Appliance name',
    'addDevice.namePlaceholder': 'e.g. Living Room AC',
    'addDevice.type': 'Appliance type',
    'addDevice.typeLoading': 'Loading types…',
    'addDevice.plugId': 'Device ID',
    'addDevice.plugIdPlaceholder': 'e.g. shellypluspluguk-a1b2c3d4e5f6',
    'addDevice.plugIdHint': "Found in the Shelly app → your plug → Settings → MQTT, listed as the MQTT Prefix. The plug must already be set up with SaveHor's MQTT settings.",
    'addDevice.airconId': 'Aircon name',
    'addDevice.airconIdPlaceholder': 'e.g. Matt-home',
    'addDevice.airconIdHint': "The module's mitsubishi2mqtt name — the <name> in its MQTT topic mitsubishi2mqtt/<name>/state. Case-sensitive, so type it exactly.",
    'addDevice.clampId': 'Ampo device UUID',
    'addDevice.clampIdPlaceholder': 'e.g. 003F10153378',
    'addDevice.clampIdHint': "The UUID of the Ampo clamp, provided by Ampotech. It measures your whole home, so it's monitor-only — there's no on/off switch.",
    'addDevice.submit': 'Add appliance',
    'addDevice.working': 'Adding…',
    'addDevice.success': 'Appliance added',
    'addDevice.err.fill': 'Fill in the appliance name and {{idName}}.',
    'addDevice.err.generic': "Couldn't add that appliance.",
    'home.addAppliance': 'Add appliance',

    'home.rightNow': 'Right now',
    'home.on': 'on',
    'home.todaysQuests': "Today's quests",
    'home.allDone': 'All done for today!',
    'home.loadingUsage': 'Loading your usage…',
    'home.notConnected': "Not connected — can't estimate right now",
    'home.budgetSpent': 'Budget spent — more adds to the bill',
    'home.idle': 'Idle — budget holding steady',
    'home.coasting': 'Coasting — ',
    'home.lastsAllDay': 'lasts all day',
    'home.leftAtThisRate': 'left at this rate',
    'home.devicesOffline': 'Devices offline — retrying…',
    'home.noDevicesPaired': 'No devices paired yet',
    'home.notConnectedShort': 'Not connected',
    'home.loadingShort': 'Loading…',
    'home.loadingShorter': 'Loading',
    'home.retryingAutomatically': "We'll keep retrying automatically",
    'home.fetchingLiveUsage': 'Fetching your live usage',
    'home.reconnecting': 'Reconnecting…',
    'home.overAllowanceSuffix': "over today's allowance",
    'home.leftAllowanceSuffix': "of today's allowance left",
    'home.kwhUsed': 'kWh used',
    'home.statusOver': 'Over',
    'home.statusOnTrack': 'On track',
    'home.statusWatchIt': 'Watch it',
    'home.greetingOverToday': 'Over for today',
    'home.greetingGreat': "You're doing great",
    'home.greetingEaseOff': 'Ease off a little',
    'home.trackingUsage': 'Tracking your usage',
    'home.trackingUsageSub': 'Add your usual monthly usage to see how this month compares',
    'home.watchYourPace': 'Watch your pace',
    'home.fetchingLiveNumbers': 'Fetching your live numbers now. This only takes a moment.',
    'home.settingEllipsis': 'Setting…',
    'home.setAirconTo': 'Set aircon to',
    'home.quickWin': 'QUICK WIN',
    'home.aircon': 'Aircon',
    'home.oneDegreeWarmer': 'One degree warmer',
    'home.now': 'NOW',
    'home.goal': 'GOAL',
    'home.demoDevice': 'DEMO DEVICE',
    'common.live': 'LIVE',
    'home.runwayTooltip': "Based on your current draw of {{watts}}W at {{rate}}, measured against the ${{dollars}} left in today's budget. Switch things off to extend it.",
    'home.baseline.trackingAgainst': 'Tracking against your {{baseline}} kWh baseline',
    'home.baseline.daysMeasured': '{{n}} {{dayWord}} measured so far — comparing needs about {{minDays}}',
    'home.baseline.goalThisMonth': 'Your goal: use {{goalPct}}% less this month',
    'home.baseline.usingLess': "You're using {{savedPct}}% less than your baseline",
    'home.baseline.onTrackGoal': 'On track for your {{goalPct}}% goal — keep it up.',
    'home.baseline.shortGoal': "A little short of your {{goalPct}}% goal — you've got this.",
    'home.baseline.aboveBaseline': "You're {{absSavedPct}}% above your baseline so far",
    'home.baseline.pullBack': 'Small tweaks today pull it back under your {{goalPct}}% goal.',

    'statusSheet.ontrackTitle': "You're on track",
    'statusSheet.ontrackLine': "You've used less than expected for this time of day. Keep it up and you'll beat your monthly goal.",
    'statusSheet.watchTitle': 'Watch your pace',
    'statusSheet.watchLine': "You're using power a little faster than planned. Ease off now and you'll still finish the day on budget.",
    'statusSheet.overTitle': "Today's allowance is spent",
    'statusSheet.overLine': "You've used your full allowance for today. Anything more adds to this month's bill — try a quick quest to claw it back.",
    'statusSheet.offlineLine': "We can't reach your usage data right now. We'll keep retrying automatically — no need to do anything.",
    'statusSheet.percentLeft': "{{pct}}% of today's allowance left",
    'statusSheet.dailyAllowance': 'Daily allowance',
    'statusSheet.dailyAllowanceSub': "Your household's daily target",
    'statusSheet.usedSoFar': 'Used so far',
    'statusSheet.usedSoFarSub': 'Updates live as appliances run',
    'statusSheet.resets': 'Resets',
    'statusSheet.resetsValue': 'Midnight',
    'statusSheet.resetsSub': 'A fresh allowance every day',
    'common.gotIt': 'Got it',

    'play.previewNotice': "Preview — points, streaks and rewards aren't saved yet. Nothing tapped on this tab affects your bill or account.",
    'play.yourPoints': 'Your points',
    'play.dayStreak': 'day streak',
    'play.today': 'Today',
    'play.thisWeek': 'This week',
    'play.resetsSun': 'Resets Sun',
    'play.spendPoints': 'Spend points',
    'play.forYou': 'For you',
    'play.iDidIt': 'I did it',
    'play.redeemed': 'Redeemed!',
    'play.redeemedSub': "We'll text you within 24 hours.",
    'play.cost': 'Cost',
    'play.after': 'After',
    'play.credits': 'Credits',
    'play.vouchers': 'Vouchers',
    'play.donate': 'Donate',
    'play.badges': 'Badges',

    'analysis.day': 'Day',
    'analysis.week': 'Week',
    'analysis.month': 'Month',
    'analysis.sixMo': '6 mo',
    'analysis.whatYouUsed': 'What you used',
    'analysis.whereItGoes': 'Where it goes',
    'analysis.insights': 'Insights',
    'analysis.neighbours': 'Neighbours',
    'analysis.whenItRuns': 'When it runs',
    'analysis.peak': 'Peak',
    'analysis.runtime': 'Runtime',
    'analysis.homeShare': 'of home',
    'common.other': 'Other',

    'you.settings': 'Settings',
    'you.language': 'Language',
    'you.languageSub': "Singapore's four official languages",
    'you.devices': 'Devices',
    'you.devicesSub': 'Not your real paired devices',
    'you.addDevice': 'Add a device',
    'you.idle': 'Idle',
    'you.offline': 'Offline',
    'you.deviceAircon': 'Aircon',
    'you.deviceWaterHeater': 'Water heater',
    'you.deviceFridge': 'Fridge',
    'you.roomLivingRoom': 'Living room',
    'you.roomBathroom': 'Bathroom',
    'you.roomKitchen': 'Kitchen',
    'you.privacy': 'Privacy',
    'you.unavailable': 'Unavailable',
  },
  zh: {
    'nav.home': '首页',
    'nav.play': '任务',
    'nav.analysis': '分析',
    'nav.you': '我的',

    'common.preview': '预览',
    'common.cancel': '取消',
    'common.confirm': '确认',
    'common.done': '完成',
    'common.save': '保存',
    'common.close': '关闭',
    'common.on': '开',
    'common.off': '关',
    'common.loading': '加载中…',

    'login.title': '欢迎回来',
    'login.sub': '登录查看今日用电情况。',
    'login.email': '电子邮箱',
    'login.password': '密码',
    'login.submit': '登录',
    'login.working': '正在登录…',
    'login.error.generic': '登录失败，请检查您的邮箱和密码。',
    'login.noAccount': '还没有账户？',
    'login.signup': '注册',

    'signup.title': '创建您的账户',
    'signup.sub': '加入您的家庭，开始省电。',
    'signup.name': '姓名',
    'signup.namePlaceholder': '例如 陈丽华',
    'signup.email': '电子邮箱',
    'signup.emailPlaceholder': 'you@savehor.com',
    'signup.unit': '单位名称',
    'signup.unitPlaceholder': '例如 Block 123 #04-12',
    'signup.unitHelper': '请填写 SaveHor 管理员为您登记的单位名称。',
    'signup.password': '密码',
    'signup.passwordPlaceholder': '至少 6 个字符',
    'signup.confirm': '确认密码',
    'signup.terms': '我同意服务条款和隐私政策',
    'signup.submit': '创建账户',
    'signup.working': '正在创建账户…',
    'signup.loggingIn': '正在登录…',
    'signup.haveAccount': '已经有账户了？',
    'signup.login': '登录',
    'signup.err.fillAll': '请填写所有字段。',
    'signup.err.pwLen': '密码至少需要 6 个字符。',
    'signup.err.pwMatch': '两次输入的密码不一致。',
    'signup.err.terms': '请先同意服务条款和隐私政策。',

    'addDevice.title': '添加电器',
    'addDevice.sub': '为您的家庭登记一个新设备。',
    'addDevice.back': '返回',
    'addDevice.kind': '设备类型',
    'addDevice.kindPlug': '智能插座（Shelly）',
    'addDevice.kindAircon': '空调（Spacemate 模块）',
    'addDevice.kindClamp': '全屋电流钳（AmpoCloud）',
    'addDevice.name': '电器名称',
    'addDevice.namePlaceholder': '例如 客厅空调',
    'addDevice.type': '电器种类',
    'addDevice.typeLoading': '正在加载种类…',
    'addDevice.plugId': '设备 ID',
    'addDevice.plugIdPlaceholder': '例如 shellypluspluguk-a1b2c3d4e5f6',
    'addDevice.plugIdHint': '在 Shelly 应用 → 您的插座 → 设置 → MQTT 中查看，即 MQTT 前缀。插座必须已按 SaveHor 的 MQTT 设置配置好。',
    'addDevice.airconId': '空调名称',
    'addDevice.airconIdPlaceholder': '例如 Matt-home',
    'addDevice.airconIdHint': '模块的 mitsubishi2mqtt 名称，即 MQTT 主题 mitsubishi2mqtt/<名称>/state 中的 <名称>。区分大小写，请准确输入。',
    'addDevice.clampId': 'Ampo 设备 UUID',
    'addDevice.clampIdPlaceholder': '例如 003F10153378',
    'addDevice.clampIdHint': 'Ampotech 提供的电流钳 UUID。它测量的是整个家庭，因此仅供监测，没有开关控制。',
    'addDevice.submit': '添加电器',
    'addDevice.working': '正在添加…',
    'addDevice.success': '电器已添加',
    'addDevice.err.fill': '请填写电器名称和{{idName}}。',
    'addDevice.err.generic': '无法添加该电器。',
    'home.addAppliance': '添加电器',

    'home.rightNow': '实时用电',
    'home.on': '台开启',
    'home.todaysQuests': '今日任务',
    'home.allDone': '今天的任务都完成了！',
    'home.loadingUsage': '正在加载用电数据…',
    'home.notConnected': '未连接 — 暂时无法估算',
    'home.budgetSpent': '预算已用完 — 之后用电将计入账单',
    'home.idle': '待机中 — 预算保持稳定',
    'home.coasting': '轻松使用 — ',
    'home.lastsAllDay': '可用一整天',
    'home.leftAtThisRate': '按此速度还能用',
    'home.devicesOffline': '设备离线 — 正在重试…',
    'home.notConnectedShort': '未连接',
    'home.loadingShort': '加载中…',
    'home.loadingShorter': '加载中',
    'home.retryingAutomatically': '系统将自动重试',
    'home.fetchingLiveUsage': '正在获取您的实时用电数据',
    'home.reconnecting': '正在重新连接…',
    'home.overAllowanceSuffix': '超出今日额度',
    'home.leftAllowanceSuffix': '今日额度剩余',
    'home.kwhUsed': '千瓦时已用',
    'home.statusOver': '超支',
    'home.statusOnTrack': '正常',
    'home.statusWatchIt': '需留意',
    'home.greetingOverToday': '今天已超支',
    'home.greetingGreat': '做得很好',
    'home.greetingEaseOff': '稍微省一点吧',
    'home.trackingUsage': '正在追踪您的用电量',
    'home.trackingUsageSub': '添加您平常每月的用电量，即可查看本月对比情况',
    'home.watchYourPace': '留意您的用电速度',
    'home.fetchingLiveNumbers': '正在获取您的实时数据，请稍候。',
    'home.settingEllipsis': '设置中…',
    'home.setAirconTo': '将空调设为',
    'home.quickWin': '轻松省电',
    'home.aircon': '空调',
    'home.oneDegreeWarmer': '调高一度',
    'home.now': '现在',
    'home.goal': '目标',
    'home.demoDevice': '演示设备',
    'common.live': '实时',
    'home.runwayTooltip': '根据您目前 {{watts}}瓦 的用电量（{{rate}}）估算，对比今天预算剩余的 ${{dollars}}。关掉一些电器即可延长这个额度。',
    'home.baseline.trackingAgainst': '正在对比您的 {{baseline}} 千瓦时基准用电量',
    'home.baseline.daysMeasured': '已记录 {{n}} 天数据 — 还需约 {{minDays}} 天才能比较',
    'home.baseline.goalThisMonth': '您的目标：本月减少 {{goalPct}}% 用电量',
    'home.baseline.usingLess': '您的用电量比基准低 {{savedPct}}%',
    'home.baseline.onTrackGoal': '正朝着 {{goalPct}}% 的目标前进 — 保持下去。',
    'home.baseline.shortGoal': '距离 {{goalPct}}% 的目标还差一点 — 您可以做到。',
    'home.baseline.aboveBaseline': '目前用电量比基准高 {{absSavedPct}}%',
    'home.baseline.pullBack': '今天做些小调整，即可拉回到 {{goalPct}}% 目标以内。',

    'statusSheet.ontrackTitle': '进度正常',
    'statusSheet.ontrackLine': '您此刻的用电量低于预期。保持下去，即可达成本月目标。',
    'statusSheet.watchTitle': '请留意用电速度',
    'statusSheet.watchLine': '您的用电速度比计划稍快。现在稍微省一点，今天仍能保持在预算内。',
    'statusSheet.overTitle': '今日额度已用完',
    'statusSheet.overLine': '您已用完今天的额度，之后的用电将计入本月账单 — 试试完成一个任务，把它省回来。',
    'statusSheet.offlineLine': '暂时无法获取您的用电数据。系统将自动重试，您无需进行任何操作。',
    'statusSheet.percentLeft': '今日额度剩余 {{pct}}%',
    'statusSheet.dailyAllowance': '每日额度',
    'statusSheet.dailyAllowanceSub': '您家庭的每日用电目标',
    'statusSheet.usedSoFar': '已用电量',
    'statusSheet.usedSoFarSub': '随电器使用实时更新',
    'statusSheet.resets': '重置时间',
    'statusSheet.resetsValue': '午夜',
    'statusSheet.resetsSub': '每天都会获得新的额度',
    'common.gotIt': '知道了',
    'home.noDevicesPaired': '尚未配对任何设备',

    'play.previewNotice': '预览 — 积分、连续天数和奖励目前尚未保存。此页面的任何操作都不会影响您的账单或账户。',
    'play.yourPoints': '我的积分',
    'play.dayStreak': '天连续',
    'play.today': '今天',
    'play.thisWeek': '本周',
    'play.resetsSun': '周日重置',
    'play.spendPoints': '兑换积分',
    'play.forYou': '为您推荐',
    'play.iDidIt': '我做到了',
    'play.redeemed': '兑换成功！',
    'play.redeemedSub': '我们将在24小时内发短信通知您。',
    'play.cost': '所需积分',
    'play.after': '兑换后剩余',
    'play.credits': '账单抵扣',
    'play.vouchers': '礼券',
    'play.donate': '捐赠',
    'play.badges': '徽章',

    'analysis.day': '日',
    'analysis.week': '周',
    'analysis.month': '月',
    'analysis.sixMo': '6个月',
    'analysis.whatYouUsed': '用电概览',
    'analysis.whereItGoes': '用电去向',
    'analysis.insights': '洞察',
    'analysis.neighbours': '邻居',
    'analysis.whenItRuns': '使用时段',
    'analysis.peak': '高峰',
    'analysis.runtime': '运行时长',
    'analysis.homeShare': '占全家用电',
    'common.other': '其他',

    'you.settings': '设置',
    'you.language': '语言',
    'you.languageSub': '新加坡的四种官方语言',
    'you.devices': '设备',
    'you.devicesSub': '并非您真实配对的设备',
    'you.addDevice': '添加设备',
    'you.idle': '待机',
    'you.offline': '离线',
    'you.deviceAircon': '空调',
    'you.deviceWaterHeater': '热水器',
    'you.deviceFridge': '冰箱',
    'you.roomLivingRoom': '客厅',
    'you.roomBathroom': '浴室',
    'you.roomKitchen': '厨房',
    'you.privacy': '隐私',
    'you.unavailable': '暂不支持',
  },
};

function getStoredLang() {
  // While the language picker is off (src/features.js), the app is English
  // only — including for anyone who already switched to Chinese before it was
  // hidden. Without this they'd be stranded in a half-translated UI with no
  // control left to switch back. The stored choice is left untouched, so it
  // comes back by itself when the picker is re-enabled.
  if (!FEATURES.languagePicker) return 'en';
  try {
    const v = localStorage.getItem(LANG_STORAGE_KEY);
    return SUPPORTED_LANGS.includes(v) ? v : 'en';
  } catch (e) {
    return 'en';
  }
}

const LangContext = React.createContext({ lang: 'en', setLang: () => {} });

function LangProvider({ children }) {
  const [lang, setLangState] = React.useState(getStoredLang);
  const setLang = React.useCallback((l) => {
    if (!SUPPORTED_LANGS.includes(l)) return;   // 'ms'/'ta' are picked via disabled rows only
    setLangState(l);
    try { localStorage.setItem(LANG_STORAGE_KEY, l); } catch (e) { /* private mode */ }
  }, []);
  const value = React.useMemo(() => ({ lang, setLang }), [lang, setLang]);
  return <LangContext.Provider value={value}>{children}</LangContext.Provider>;
}

function useLang() {
  return React.useContext(LangContext);
}

// useT — returns a translate function `tr(key, vars?)`. Named `tr`, not `t`,
// at call sites: plenty of existing components already use `t` for other
// things (tab objects, timestamps), and shadowing them silently breaks the UI.
// `vars` fills `{{name}}` placeholders in the template, e.g.
//   tr('home.daysMeasured', { n: 4 })  with template "{{n}} days measured…"
function useT() {
  const { lang } = useLang();
  return React.useCallback((key, vars) => {
    const table = STRINGS[lang] || STRINGS.en;
    const template = table[key] != null ? table[key] : (STRINGS.en[key] != null ? STRINGS.en[key] : key);
    if (!vars) return template;
    return template.replace(/\{\{(\w+)\}\}/g, (m, name) => (vars[name] != null ? vars[name] : m));
  }, [lang]);
}

Object.assign(window, { LangProvider, useLang, useT, STRINGS, SUPPORTED_LANGS });
