// Main app: layout shell (top bar + left nav) and routing

function VeraCamLogo({ size = 22 }) {
  return (
    <div className="inline-flex items-center gap-2.5">
      <svg width={size} height={size} viewBox="0 0 32 32" fill="none" aria-hidden="true">
        <rect x="2" y="6" width="20" height="20" rx="3" stroke="#38a169" strokeWidth="2" />
        <circle cx="12" cy="16" r="5" stroke="#38a169" strokeWidth="2" />
        <circle cx="12" cy="16" r="2" fill="#38a169" />
        <path d="M22 12l8-4v16l-8-4z" stroke="#38a169" strokeWidth="2" strokeLinejoin="round" />
      </svg>
      <div className="leading-none">
        <div className="font-display font-bold text-slate-100 tracking-tight" style={{ fontSize: size * 0.85 }}>VeraCam</div>
      </div>
    </div>
  );
}

function NavItem({ icon: Icon, label, active, badge, onClick, stubbed }) {
  return (
    <button
      onClick={onClick}
      className={`w-full text-left px-3 py-2 rounded-md flex items-center gap-3 transition-all group relative ${
        active
          ? 'bg-forest-500/15 text-forest-300 border border-forest-500/30'
          : 'text-slate-300 hover:bg-slate-850 hover:text-slate-100 border border-transparent'
      }`}
    >
      {active && <span className="absolute inset-y-2 left-0 w-0.5 bg-forest-500 rounded-r-full" />}
      <Icon size={16} className={active ? 'text-forest-400' : 'text-slate-400 group-hover:text-slate-200'} />
      <span className="text-[13px] font-medium truncate flex-1">{label}</span>
      {badge !== undefined && badge !== 0 && (
        <span className={`text-[10px] font-mono px-1.5 py-0.5 rounded ${
          active ? 'bg-forest-500/30 text-forest-200' : 'bg-red-500/20 text-red-300'
        }`}>{badge}</span>
      )}
      {stubbed && !active && (
        <span className="text-[9px] uppercase tracking-wider text-slate-500 font-medium">stub</span>
      )}
    </button>
  );
}

function SiteSelector({ value, onChange }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    function onClick(e) { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, []);
  const current = value ? lookupSite(value) : null;
  const { t } = useI18n();

  return (
    <div ref={ref} className="relative">
      <button
        onClick={() => setOpen((o) => !o)}
        className="h-9 px-3 inline-flex items-center gap-2.5 bg-slate-850 hover:bg-slate-800 border border-slate-700 rounded transition-colors"
      >
        <Icons.Building size={15} className="text-slate-400" />
        <div className="text-left">
          <div className="text-[10px] uppercase tracking-wider text-slate-500 leading-none">Instalação</div>
          <div className="text-[13px] font-medium text-slate-100 leading-tight mt-0.5">
            {current ? current.short : t('topbar.allSites')}
          </div>
        </div>
        <Icons.ChevronDown size={14} className="text-slate-400" />
      </button>
      {open && (
        <div className="absolute z-50 mt-1 left-0 min-w-[280px] bg-navy-900 border border-slate-700 rounded shadow-xl py-1 animate-fadeIn">
          <button
            onClick={() => { onChange(null); setOpen(false); }}
            className={`w-full text-left px-3 py-2 hover:bg-slate-800 flex items-center justify-between ${!value ? 'text-forest-400' : 'text-slate-200'}`}
          >
            <div>
              <div className="text-[13px] font-medium">{t('topbar.allSites')}</div>
              <div className="text-[10px] text-slate-500">Vista consolidada · {CAMERAS.length} câmaras</div>
            </div>
            {!value && <Icons.Check size={13} />}
          </button>
          <div className="border-t border-slate-800 my-1" />
          {SITES.map((s) => {
            const cams = CAMERAS.filter((c) => c.site_id === s.id);
            const online = cams.filter((c) => c.status === 'online').length;
            return (
              <button
                key={s.id}
                onClick={() => { onChange(s.id); setOpen(false); }}
                className={`w-full text-left px-3 py-2 hover:bg-slate-800 flex items-start justify-between gap-3 ${value === s.id ? 'text-forest-400' : 'text-slate-200'}`}
              >
                <div className="min-w-0">
                  <div className="text-[13px] font-medium truncate">{s.name}</div>
                  <div className="text-[10px] text-slate-500 truncate">{s.address} · {online}/{cams.length} câmaras</div>
                </div>
                {value === s.id && <Icons.Check size={13} className="shrink-0 mt-0.5" />}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

function HealthPill({ siteId }) {
  const { t } = useI18n();
  const cams = siteId ? CAMERAS.filter((c) => c.site_id === siteId) : CAMERAS;
  const online = cams.filter((c) => c.status === 'online').length;
  const total = cams.length;
  const sites = siteId ? 1 : SITES.length;
  const healthy = online === total;
  const degraded = cams.some((c) => c.status === 'degraded');
  const offline = cams.some((c) => c.status === 'offline');

  return (
    <div className="hidden md:flex items-center gap-2 h-9 px-3 bg-slate-850 border border-slate-700 rounded">
      <span className={`w-1.5 h-1.5 rounded-full ${healthy ? 'bg-forest-500' : offline ? 'bg-red-500' : 'bg-amber-500'} animate-pulseDot`} />
      <div className="text-[11px] text-slate-300 leading-tight font-mono">
        <div className="flex items-center gap-1.5">
          <Icons.Video size={11} />
          <span>{online}/{total} {t('topbar.health.cameras')}</span>
        </div>
        <div className="flex items-center gap-1.5 text-slate-400 mt-0.5">
          <Icons.Bolt size={11} />
          <span>{sites}/{sites} {t('topbar.health.nodes')}</span>
        </div>
      </div>
    </div>
  );
}

function LangToggle() {
  const { lang, setLang } = useI18n();
  return (
    <div className="h-9 inline-flex items-center bg-slate-850 border border-slate-700 rounded overflow-hidden text-[11px] font-mono font-medium">
      {['pt-PT', 'EN'].map((l) => (
        <button
          key={l}
          onClick={() => setLang(l)}
          className={`h-full px-2.5 transition-colors ${lang === l ? 'bg-forest-600 text-white' : 'text-slate-400 hover:text-slate-200'}`}
        >
          {l === 'pt-PT' ? 'PT' : 'EN'}
        </button>
      ))}
    </div>
  );
}

function Clock() {
  const [now, setNow] = React.useState(new Date());
  React.useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  return (
    <div className="hidden lg:block text-right leading-tight">
      <div className="font-mono text-[15px] text-slate-100 tabular-nums">
        {now.toLocaleTimeString('pt-PT', { hour: '2-digit', minute: '2-digit', second: '2-digit' })}
      </div>
      <div className="text-[10px] text-slate-500 font-mono uppercase tracking-wider">
        {now.toLocaleDateString('pt-PT', { weekday: 'short', day: '2-digit', month: 'short' })} · Africa/Luanda
      </div>
    </div>
  );
}

function OperatorChip() {
  const { t } = useI18n();
  // Mock-mode: Mário Quitumba, the security operator. Live mode has no auth
  // yet, so fall back to whatever identity exists, or a placeholder.
  const me = IDENTITIES[2] || IDENTITIES[0]
    || { name: 'Operador', initials: 'OP', role: '' };
  return (
    <button className="h-9 inline-flex items-center gap-2.5 pl-1.5 pr-3 bg-slate-850 hover:bg-slate-800 border border-slate-700 rounded transition-colors">
      <IdentityAvatar identity={me} size={26} />
      <div className="text-left">
        <div className="text-[10px] uppercase tracking-wider text-slate-500 leading-none">{t('topbar.operator')}</div>
        <div className="text-[12px] font-medium text-slate-100 leading-tight mt-0.5">{me.name.split(' ')[0]} {me.name.split(' ')[1]?.[0]}.</div>
      </div>
      <Icons.ChevronDown size={13} className="text-slate-500" />
    </button>
  );
}

function App() {
  const { t } = useI18n();
  // The URL hash names the screen (#compliance), so a view can be linked to.
  const [route, setRoute] = React.useState(() => window.location.hash.slice(1) || 'monitoring');
  React.useEffect(() => { history.replaceState(null, '', `#${route}`); }, [route]);
  const [siteId, setSiteId] = React.useState(null);
  const [findAgainTrack, setFindAgainTrack] = React.useState(null);

  // KPI count for nav badges
  const liveAlerts = EVENTS.filter((e) => e.severity === 'critical' || e.severity === 'high').length;

  const navOps = [
    { id: 'onboarding', label: t('nav.onboarding'), icon: Icons.Home, stubbed: true },
    { id: 'monitoring', label: t('nav.monitoring'), icon: Icons.Video, badge: liveAlerts },
    { id: 'search', label: t('nav.search'), icon: Icons.Search },
  ];
  const navAdmin = [
    { id: 'zones', label: t('nav.zones'), icon: Icons.Polygon, stubbed: true },
    { id: 'rules', label: t('nav.rules'), icon: Icons.Bell, stubbed: true },
    { id: 'identities', label: t('nav.identities'), icon: Icons.Users, stubbed: true },
    { id: 'compliance', label: t('nav.compliance'), icon: Icons.Shield },
  ];

  function goSearch(track) {
    setFindAgainTrack(track);
    setRoute('search');
  }

  return (
    <div className="h-screen flex flex-col bg-navy-950 overflow-hidden">
      {/* Top bar */}
      <header className="h-14 shrink-0 bg-navy-900/80 backdrop-blur-sm border-b border-slate-800/70 flex items-center justify-between px-4 gap-3">
        <div className="flex items-center gap-4">
          <VeraCamLogo />
          <span className="hidden xl:block text-[11px] text-slate-500 italic border-l border-slate-700 pl-3">
            {t('app.tagline')}
          </span>
        </div>
        <div className="flex items-center gap-2">
          <SiteSelector value={siteId} onChange={setSiteId} />
          <HealthPill siteId={siteId} />
          <Clock />
          <LangToggle />
          <div className="hidden sm:block w-px h-6 bg-slate-700/60 mx-1" />
          <IconButton icon={Icons.Bell} label="Notificações" />
          <OperatorChip />
        </div>
      </header>

      {/* Body */}
      <div className="flex-1 min-h-0 flex">
        {/* Left rail */}
        <aside className="w-52 shrink-0 bg-navy-900/40 border-r border-slate-800/70 flex flex-col">
          <nav className="flex-1 overflow-y-auto p-2.5 space-y-3">
            <div>
              <div className="text-[9px] uppercase tracking-[0.14em] text-slate-500 font-semibold px-2.5 pb-1.5">{t('nav.section.live')}</div>
              <div className="space-y-0.5">
                {navOps.map((n) => (
                  <NavItem
                    key={n.id}
                    icon={n.icon}
                    label={n.label}
                    active={route === n.id}
                    badge={n.badge}
                    stubbed={n.stubbed}
                    onClick={() => setRoute(n.id)}
                  />
                ))}
              </div>
            </div>
            <div>
              <div className="text-[9px] uppercase tracking-[0.14em] text-slate-500 font-semibold px-2.5 pb-1.5">{t('nav.section.admin')}</div>
              <div className="space-y-0.5">
                {navAdmin.map((n) => (
                  <NavItem
                    key={n.id}
                    icon={n.icon}
                    label={n.label}
                    active={route === n.id}
                    stubbed={n.stubbed}
                    onClick={() => setRoute(n.id)}
                  />
                ))}
              </div>
            </div>
          </nav>
          {/* Footer — compliance + edge status */}
          <div className="p-3 border-t border-slate-800/70 space-y-2">
            <div className="bg-slate-850/40 border border-slate-700/50 rounded p-2.5 text-[10px]">
              <div className="flex items-center gap-1.5 text-forest-400 font-medium">
                <Icons.Shield size={12} />
                <span className="uppercase tracking-wider">{t('compliance.law')}</span>
              </div>
              <p className="text-slate-400 mt-1 leading-snug">
                Retenção · consentimento · auditoria activos.
              </p>
            </div>
            <div className="flex items-center justify-between text-[10px] font-mono text-slate-500">
              <span className="inline-flex items-center gap-1.5">
                <span className="w-1.5 h-1.5 rounded-full bg-forest-500 animate-pulseDot" />
                edge online
              </span>
              <span>v0.8.4</span>
            </div>
          </div>
        </aside>

        {/* Main */}
        <main className="flex-1 min-w-0 overflow-hidden bg-navy-950" data-screen-label={route}>
          {route === 'monitoring' && <MonitoringView siteId={siteId} onFindAgain={goSearch} />}
          {route === 'search' && <SearchView initialFindAgainTrack={findAgainTrack} />}
          {route === 'onboarding' && <OnboardingView />}
          {route === 'zones' && <ZoneEditorView />}
          {route === 'rules' && <AlertRulesView />}
          {route === 'identities' && <IdentitiesView />}
          {route === 'compliance' && <GovernanceView />}
        </main>
      </div>
    </div>
  );
}

function Root() {
  return (
    <I18nProvider>
      <App />
    </I18nProvider>
  );
}

// Wait for the live-data layer (if configured) so the first render already
// shows API rows; resolves immediately in mock mode.
(window.VERACAM_DATA_READY || Promise.resolve()).then(() => {
  ReactDOM.createRoot(document.getElementById('root')).render(<Root />);
});
