/* global React */
/* Mobile-only shell components: bottom tab bar, FAB, install hint.
   Rendered conditionally by App when window.innerWidth <= 768. */

// Hook: track whether we're under the mobile breakpoint.
// A phone in landscape is wider than `breakpoint`, so width alone would flip it
// to the desktop layout (and the desktop chart overflows — issue #7). We also
// treat a short viewport (<=480px tall) as mobile so phones stay in the mobile
// shell in either orientation. This mirrors the CSS media query exactly:
//   @media (max-width: 768px), (max-height: 480px)
const isMobileViewport = (breakpoint = 768) => {
  if (typeof window === 'undefined') return false;
  return window.innerWidth <= breakpoint || window.innerHeight <= 480;
};

const useIsMobile = (breakpoint = 768) => {
  const [isMobile, setIsMobile] = useState(() => isMobileViewport(breakpoint));
  useEffect(() => {
    const sync = () => setIsMobile(isMobileViewport(breakpoint));
    window.addEventListener('resize', sync);
    window.addEventListener('orientationchange', sync);
    document.body.classList.toggle('is-mobile', isMobileViewport(breakpoint));
    return () => {
      window.removeEventListener('resize', sync);
      window.removeEventListener('orientationchange', sync);
    };
  }, [breakpoint]);
  useEffect(() => {
    document.body.classList.toggle('is-mobile', isMobile);
  }, [isMobile]);
  return isMobile;
};

// Bottom tab bar — 4 primary pages + overflow chip for "Daha".
// Renders fixed to the bottom of the viewport. Tap targets are 56px tall.
const MobileBottomNav = ({ page, setPage, alertCount }) => {
  const [moreOpen, setMoreOpen] = useState(false);
  const PRIMARY = [
    { id: 'overview',  label: 'Bakış',  icon: '◐' },
    { id: 'reporting', label: 'Rapor',  icon: '◰' },
    { id: 'pricing',   label: 'Fiyat',  icon: '€' },
    { id: 'alerts',    label: 'Uyarı',  icon: '!' },
  ];
  const SECONDARY = [
    { id: 'briefing', label: 'Brifing' },
    { id: 'scenario', label: 'Senaryo' },
    { id: 'forecast', label: 'Tahmin' },
    { id: 'budget',   label: 'Bütçe' },
    { id: 'compset',  label: 'Rakip' },
    { id: 'flights',  label: 'Uçuş' },
    { id: 'channels', label: 'Kanal' },
  ];
  const isSecondary = SECONDARY.some(s => s.id === page);

  return React.createElement(React.Fragment, null,
    moreOpen && React.createElement('div', {
      className: 'm-sheet-backdrop',
      onClick: () => setMoreOpen(false)
    },
      React.createElement('div', { className: 'm-sheet', onClick: e => e.stopPropagation() },
        React.createElement('div', { className: 'm-sheet-handle' }),
        React.createElement('div', { className: 'm-sheet-title' }, 'Diğer Sayfalar'),
        React.createElement('div', { className: 'm-sheet-grid' },
          SECONDARY.map(s => React.createElement('div', {
            key: s.id,
            className: 'm-sheet-item' + (page === s.id ? ' active' : ''),
            onClick: () => { setPage(s.id); setMoreOpen(false); }
          }, s.label))
        )
      )
    ),
    React.createElement('nav', { className: 'm-tabbar' },
      PRIMARY.map(t => React.createElement('button', {
        key: t.id,
        className: 'm-tab' + (page === t.id ? ' active' : ''),
        onClick: () => setPage(t.id)
      },
        React.createElement('span', { className: 'm-tab-icon' }, t.icon),
        React.createElement('span', { className: 'm-tab-label' }, t.label),
        t.id === 'alerts' && alertCount > 0 && React.createElement('span', {
          className: 'm-tab-badge'
        }, alertCount > 99 ? '99+' : String(alertCount))
      )),
      React.createElement('button', {
        className: 'm-tab' + (isSecondary ? ' active' : ''),
        onClick: () => setMoreOpen(true)
      },
        React.createElement('span', { className: 'm-tab-icon' }, '⋯'),
        React.createElement('span', { className: 'm-tab-label' }, 'Daha')
      )
    )
  );
};

// Floating action button — opens Copilot. Hidden when Copilot is already open.
const MobileCopilotFAB = ({ open, onToggle }) => {
  if (open) return null;
  return React.createElement('button', {
    className: 'm-fab',
    onClick: onToggle,
    'aria-label': 'Copilot\'u aç'
  },
    React.createElement('span', { className: 'm-fab-glyph' }, '✦'),
    React.createElement('span', { className: 'm-fab-label' }, 'Copilot')
  );
};

// First-visit hint inviting "Add to Home Screen" on iOS Safari.
// Dismissable, persists dismissal in localStorage.
const MobileInstallHint = () => {
  const [show, setShow] = useState(false);
  useEffect(() => {
    if (typeof window === 'undefined') return;
    const dismissed = localStorage.getItem('fs_install_dismissed');
    const standalone = window.matchMedia('(display-mode: standalone)').matches
                       || window.navigator.standalone === true;
    const isIOS = /iPad|iPhone|iPod/.test(window.navigator.userAgent);
    if (!dismissed && !standalone && isIOS) {
      const t = setTimeout(() => setShow(true), 2200);
      return () => clearTimeout(t);
    }
  }, []);
  const dismiss = () => {
    localStorage.setItem('fs_install_dismissed', '1');
    setShow(false);
  };
  if (!show) return null;
  return React.createElement('div', { className: 'm-install-hint' },
    React.createElement('div', { className: 'm-install-text' },
      React.createElement('div', { className: 'm-install-title' }, 'Ana ekrana ekle'),
      React.createElement('div', { className: 'm-install-body' },
        'Bu sayfayı bir uygulama gibi açmak için Safari\'de ',
        React.createElement('strong', null, 'Paylaş'),
        ' › ',
        React.createElement('strong', null, 'Ana Ekrana Ekle'),
        '.'
      )
    ),
    React.createElement('button', { className: 'm-install-dismiss', onClick: dismiss }, '×')
  );
};

// Compact mobile header: brand on left, page title, action icons on right.
// Replaces the desktop masthead + topbar on phones.
const PAGE_TITLES = {
  briefing:  'Günlük Brifing',
  overview:  'Genel Bakış',
  reporting: 'Raporlama',
  pricing:   'Fiyat Önerileri',
  scenario:  'Senaryo Simülasyonu',
  forecast:  'Tahmin',
  compset:   'Rakip Seti',
  flights:   'Uçuşlar',
  budget:    'Bütçe vs Gerçekleşen',
  alerts:    'Uyarılar',
  channels:  'Kanallar',
};

const MobileHeader = ({ page, alertCount, onSearch }) => {
  return React.createElement('header', { className: 'm-header' },
    React.createElement('div', { className: 'm-header-brand' },
      React.createElement('span', { className: 'm-header-brand-name' },
        'Fun ',
        React.createElement('em', null, '&'),
        ' Sun'
      ),
      React.createElement('span', { className: 'm-header-brand-tag' }, 'GELİR MASASI')
    ),
    React.createElement('div', { className: 'm-header-title' }, PAGE_TITLES[page] || page),
    React.createElement('div', { className: 'm-header-actions' },
      React.createElement('button', {
        className: 'm-icon-btn', onClick: onSearch,
        'aria-label': 'Ara'
      }, '⌕'),
      alertCount > 0 && React.createElement('span', { className: 'm-header-alert-pill' }, alertCount)
    )
  );
};

// On mobile, .tbl tables collapse into stacked cards and the <thead> row is
// hidden — so every value ends up with no label (issues #5, #6, #10). This
// copies each column's header text onto its body cells as data-label; the
// mobile CSS renders that as a small eyebrow above the value. The promoted
// headline cell and the hidden rank cell are skipped. Safe on desktop too:
// the ::before rule only exists inside the mobile media query.
const enhanceTableLabels = (root) => {
  const scope = (root && root.querySelectorAll) ? root : document;
  scope.querySelectorAll('table.tbl').forEach((tbl) => {
    const labels = Array.from(tbl.querySelectorAll('thead th'))
      .map((th) => (th.textContent || '').trim());
    if (!labels.length) return;
    tbl.querySelectorAll('tbody tr').forEach((tr) => {
      const cells = Array.from(tr.children).filter((el) => el.tagName === 'TD');
      if (!cells.length) return;
      const first = cells[0];
      const isRank = first.classList.contains('text-faint')
        && first.classList.contains('mono')
        && !first.classList.contains('num');
      const headlineIdx = isRank ? 1 : 0;
      cells.forEach((td, i) => {
        if (i === headlineIdx || (isRank && i === 0)) {
          td.removeAttribute('data-label');
          return;
        }
        const lbl = labels[i];
        if (lbl) td.setAttribute('data-label', lbl);
        else td.removeAttribute('data-label');
      });
    });
  });
};

// enhanceTableLabels must re-run whenever table rows change. Some tables live
// in components with their own state (e.g. reporting's HotelView star/region/
// search filters) that re-render WITHOUT re-rendering App — so an App-level
// effect misses them and their cards stay unlabeled (reporting "Otel" section).
// A MutationObserver on the app root re-applies labels on any DOM change,
// debounced via rAF. Setting data-label is an attribute write, which a
// childList/subtree observer does not see, so there's no feedback loop.
let __tblObserver = null;
const observeTableLabels = (root) => {
  const target = (root && root.nodeType) ? root : document.body;
  if (__tblObserver) __tblObserver.disconnect();
  let queued = false;
  const flush = () => { queued = false; enhanceTableLabels(document); };
  __tblObserver = new MutationObserver(() => {
    if (queued) return;
    queued = true;
    (window.requestAnimationFrame || window.setTimeout)(flush);
  });
  __tblObserver.observe(target, { childList: true, subtree: true });
  enhanceTableLabels(document);
};

window.useIsMobile = useIsMobile;
window.enhanceTableLabels = enhanceTableLabels;
window.observeTableLabels = observeTableLabels;
window.MobileBottomNav = MobileBottomNav;
window.MobileCopilotFAB = MobileCopilotFAB;
window.MobileInstallHint = MobileInstallHint;
window.MobileHeader = MobileHeader;
