#!/usr/bin/env node
/**
 * Merge missing Nepali (ne) i18n keys from translations map.
 * Usage: node scripts/merge-ne-translations.mjs
 */
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.join(__dirname, "..");
const localesDir = path.join(root, "src/i18n/locales");

/** @type {Record<string, Record<string, string>>} */
const translations = {
  "adminUsers.json": {
    siteRequired: "साइट छान्नुहोस्",
    "table.sites": "बाँधिएका साइटहरू",
    "permissionDialog.site": "साइट",
    "accountDialog.site": "बाँधिएको साइट",
    "accountDialog.sitePlaceholder": "यो खाताले पहुँच पाउने साइट छान्नुहोस्",
  },
  "agents.json": {
    "lineUi.kicker": "क्रेडिट शेयर · एजेन्ट ट्री",
    "lineUi.agentCount": "यो समूहमा {{count}} एजेन्ट",
    "lineUi.searchPlaceholder": "नाम वा लगइन खोज्नुहोस्",
    "lineUi.directChildren": "प्रत्यक्ष अधीनस्थ {{count}}",
    "lineUi.selectAgent": "शेयर र क्रेडिट हेर्न एजेन्ट छान्नुहोस्",
    "lineUi.selectAgentHint":
      "सेटलमेन्ट सीमा एजेन्ट ट्री अनुसार; शेयर, क्रेडिट र रिबेट प्रति नोड कन्फिग गरिन्छ।",
    "lineUi.allocatedCredit": "बाँडिएको",
    "lineUi.availableCredit": "उपलब्ध",
    "lineUi.profileFootnote": "रिबेट सीमा {{rebate}}% · पूर्वनिर्धारित {{defaultRebate}}%",
    "lineUi.tabOverview": "अवलोकन",
    "lineUi.tabProfile": "शेयर र क्रेडिट",
    "lineUi.tabProfileReadOnly": "शेयर र क्रेडिट (पढ्न मात्र)",
    "lineUi.currentSite": "साइट",
    "lineUi.viewAll": "सबै हेर्नुहोस्",
    "lineUi.shareRebateCap": "रिबेट सीमा {{rate}}%",
    "lineUi.overviewDownlineCard": "प्रत्यक्ष अधीनस्थ एजेन्ट हेर्नुहोस् र व्यवस्थापन गर्नुहोस्",
    "lineUi.overviewDownlineCount": "{{count}}",
    "lineUi.overviewPlayersHint": "प्रत्यक्ष खेलाडी र क्रेडिट स्थिति हेर्नुहोस्",
    "lineUi.overviewPlayersSummary": "खेलाडी व्यवस्थापन",
    "lineUi.downlineEmptyTitle": "अहिले प्रत्यक्ष अधीनस्थ छैन",
    "lineUi.editAccount": "खाता र स्थिति",
    "lineUi.saveProfile": "शेयर र क्रेडिट बचत",
    "lineUi.tabDownline": "अधीनस्थ",
    "lineUi.tabPlayers": "खेलाडी",
    "lineUi.noDelegatedTabs":
      "यो एजेन्टले अधीनस्थ एजेन्ट वा खेलाडी सिर्जना गर्न सक्दैन; शेयर र क्रेडिट मात्र लागू हुन्छ।",
    listSearch: "नाम / कोड / लगइन खोज्नुहोस्",
    siteSearch: "साइट नाम खोज्नुहोस्",
    parentAgent: "माथिल्लो",
    childrenCount: "प्रत्यक्ष अधीनस्थ",
    "subnav.provisionHint": "एक पटकको अनबोर्डिङ; दैनिक कामका लागि लाइन र एजेन्ट ट्री प्रयोग गर्नुहोस्",
    "profile.validation.creditBelowAllocated":
      "क्रेडिट सीमा बाँडिएको क्रेडिभन्दा कम हुन सक्दैन (न्यूनतम {{min}})",
    "profile.validation.creditExceedsParentWithMax": "क्रेडिट सीमा {{max}} भन्दा बढी हुन सक्दैन",
    "settlementBills.periodLabel": "अवधि",
    "settlementBills.periodPlaceholder": "अवधि छान्नुहोस्",
    "settlementBills.allPeriods": "सबै अवधि",
    "settlementBills.filteredByPeriodRange": "{{range}} का बिलहरू",
    "settlementBills.emptyNoPeriodsManage":
      "अहिले अवधि वा बिल छैन। अवधि व्यवस्थापनमा छिटो प्रिसेट प्रयोग गर्नुहोस्, त्यसपछि अवधि बन्द गर्नुहोस्।",
    "settlementBills.emptyNoPeriodsAgent":
      "अहिले बिल छैन। तपाईंको माथिल्लो वा प्लेटफर्मले अवधि बन्द गर्छ; मिति प्रविष्ट गर्नु पर्दैन।",
    "settlementBills.emptyNoClosed": "बन्द अवधि छैन। बिल बन्द पछि सिर्जना हुन्छ।",
    "settlementBills.typePlayer": "खेलाडी बिल",
    "settlementBills.typeAgent": "एजेन्ट बिल",
    "settlementBills.columns.period": "अवधि",
    "settlementPeriods.manageTitle": "अवधि व्यवस्थापन",
    "settlementPeriods.manageHint":
      "यहाँ अवधि खोल्नुहोस् र बन्द गर्नुहोस्; माथिका बिल स्वतः अद्यावधिक हुन्छ। छिटो प्रिसेट सामान्यतया पर्याप्त।",
    "settlementPeriods.presetThisWeek": "यो हप्ता",
    "settlementPeriods.presetLastWeek": "गत हप्ता",
    "settlementPeriods.presetThisMonth": "यो महिना",
    "settlementPeriods.openHint": "स्थानीय मिति ({{tz}})",
    "settlementPeriods.startDate": "सुरु मिति",
    "settlementPeriods.endDate": "अन्त्य मिति",
    "settlementPeriods.open": "अवधि खोल्नुहोस्",
    "settlementPeriods.openFailed": "अवधि खोल्न असफल",
    "settlementPeriods.datesRequired": "सुरु र अन्त्य मिति प्रविष्ट गर्नुहोस्",
    "settlementPeriods.invalidRange": "अन्त्य मिति सुरु मितिभन्दा अगाडि हुन सक्दैन",
    "settlementPeriods.statusOpen": "खुला",
    "settlementPeriods.statusClosed": "बन्द",
    "playersPanel.loginRequired": "लगइन प्रयोगकर्ता नाम र प्रारम्भिक पासवर्ड प्रविष्ट गर्नुहोस्",
    "playersPanel.loginUsername": "लगइन प्रयोगकर्ता नाम",
    "playersPanel.initialPassword": "प्रारम्भिक पासवर्ड",
    "playersPanel.externalIdOptional": "बाह्य ID (वैकल्पिक)",
    "playersPanel.externalIdHint": "स्वतः सिर्जनाका लागि खाली राख्नुहोस्",
    "playersPanel.creditLimit": "क्रेडिट सीमा",
    "playersPanel.rebateRate": "रिबेट दर (%)",
    "playersPanel.rebateRateHint": "प्रतिशत लेख्नुहोस्, जस्तै 5 = 5%",
    "playersPanel.availableToGrant": "एजेन्टले दिन सक्ने: {{amount}}",
    "playersPanel.riskTags": "जोखिम ट्याग",
    "playersPanel.riskTagsPlaceholder": "अल्पविरामले छुट्याउनुहोस्",
    "playersPanel.createSuccessNative": "खेलाडी {{name}} सिर्जना भयो — लटरी /login प्रयोग गर्नुहोस्",
    "users.email": "इमेल",
  },
  "common.json": {
    "export.ticketCombinations.filename": "ticket-combinations",
    "export.ticketCombinations.sheetName": "संयोजनहरू",
    "integrationSites.emptyPlatformHint":
      "अहिले एकीकरण साइट छैन। एजेन्ट, खेलाडी वा सेटलमेन्ट व्यवस्थापन अघि साइट सिर्जना गर्नुहोस्।",
    "integrationSites.createSite": "एकीकरण साइट सिर्जना",
  },
  "config.json": {
    "integrationSites.adminAccountCreated": "साइट एडमिन खाता {{username}} सिर्जना भयो",
    "integrationSites.delete": "साइट मेटाउनुहोस्",
    "integrationSites.deleteSuccess": "साइट {{code}} मेटाइयो",
    "integrationSites.deleteFailed": "साइट मेटाउन असफल",
    "integrationSites.deleteConfirmTitle": "यो साइट मेटाउने?",
    "integrationSites.deleteConfirmDescription":
      "यसले साइट {{code}} ({{name}}), यसको एजेन्ट लाइन, सेटलमेन्ट अवधि, खेलाडी र साइट एडमिन खाता स्थायी रूपमा हटाउँछ। पूर्ववत गर्न मिल्दैन।",
    "integrationSites.deleteConfirm": "मेटाउनुहोस्",
    "integrationSites.deleting": "मेटाउँदै…",
    "integrationSites.form.adminUsernameRequired": "साइट एडमिन प्रयोगकर्ता नाम आवश्यक",
    "integrationSites.form.adminNicknameRequired": "साइट एडमिन उपनाम आवश्यक",
    "integrationSites.form.adminPasswordRequired": "प्रारम्भिक साइट एडमिन पासवर्ड कम्तीमा ८ अक्षर",
    "integrationSites.fields.adminUsername": "एडमिन प्रयोगकर्ता नाम",
    "integrationSites.fields.adminNickname": "एडमिन उपनाम",
    "integrationSites.fields.adminPassword": "प्रारम्भिक पासवर्ड",
    "integrationSites.fields.adminEmail": "इमेल (वैकल्पिक)",
    "integrationSites.placeholders.adminUsername": "एडमिन प्रयोगकर्ता नाम लेख्नुहोस्",
    "integrationSites.placeholders.adminNickname": "खाता उपनाम लेख्नुहोस्",
    "integrationSites.placeholders.adminPassword": "कम्तीमा ८ अक्षर",
    "integrationSites.placeholders.adminEmail": "इमेल लेख्नुहोस्",
    "integrationSites.adminAccountSectionTitle": "साइट एडमिन खाता",
    "integrationSites.adminAccountSectionDescription":
      "साइट सिर्जना गर्दा त्यस साइटसँग बाँधिएको एउटा एडमिन खाता पनि सिर्जना हुन्छ।",
    "system.saveDrawSuccess": "ड्र प्यारामिटर बचत भयो",
    "system.saveCurrencyFormatSuccess": "मुद्रा प्रदर्शन ढाँचा बचत भयो",
    "system.saveSettlementSuccess": "सेटलमेन्ट स्वचालन बचत भयो",
    "system.sections.draw": "ड्र तालिका र समीक्षा",
    "system.sections.drawDescription":
      "ड्र समय, बन्द सञ्झ्याल, म्यानुअल समीक्षा र कूलडाउन नियन्त्रण। यो ब्लकमा परिवर्तित फिल्ड मात्र पेश हुन्छ।",
    "system.sections.currencyFormat": "मुद्रा प्रदर्शन ढाँचा",
    "system.sections.currencyFormatDescription":
      "साइटभरि रकमका दशमलव र विभाजक (मुद्रा मास्टर डाटाबाट अलग)।",
    "system.sections.settlement": "सेटलमेन्ट स्वचालन",
    "system.sections.settlementDescription":
      "टिक स्वतः सेटलमेन्ट, अनुमोदन र भुक्तानी चलाउने नियन्त्रण। यो ब्लकमा परिवर्तित फिल्ड मात्र पेश हुन्छ।",
    "system.confirmSaveDrawTitle": "ड्र प्यारामिटर बचत गर्ने?",
    "system.confirmSaveDrawDescription":
      "यसले यो ब्लकमा ड्र समीक्षा, तालिका समय र कूलडाउन मात्र अद्यावधिक गर्छ।",
    "system.confirmSaveCurrencyFormatTitle": "मुद्रा प्रदर्शन ढाँचा बचत गर्ने?",
    "system.confirmSaveCurrencyFormatDescription": "यसले दशमलव स्थान र विभाजक अद्यावधिक गर्छ।",
    "system.confirmSaveSettlementTitle": "सेटलमेन्ट स्वचालन बचत गर्ने?",
    "system.confirmSaveSettlementDescription":
      "यसले स्वतः सेटलमेन्ट, अनुमोदन र भुक्तानी स्विच अद्यावधिक गर्छ।",
    "play.filters.sectionTitle": "खेल फिल्टर",
    "play.filters.sectionDescription":
      "पहिले सूची संकुचित गर्नुहोस्, त्यसपछि ब्याच स्विच वा पङ्क्ति सम्पादन प्रयोग गर्नुहोस्।",
    "play.filters.keyword": "खेल खोज्नुहोस्",
    "play.filters.keywordPlaceholder": "खेल कोड, प्रदर्शन नाम वा श्रेणीले फिल्टर",
    "play.filters.category": "श्रेणी",
    "play.filters.status": "स्थिति",
    "play.filters.allCategories": "सबै श्रेणी",
    "play.filters.allStatuses": "सबै स्थिति",
    "play.filters.uncategorized": "अवर्गीकृत",
    "play.filters.reset": "फिल्टर हटाउनुहोस्",
    "play.filters.empty": "मिल्ने खेल प्रकार छैन",
    "play.filters.groupCount": "{{count}} खेल",
  },
  "dashboard.json": {
    "analytics.summaryShareProfit": "आफ्नो शेयर नाफा",
    "analytics.shareProfitHint":
      "विभाजन पछि तपाईंको शेयर — प्लेटफर्म वा सम्पूर्ण टोलीको कुल नाफा/नोक्सान होइन",
    currentDrawFinanceHint: "तलका चार्ट ड्र {{drawNo}} का लागि",
    "agent.heroEyebrow": "आजको लाइन ककपिट",
    "agent.heroTitle": "{{name}} प्रत्यक्ष सञ्चालन",
    "agent.creditAllocated": "बाँडिएको {{amount}}",
    "agent.creditUsed": "प्रयोग {{amount}}",
    "agent.settlementCycle": "चक्र {{cycle}}",
    "agent.betOrdersToday": "आजका बाजी अर्डर",
    "agent.todayPayout": "आजको भुक्तानी",
    "agent.todayProfit": "आजको नाफा",
    "agent.sevenDayPayout": "भुक्तानी {{amount}}",
    "agent.sevenDayProfit": "नाफा {{amount}}",
    "agent.sevenDayShareProfit": "शेयर नाफा {{amount}}",
    "agent.topMomentum": "आजको बाजी केन्द्र",
    "agent.topMomentumHint": "नाफा {{profit}}",
    "agent.topMomentumPayout": "भुक्तानी {{amount}}",
    "agent.managementFocus": "व्यवस्थापन केन्द्र",
    "agent.focusBet": "आजको बाजी मात्रा निगरानी",
    "agent.focusPlayers": "आजका सक्रिय खेलाडी",
    "agent.focusBills": "पछ्याउन बाँकी बिल",
    "agent.quickStatsTitle": "लाइन अनुमति झलक",
    "agent.canCreateChildAgent": "सन्तान एजेन्ट सिर्जना गर्न सक्छ",
    "agent.canCreatePlayer": "खेलाडी सिर्जना गर्न सक्छ",
    "agent.lineDepth": "लाइन गहिराइ",
    "agent.viewBills": "बिल हेर्नुहोस्",
    "agent.viewLine": "एजेन्ट लाइन",
    "agent.quickLinks.tickets": "टिकट",
    "agent.quickLinks.players": "खेलाडी",
    "agent.quickLinks.reports": "रिपोर्ट",
    "agent.quickLinks.agents": "अधीनस्थ एजेन्ट",
    "agent.quickLinks.bills": "एजेन्ट बिल",
    "warnings.apiResourceMissing":
      "ड्यासबोर्ड विश्लेषण API दर्ता छैन। चलाउनुहोस्: php artisan lottery:admin-auth-sync (वा पछिल्लो माइग्रेसन), त्यसपछि रिफ्रेस।",
  },
  "draws.json": {
    backToList: "ड्र सूचीमा फर्कनुहोस्",
    overviewTitle: "ड्र अवलोकन",
    overviewBetTotal: "कुल बाजी",
    overviewPayoutTotal: "कुल भुक्तानी",
    overviewProfitLoss: "नाफा/नोक्सान",
    reviewQueueHint: "नतिजा सिर्जना पछि समीक्षा र प्रकाशनमा जारी राख्नुहोस्।",
  },
  "players.json": {
    ticketTableHint:
      "यो तालिकाले खेलाडीका हालैका टिकट देखाउँछ। पूर्ण सन्दर्भ र समस्या समाधानका लागि पङ्क्ति कार्यबाट मुख्य टिकट सूचीमा जानुहोस्।",
    tabCreditLedger: "क्रेडिट लेजर",
    filterSite: "साइट",
    filterAllSites: "सबै साइट",
    scopeAllSites: "स्कोप: सबै साइटका सबै खेलाडी (सुपर एडमिन)",
    scopeFilteredSite: "स्कोप: साइट {{site}}",
    scopeAgentLine: "स्कोप: {{site}} · एजेन्ट लाइन “{{name}}” र अधीनस्थ खेलाडी",
    scopeSingleSite: "स्कोप: साइट {{site}}",
    scopeMultiSite: "स्कोप: {{count}} बाँधिएका साइट; संकुचित गर्न फिल्टर प्रयोग गर्नुहोस्",
    fundingMode: "फन्डिङ मोड",
    authSource: "प्रमाणीकरण स्रोत",
    creditSection: "क्रेडिट लाइन",
    usedCredit: "प्रयोग भएको क्रेडिट",
    fundingCredit: "क्रेडिट लाइन",
    fundingWallet: "मुख्य साइट वालेट",
    authMainSite: "मुख्य साइट SSO",
    authNative: "लटरी नेटिभ",
    creditLimit: "क्रेडिट सीमा",
    availableCredit: "उपलब्ध क्रेडिट",
    confirmFreezeTitle: "खेलाडी फ्रिज गर्ने?",
    confirmFreezeDescription: "खेलाडी {{name}} ले बाजी लगाउन सक्ने छैन।",
    confirmUnfreezeTitle: "खेलाडी अनफ्रिज गर्ने?",
    confirmUnfreezeDescription: "खेलाडी {{name}} सामान्य स्थितिमा फर्किनेछ।",
  },
  "reconcile.json": {
    createHint:
      "छानिएको अवधिमा ट्रान्सफर अर्डर स्क्यान गर्छ, लटरी वालेट लेजर तुलना गर्छ, र वालेट API कन्फिग भएमा मुख्य साइट idempotent रेकर्ड जाँच गर्छ।",
    createSuccessEmpty: "स्क्यान सम्पन्न: कुनै समस्या फेला परेन",
    transferNo: "ट्रान्सफर नं.",
    walletTxnNo: "लटरी वालेट लेनदेन",
    mainSiteRef: "मुख्य साइट सन्दर्भ",
    mainSiteCheck: "मुख्य साइट जाँच",
    actions: "कार्य",
    itemMainSiteRecordMissing: "मुख्य साइटमा छैन",
    itemMainSiteFailed: "मुख्य साइटमा असफल",
    mainSiteMatched: "मुख्य साइट ठीक",
    mainSiteNotFound: "मुख्य साइटमा छैन",
    mainSiteFailed: "मुख्य साइट असफल",
    mainSiteUnavailable: "मुख्य साइट उपलब्ध छैन",
    mainSiteSkipped: "जाँच गरिएको छैन",
  },
  "reports.json": {
    "tasks.currentReportHint": "यहाँ हाल छानिएको रिपोर्टका निर्यात कार्य मात्र देखिन्छ।",
    "preview.stats.notQueried": "क्वेरी गरिएको छैन",
    "preview.stats.notSet": "सेट गरिएको छैन",
  },
  "risk.json": {
    "confirm.closeTitle": "नम्बर बन्द गर्ने?",
    "confirm.closeDescription": "नम्बर {{number}} यो ड्रका लागि ब्लक हुनेछ।",
    "confirm.recoverTitle": "नम्बर पुन: खोल्ने?",
    "confirm.recoverDescription": "नम्बर {{number}} फेरि बाजीका लागि खुल्नेछ।",
  },
  "tickets.json": {
    filterSite: "साइट",
    filterAllSites: "सबै साइट",
    viewTicketInList: "यो टिकट हेर्नुहोस्",
    statusSelectedCount: "{{count}} छानिएको",
  },
  "wallet.json": {
    scopeHint:
      "यो क्षेत्र मुख्य साइट वालेट मोड (वालेट लेनदेन र ट्रान्सफर) का लागि हो। क्रेडिट लाइन अवधि सेटलमेन्टका लागि हेर्नुहोस्",
    scopeHintSettlementLink: "सेटलमेन्ट केन्द्र",
    scopeHintSettlement: "सेटलमेन्ट केन्द्र",
    ledgerChannel: "लेजर",
    ledgerCredit: "क्रेडिट लेजर",
    ledgerWallet: "वालेट लेनदेन",
  },
};

function setNested(obj, dotKey, value) {
  const parts = dotKey.split(".");
  let cur = obj;
  for (let i = 0; i < parts.length - 1; i++) {
    if (!(parts[i] in cur) || typeof cur[parts[i]] !== "object" || Array.isArray(cur[parts[i]])) {
      cur[parts[i]] = {};
    }
    cur = cur[parts[i]];
  }
  cur[parts[parts.length - 1]] = value;
}

function sortKeysDeep(value) {
  if (Array.isArray(value)) return value;
  if (value && typeof value === "object") {
    return Object.fromEntries(
      Object.keys(value)
        .sort()
        .map((k) => [k, sortKeysDeep(value[k])]),
    );
  }
  return value;
}

let merged = 0;
for (const [file, keys] of Object.entries(translations)) {
  const nePath = path.join(localesDir, "ne", file);
  const ne = JSON.parse(fs.readFileSync(nePath, "utf8"));
  for (const [dotKey, neValue] of Object.entries(keys)) {
    setNested(ne, dotKey, neValue);
    merged++;
  }
  fs.writeFileSync(nePath, `${JSON.stringify(sortKeysDeep(ne), null, 2)}\n`, "utf8");
  console.log(`Updated ${file} (+${Object.keys(keys).length} keys)`);
}
console.log(`Total merged: ${merged}`);
