// daygig-nav.js — Navigation: collapsible groups, profile-aware modules, showTab, welcomeBanner

// ── Navigation ────────────────────────────────────────────────────────────
// Map each tab to its parent group so clicking a tab auto-opens its group.
const _tabGroup = {
  transactions:'money', receipts:'money', accounting:'money', reports:'money',
  jobs:'jobs', estimates:'jobs', invoices:'jobs', subcontractors:'jobs',
  properties:'rentals', leases:'rentals', rentroll:'rentals', propertypnl:'rentals', schedulee:'rentals',
  strbookings:'rentals', reserves:'rentals',
  products:'catalog', materials:'catalog',
  sales:'sales',
  projects:'work',
  compliance:'compliance',
};

const _allGroups = ['money','jobs','rentals','catalog','sales','work','compliance'];

// Tabs that should be hidden when their matching module flag is disabled.
const _moduleControlledTabs = {
  receipts: 'enable_receipts',
  products: 'enable_inventory',
  materials: 'enable_materials',
  sales: 'enable_inventory',
  projects: 'enable_campaigns',
  compliance: 'enable_deadlines',
};

let _daygigNavProfile = 'business';
let _daygigNavSettings = {};
let _daygigNavClicksBound = false;

function toggleNavGroup(name) {
  const grp = document.getElementById('navg-' + name);
  if (!grp || grp.classList.contains('dg-hidden-by-profile')) return;
  const isOpen = grp.classList.contains('open');
  // Close all groups
  _allGroups.forEach(g => {
    const el = document.getElementById('navg-' + g);
    if (el) el.classList.remove('open');
  });
  // Toggle the clicked one
  if (!isOpen) grp.classList.add('open');
}

function openNavGroup(name) {
  _allGroups.forEach(g => {
    const el = document.getElementById('navg-' + g);
    if (el) el.classList.remove('open');
  });
  const grp = document.getElementById('navg-' + name);
  if (grp && !grp.classList.contains('dg-hidden-by-profile')) grp.classList.add('open');
}

async function initNav() {
  sanitizeNavLabels();
  _daygigNavSettings = await loadDaygigNavSettings();
  _daygigNavProfile = (_daygigNavSettings.user_profile || 'business').toLowerCase();
  applyProfileNavVisibility(_daygigNavSettings);

  bindNavClicks();

  // If the currently active panel is now hidden by profile/module settings,
  // fall back to dashboard so the app never opens to a blank/disabled area.
  const activePanel = document.querySelector('.panel.active');
  const activeTab = activePanel ? activePanel.id.replace(/^panel-/, '') : '';
  if (activeTab && !isTabAllowed(activeTab)) showTab('dashboard');

  // Task 24: Re-sync the topbar title to the actually-active panel.
  // applyPersonalReportTabs() may call rptTab() which can trigger showTab('reports'),
  // leaving the topbar showing "Spending Reports" while the dashboard button is highlighted.
  const syncPanel = document.querySelector('.panel.active');
  const syncTab = syncPanel ? syncPanel.id.replace(/^panel-/, '') : 'dashboard';
  const _bTitles = { dashboard:'Dashboard', settings:'Settings', transactions:'Transactions', accounting:'Accounting', materials:'Materials', compliance:'Compliance', reports:'Reports', products:'Products', sales:'Sales', projects:'Projects', receipts:'Receipts' };
  const _pTitles = { dashboard:'Overview', settings:'Settings', transactions:'Transactions', accounting:'Books', reports:'Spending Reports', receipts:'Receipts' };
  const _tMap = _daygigNavProfile === 'personal' ? { ..._bTitles, ..._pTitles } : _bTitles;
  const navTitleEl = document.getElementById('topbarTitle');
  if (navTitleEl) navTitleEl.textContent = _tMap[syncTab] || cap(syncTab);
}

function bindNavClicks() {
  if (_daygigNavClicksBound) return;
  document.addEventListener('click', (event) => {
    const btn = event.target.closest('.nav-btn:not(.disabled)');
    if (!btn) return;
    if (btn.getAttribute('onclick')) return;
    event.preventDefault();
    showTab(btn.dataset.tab, btn.dataset);
  });
  _daygigNavClicksBound = true;
}

async function loadDaygigNavSettings() {
  // Most robust path: let the HTML template define window.DAYGIG_SETTINGS.
  // This works even if there is no settings API yet.
  if (window.DAYGIG_SETTINGS && typeof window.DAYGIG_SETTINGS === 'object') {
    return normalizeSettings(window.DAYGIG_SETTINGS);
  }

  // Fallbacks for likely future/current API names. If neither exists, the nav
  // stays fully enabled as a business setup so legacy pages keep working.
  const urls = ['/api/settings', '/api/setup/settings', '/api/profile'];
  for (const url of urls) {
    try {
      const res = await fetch(url, { headers: { 'Accept': 'application/json' } });
      if (!res.ok) continue;
      const data = await res.json();
      const settings = data.settings || data.profile || data;
      return normalizeSettings(settings);
    } catch (e) {
      // Keep trying fallbacks.
    }
  }
  return normalizeSettings({ user_profile: 'business' });
}

function normalizeSettings(raw) {
  const out = { ...raw };
  const features = String(out.features || '').split(',').map(s => s.trim()).filter(Boolean);

  // Backward compatibility: if older setup only saved the comma-separated
  // features field, derive the newer enable_* flags from it.
  const featureToFlag = {
    campaigns: 'enable_campaigns',
    inventory: 'enable_inventory',
    bom: 'enable_bom',
    materials: 'enable_materials',
    receipts: 'enable_receipts',
    deadlines: 'enable_deadlines',
    shipments: 'enable_shipments',
    personal_budgeting: 'enable_personal_budgeting',
    spending_categories: 'enable_spending_categories',
    subscription_tracking: 'enable_subscription_tracking',
    subscriptions: 'enable_subscription_tracking',
  };
  features.forEach(f => {
    if (featureToFlag[f] && out[featureToFlag[f]] == null) out[featureToFlag[f]] = '1';
  });

  // BOM implies materials, because the Materials area is where BOM inputs live.
  if (truthy(out.enable_bom) && out.enable_materials == null) out.enable_materials = '1';

  return out;
}


function sanitizeNavLabels() {
  // Keep each nav button to exactly one icon span and one label span. This
  // prevents doubled/overlapped sidebar text if older builds or cached scripts
  // left text nodes inside the buttons.
  document.querySelectorAll('.nav-btn').forEach(btn => {
    const icon = btn.querySelector('.ni');
    let label = btn.querySelector('.nav-label');
    if (!label) {
      label = document.createElement('span');
      label.className = 'nav-label';
      label.textContent = btn.dataset.originalLabel || btn.textContent.trim();
      btn.appendChild(label);
    }
    if (!btn.dataset.originalLabel) btn.dataset.originalLabel = label.textContent.trim();
    Array.from(btn.childNodes).forEach(node => {
      if (node.nodeType === Node.TEXT_NODE && node.textContent.trim()) node.textContent = '';
    });
    Array.from(btn.querySelectorAll('span')).forEach(span => {
      if (span !== icon && span !== label) span.remove();
    });
  });
}

function applyProfileNavVisibility(settings = {}) {
  ensureProfileHiddenStyle();
  resetProfileNavVisibility();

  const profile = (settings.user_profile || 'business').toLowerCase();

  // The Rentals group only belongs in landlord mode.
  if (profile !== 'landlord') hideNavGroup('rentals');

  // The Jobs group only belongs in contractor mode.
  if (profile !== 'contractor') hideNavGroup('jobs');

  // Landlord mode: keep money/reports/settings, show Rentals, hide retail ops.
  if (profile === 'landlord') {
    hideNavGroup('catalog');
    hideNavGroup('sales');
    hideNavGroup('work');

    hideTab('products');
    hideTab('materials');
    hideTab('sales');
    hideTab('projects');

    // Compliance (mileage, deadlines) stays available only if its module is on.
    if (settings.enable_deadlines != null && !truthy(settings.enable_deadlines)) hideNavGroup('compliance');

    renameTab('dashboard', 'Dashboard');
    openNavGroup('rentals');
    return;
  }

  // Personal finance mode: keep money/report/settings areas, hide business ops.
  if (profile === 'personal') {
    hideNavGroup('catalog');
    hideNavGroup('sales');
    hideNavGroup('work');
    hideNavGroup('compliance');

    hideTab('products');
    hideTab('materials');
    hideTab('sales');
    hideTab('projects');
    hideTab('compliance');
    // Both the Expenses and Ledger buttons share data-tab="accounting"; renaming
    // them to "Books" produced two identical sidebar items. These are
    // double-entry views, so hide them in personal mode — Transactions + the
    // Overview/Spending Reports cover the personal need.
    hideTab('accounting');
    // Hide the business GAAP statements (P&L, Balance Sheet, Trial Balance) from
    // the Reports panel in personal mode.
    applyPersonalReportTabs();

    renameTab('dashboard', 'Overview');
    renameTab('transactions', 'Transactions');
    renameTab('reports', 'Spending Reports');
    return;
  }

  // Contractor mode: a business variant for home-services trades. Hide the
  // creative/retail-only areas (product catalog, campaigns/events). Keep money,
  // materials/parts, receipts, reports, compliance (mileage/deadlines), and
  // settings. The Jobs / Estimates / Invoices module is layered on in Phase 1.
  if (profile === 'contractor') {
    hideTab('products');     // no product catalog
    hideTab('projects');     // hides Projects / Events / Campaigns (creative work)
    hideNavGroup('work');

    // Materials (parts) stays available for job costing.
    if (truthy(settings.enable_materials)) showTabButton('materials');
    // Compliance (mileage, tax deadlines) only if its module is enabled.
    if (settings.enable_deadlines != null && !truthy(settings.enable_deadlines)) hideNavGroup('compliance');

    renameTab('dashboard', 'Dashboard');
    renameTab('sales', 'Customers & Jobs');
    openNavGroup('jobs');

    _allGroups.forEach(group => {
      const groupEl = document.getElementById('navg-' + group);
      if (!groupEl) return;
      const visibleButtons = groupEl.querySelectorAll('.nav-btn:not(.dg-hidden-by-profile)');
      if (visibleButtons.length === 0) hideNavGroup(group);
    });
    return;
  }

  // Business mode: hide only modules the setup wizard disabled.
  Object.entries(_moduleControlledTabs).forEach(([tab, flag]) => {
    if (settings[flag] != null && !truthy(settings[flag])) hideTab(tab);
  });

  // If Materials is enabled solely through BOM, keep it visible.
  if (truthy(settings.enable_bom) || truthy(settings.enable_materials)) showTabButton('materials');

  // Hide empty groups after individual tab hiding.
  _allGroups.forEach(group => {
    const groupEl = document.getElementById('navg-' + group);
    if (!groupEl) return;
    const visibleButtons = groupEl.querySelectorAll('.nav-btn:not(.dg-hidden-by-profile)');
    if (visibleButtons.length === 0) hideNavGroup(group);
  });
}


function resetProfileNavVisibility() {
  sanitizeNavLabels();
  document.querySelectorAll('.dg-hidden-by-profile').forEach(el => {
    el.classList.remove('dg-hidden-by-profile');
  });
  document.querySelectorAll('.nav-group').forEach(el => {
    el.classList.remove('dg-hidden-by-profile');
  });
  renameTab('dashboard', 'Dashboard');
  renameTab('transactions', 'Transactions');
  renameTab('reports', 'Reports');
  document.querySelectorAll('.nav-btn[data-tab="accounting"]').forEach(btn => {
    const label = btn.querySelector('.nav-label');
    if (label) label.textContent = btn.dataset.acctTarget === 'ledger' ? 'Ledger' : 'Expenses';
  });
}

function isTabAllowed(tab) {
  const btn = document.querySelector(`.nav-btn[data-tab="${tab}"]`);
  return !btn || !btn.classList.contains('dg-hidden-by-profile');
}

function hideNavGroup(group) {
  const el = document.getElementById('navg-' + group);
  if (el) el.classList.add('dg-hidden-by-profile');
}

function hideTab(tab) {
  document.querySelectorAll(`.nav-btn[data-tab="${tab}"]`).forEach(el => {
    el.classList.add('dg-hidden-by-profile');
  });
}

function showTabButton(tab) {
  document.querySelectorAll(`.nav-btn[data-tab="${tab}"]`).forEach(el => {
    el.classList.remove('dg-hidden-by-profile');
  });
}

function renameTab(tab, label) {
  document.querySelectorAll(`.nav-btn[data-tab="${tab}"]`).forEach(btn => {
    const labelEl = btn.querySelector('.nav-label');
    if (labelEl) {
      labelEl.textContent = label;
    } else {
      btn.textContent = label;
    }
  });
}

function applyPersonalReportTabs() {
  // Hide the business GAAP report sub-tabs in personal mode. resetProfileNav-
  // Visibility() clears the dg-hidden-by-profile class for business mode.
  const hide = ['pl', 'balance', 'trial'];
  let firstVisible = null;
  document.querySelectorAll('.rpt-tab').forEach(btn => {
    const r = btn.dataset.rpt;
    if (hide.includes(r)) {
      btn.classList.add('dg-hidden-by-profile');
    } else if (!firstVisible) {
      firstVisible = r;
    }
  });
  // If the currently active sub-tab was just hidden, switch to a visible one.
  if (firstVisible && typeof rptTab === 'function') {
    const active = document.querySelector('.rpt-tab.active');
    if (!active || hide.includes(active.dataset.rpt)) {
      try { rptTab(firstVisible); } catch (e) { /* reports panel not ready yet */ }
    }
  }
}

function ensureProfileHiddenStyle() {
  if (document.getElementById('dg-profile-nav-style')) return;
  const style = document.createElement('style');
  style.id = 'dg-profile-nav-style';
  style.textContent = '.dg-hidden-by-profile{display:none!important;}';
  document.head.appendChild(style);
}

function truthy(v) {
  return ['1','true','yes','on','enabled'].includes(String(v).trim().toLowerCase());
}

function showTab(tab, opts = {}) {
  if (!isTabAllowed(tab)) tab = 'dashboard';

  document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
  document.querySelectorAll('.nav-btn').forEach(b => b.classList.remove('active'));
  const panel = document.getElementById('panel-' + tab);
  if (panel) panel.classList.add('active');

  let selector = `.nav-btn[data-tab="${tab}"]`;
  if (opts.salesTarget) selector += `[data-sales-target="${opts.salesTarget}"]`;
  if (opts.projTarget) selector += `[data-proj-target="${opts.projTarget}"]`;
  if (opts.acctTarget) selector += `[data-acct-target="${opts.acctTarget}"]`;
  if (opts.complianceTarget) selector += `[data-compliance-target="${opts.complianceTarget}"]`;
  const btn = document.querySelector(selector) || document.querySelector(`.nav-btn[data-tab="${tab}"]`);
  if (btn) btn.classList.add('active');

  // Auto-open the parent nav group
  const grp = _tabGroup[tab];
  if (grp) openNavGroup(grp);

  const businessTitles = {
    dashboard:'Dashboard', settings:'Settings', transactions:'Transactions',
    accounting:'Accounting', materials:'Materials', compliance:'Compliance',
    reports:'Reports', products:'Products', sales:'Sales', projects:'Projects',
    jobs:'Jobs', estimates:'Estimates', invoices:'Invoices', subcontractors:'Subcontractors',
    receipts:'Receipts', properties:'Properties', leases:'Tenants & Leases',
    rentroll:'Rent Roll', propertypnl:'Property P&L', schedulee:'Schedule E & Taxes',
    strbookings:'STR Bookings', reserves:'Reserves & Draws',
  };
  const personalTitles = {
    dashboard:'Overview', settings:'Settings', transactions:'Transactions',
    accounting:'Books', reports:'Spending Reports', receipts:'Receipts',
  };
  const titles = _daygigNavProfile === 'personal' ? { ...businessTitles, ...personalTitles } : businessTitles;
  const titleEl = document.getElementById('topbarTitle');
  if (titleEl) titleEl.textContent = titles[tab] || cap(tab);
  // Task 30: for accounting sub-tabs, show "Expenses" or "Ledger" instead of generic "Accounting"
  if (tab === 'accounting' && opts.acctTarget && titleEl) {
    const acctLabels = { expenses: 'Expenses', ledger: 'Ledger' };
    if (acctLabels[opts.acctTarget]) titleEl.textContent = acctLabels[opts.acctTarget];
  }

  // Tab-specific on-open actions. Guard every module call so disabling or
  // omitting a feature does not throw a runtime error.
  if (tab === 'transactions' && typeof window.recLoadSavedMappings === 'function' && typeof window.txnTab === 'function') {
    window.recLoadSavedMappings(); window.txnTab('import');
  }
  if (tab === 'projects' && typeof window.projTab === 'function')         { window.projTab(opts.projTarget || 'overview'); }
  if (tab === 'sales' && typeof window.salesTab === 'function')           { window.salesTab(opts.salesTarget || 'orders'); }
  if (tab === 'jobs' && typeof window.jobsLoad === 'function')            { window.jobsLoad(); }
  if (tab === 'estimates' && typeof window.docLoad === 'function')        { window.docLoad('estimate'); }
  if (tab === 'invoices' && typeof window.docLoad === 'function')         { window.docLoad('invoice'); }
  if (tab === 'subcontractors' && typeof window.subsLoad === 'function')  { window.subsLoad(); window.subs1099(); }
  // Task 27: in personal mode open the first visible sub-tab, not P&L
  if (tab === 'reports' && typeof window.rptTab === 'function') {
    if (_daygigNavProfile === 'personal') {
      const firstVis = Array.from(document.querySelectorAll('.rpt-tab:not(.dg-hidden-by-profile)')).find(el => el.dataset && el.dataset.rpt);
      window.rptTab(firstVis ? firstVis.dataset.rpt : 'spending');
    } else {
      window.rptTab('pl');
    }
  }
  if (tab === 'products' && typeof window.prodSubTab === 'function')      { window.prodSubTab('list'); }
  if (tab === 'materials' && typeof window.materialsLoad === 'function')  { window.materialsLoad(); }
  if (tab === 'receipts' && typeof window.rcpReset === 'function')        { window.rcpReset(); }
  if (tab === 'accounting' && typeof window.acctTab === 'function')       { window.acctTab(opts.acctTarget || 'ledger'); }
  if (tab === 'compliance' && typeof window.complianceTab === 'function') { window.complianceTab(opts.complianceTarget || 'deadlines'); }
  if (tab === 'settings'   && typeof window.loadBackupPanel === 'function') { window.loadBackupPanel(); }
  if (tab === 'properties' && typeof window.llLoadProperties === 'function') { window.llLoadProperties(); }
  if (tab === 'leases'     && typeof window.llLoadLeasesPanel === 'function') { window.llLoadLeasesPanel(); }
  if (tab === 'rentroll'   && typeof window.llLoadRentRoll === 'function')    { window.llLoadRentRoll(); }
  if (tab === 'schedulee'  && typeof window.llLoadScheduleE === 'function')   { window.llLoadScheduleE(); }
  if (tab === 'propertypnl' && typeof window.llLoadPropertyPnl === 'function') { window.llLoadPropertyPnl(); }
  if (tab === 'strbookings' && typeof window.llLoadStrBookings === 'function') { window.llLoadStrBookings(); }
  if (tab === 'reserves'   && typeof window.llLoadReserves === 'function')     { window.llLoadReserves(); }
}

// ── Welcome banner ────────────────────────────────────────────────────────
function initWelcomeBanner() {
  const dismissed = localStorage.getItem('daygig_welcome_dismissed');
  const banner = document.getElementById('welcomeBanner');
  if (dismissed && banner) {
    banner.style.display = 'none';
  }
}

function dismissWelcome() {
  localStorage.setItem('daygig_welcome_dismissed', '1');
  const banner = document.getElementById('welcomeBanner');
  if (!banner) return;
  banner.style.opacity = '0';
  banner.style.transition = 'opacity .3s';
  setTimeout(() => banner.style.display = 'none', 300);
}

// ── Reconnect ─────────────────────────────────────────────────────────────
async function dgReconnect() {
  const btn = document.getElementById('reconnectBtn');
  const dot = document.getElementById('healthDot');
  const lbl = document.getElementById('healthLabel');
  if (btn) btn.textContent = '↺ Reconnecting…';
  if (dot) { dot.className = 'health-dot'; }
  if (lbl) lbl.textContent = 'Connecting…';
  try {
    const res = await fetch('/api/health');
    const data = await res.json();
    if (data.ok) {
      if (dot) dot.className = 'health-dot ok';
      if (lbl) lbl.textContent = 'Connected';
      if (btn) btn.style.display = 'none';
      const logo = document.getElementById('brandLogo');
      if (logo) { logo.classList.remove('logo-disconnected'); logo.classList.add('logo-connected'); }
    } else {
      throw new Error('unhealthy');
    }
  } catch(e) {
    if (dot) dot.className = 'health-dot err';
    if (lbl) lbl.textContent = 'Disconnected';
    if (btn) { btn.style.display = 'block'; btn.textContent = '↺ Reconnect'; }
    const logo = document.getElementById('brandLogo');
    if (logo) { logo.classList.remove('logo-connected'); logo.classList.add('logo-disconnected'); }
  }
}

Object.assign(window, {
  toggleNavGroup,
  openNavGroup,
  initNav,
  showTab,
  initWelcomeBanner,
  dismissWelcome,
  dgReconnect,
});

bindNavClicks();
