/* Route table — gives every navigable page its own clean, bookmarkable
   URL path (e.g. /players, /users) instead of everything living under
   one address. `active` (the page id used throughout host.jsx/app.jsx)
   is the single source of truth for "what's on screen"; this table is
   just the two-way mapping between that id and a URL path.

   A few PayBO-internal pages share a label with a top host-nav item of
   the same name (e.g. PayBO's own "Players" sub-page vs. the host's
   "Players" top-nav item) — those are nested under /payments/... so
   the paths stay unique. */

const ROUTE_TABLE = [
  // PayBO (Payments) section — reached via the "Payments" host-nav item.
  ["dashboard", "/payments/dashboard"],
  ["transactions", "/payments/transactions"],
  ["deposits", "/payments/deposits"],
  ["withdrawals", "/payments/withdrawals"],
  ["to-confirm", "/payments/to-confirm"],
  ["methods", "/payments/methods"],
  ["players", "/payments/players"],
  ["rules", "/payments/rules"],
  ["fees", "/payments/fees"],
  ["reports", "/payments/reports"],
  ["activity", "/payments/activity"],
  ["devphase", "/payments/development"],
  ["frontend", "/payments/frontend"],
  ["settings", "/payments/settings"],

  // White-label host top nav.
  ["host-dashboard", "/dashboard"],
  ["host-players", "/players"],
  ["host-users", "/users"],
  ["host-sportcoupons", "/sport-coupons"],
  ["host-deposit", "/deposit"],
  ["host-vouchers", "/vouchers"],
  ["host-deposits", "/deposits"],
  ["host-withdraws", "/withdraws"],
  ["host-messages", "/messages"],
  ["bonus-programs", "/bonus-campaigns"],
  ["bonus-promo-codes", "/bonus-campaigns/promo-codes"],

  // Report dropdown.
  ["bonus-retention", "/reports/bonus-retention"],
  ["report-conversion", "/reports/conversion"],
  ["report-summary", "/reports/summary"],
  ["report-players", "/reports/players"],
  ["report-betting", "/reports/betting"],
  ["report-bettype", "/reports/bet-type"],
  ["report-daily", "/reports/daily"],
  ["report-transactions", "/reports/transactions"],
  ["report-credittx", "/reports/credit-transactions"],
  ["report-withdrawals", "/reports/withdrawal-requests"],
  ["report-commissions", "/reports/commissions"],
  ["report-costs", "/reports/provider-costs"],
  ["report-netwin", "/reports/net-win"],
  ["report-dailyperf", "/reports/daily-performance"],
  ["report-business", "/reports/business"],

  // Settings (Impostazioni) dropdown.
  ["settings-languages", "/settings/languages"],
  ["settings-jobs", "/settings/jobs"],
  ["settings-change-domain", "/settings/change-domain"],
  ["settings-deposit-methods", "/settings/deposit-methods"],
  ["settings-withdrawal-methods", "/settings/withdrawal-methods"],
  ["settings-currencies", "/settings/currencies"],
  ["settings-deleted-users", "/settings/deleted-users"],
  ["settings-support", "/settings/support"],
  ["host-myaccount", "/myaccount"],
  ["report-network-liab", "/reports/network-liabilities"],
  ["report-affiliates", "/reports/affiliates"],
  ["host-withdraw-to", "/withdraw"],
  ["settings-vendors", "/settings/vendors-groups"],

  // Stand-up tooling, not an operator screen. Reachable by URL only — it is
  // deliberately absent from every nav, because it belongs to whoever is
  // connecting the platform, not to whoever runs it.
  ["dev-connection", "/dev/connection"],

  // Commissions dropdown.
  ["comm-sport-profiles", "/commissions/sport-profiles"],
  ["comm-profiles", "/commissions/profiles"],
  ["comm-payments", "/commissions/payments"],
  ["comm-cashback", "/commissions/cashback"],
  ["comm-cashback-payments", "/commissions/cashback-payments"],

  // CMS dropdown.
  ["cms-banners", "/cms/banners"],
  ["cms-faq", "/cms/faq"],
  ["cms-faq-cat", "/cms/faq-categories"],
  ["cms-promotions", "/cms/promotions"],
  ["cms-provider-promo", "/cms/provider-promotions"],
  ["cms-promoplay", "/cms/promoplay-promotions"],
  ["cms-promo-triggers", "/cms/promo-triggers"],
  ["sport-bet", "/sport/bet"],
  ["sport-settings", "/sport/settings"],
  ["cms-blogs", "/cms/blogs"],
  ["cms-blog-cat", "/cms/blog-categories"],
  ["cms-help-cat", "/cms/help-categories"],
  ["cms-help-pages", "/cms/help-pages"],
  ["host-skins", "/cms/skins"],
  ["cms-game-cat", "/cms/game-categories"],
  ["cms-game-subcat", "/cms/game-subcategories"],
  ["cms-game-labels", "/cms/game-labels"],
  ["cms-game-import", "/cms/game-import"],
  ["cms-providers", "/cms/providers"],
  ["cms-launch-urls", "/cms/launch-urls"],
  ["cms-oauth", "/cms/oauth-clients"],

  // Legacy standalone page, kept for back-compat.
];

const ROUTE_TO_PATH = Object.fromEntries(ROUTE_TABLE);
const PATH_TO_ROUTE = Object.fromEntries(ROUTE_TABLE.map(([id, path]) => [path, id]));

// Turns a plain tab label ("Banner Provider Promotion", "FAQ & FOOTER (API)")
// into a URL-safe slug ("banner-provider-promotion", "faq-footer-api") —
// used by pages whose tabs are just an array of label strings rather than
// [id, label, slug] tuples.
const slugifyTab = (label) => String(label).toLowerCase()
  .replace(/[()&]/g, " ")
  .replace(/[^a-z0-9]+/g, "-")
  .replace(/^-+|-+$/g, "");
window.slugifyTab = slugifyTab;

const pathForActive = (id) => ROUTE_TO_PATH[id] || null;
const activeForPath = (path) => {
  if (!path) return null;
  const clean = path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path;
  if (PATH_TO_ROUTE[clean]) return PATH_TO_ROUTE[clean];
  // Prefix fallback — a drill-in page's own sub-tabs (e.g. /players/history,
  // via useUrlTab below) aren't registered as top-level routes, so a direct
  // load/refresh on one still needs to resolve back to its parent page
  // instead of falling through to the default. Longest match wins in case
  // more than one registered path is a prefix.
  let best = null, bestLen = -1;
  for (const [id, routePath] of ROUTE_TABLE) {
    if (clean.startsWith(routePath + "/") && routePath.length > bestLen) { best = id; bestLen = routePath.length; }
  }
  return best;
};

window.pathForActive = pathForActive;
window.activeForPath = activeForPath;

/* Sub-tab URL sync for a drill-in page whose top-level route already has a
   canonical path (e.g. /players) but whose content has its own independent
   tabs that deserve a path too (e.g. /players/history). No record id is
   encoded — a fresh load of /players/history still needs a player selected
   in memory to mean anything; until then it just falls back to the page's
   base view, same as loading the bare base path.

   `tabs` is the same [id, label, slug] tuple shape already used for on-
   screen tab rendering — slug "" means "this is the default tab, no path
   suffix". Returns [tab, setTab], mirroring useState. */
const useUrlTab = (basePath, tabs, defaultTab) => {
  const resolve = (path) => {
    if (path === basePath) return defaultTab;
    if (path.startsWith(basePath + "/")) {
      const rest = path.slice(basePath.length + 1);
      // Exact match first; then longest-prefix match for tabs whose own
      // content has further nested sub-routes (e.g. a wizard whose steps
      // live under this tab's own path, as with /bonus-campaigns/create/*).
      let best = null, bestLen = -1;
      for (const t of tabs) {
        const slug = t[2];
        if (!slug) continue;
        if ((rest === slug || rest.startsWith(slug + "/")) && slug.length > bestLen) { best = t[0]; bestLen = slug.length; }
      }
      if (best !== null) return best;
    }
    return null;
  };

  const [tab, setTabState] = React.useState(() => {
    // Nullish, not falsy — a resolved tab id can legitimately be 0 (e.g. a
    // numeric step index), which `||` would wrongly discard in favor of
    // defaultTab even though it's already the correct value.
    try { const r = resolve(window.location.pathname); return r !== null ? r : defaultTab; } catch (_e) { return defaultTab; }
  });

  const setTab = (id) => {
    setTabState(id);
    try {
      const hit = tabs.find(t => t[0] === id);
      const path = hit && hit[2] ? `${basePath}/${hit[2]}` : basePath;
      if (window.location.pathname !== path) window.history.pushState({ tab: id }, "", path);
    } catch (_e) {}
  };

  React.useEffect(() => {
    const onPopState = () => {
      try {
        const next = resolve(window.location.pathname);
        if (next !== null) setTabState(next);
      } catch (_e) {}
    };
    window.addEventListener("popstate", onPopState);
    return () => window.removeEventListener("popstate", onPopState);
  }, []);

  return [tab, setTab];
};
window.useUrlTab = useUrlTab;
