import React from 'react';
import { useEffect, useState } from 'react';
import {
  LayoutDashboard,
  Archive,
  RotateCcw,
  Clock,
  Cloud,
  Bell,
  ScrollText,
  Settings as SettingsIcon,
  ShieldCheck,
  Activity,
  Send,
  Menu as MenuIcon,
  X as XIcon,
} from 'lucide-react';
import { cn } from '@/lib/cn';
import { bk } from '@/lib/api';
import type { PageKey } from '@/App';
import { MaintenanceBadge } from './MaintenanceBadge';
import { __ } from '@/lib/i18n';

// Build the nav inside the component so __() evaluates at render time —
// running it at module-load can race against wp.i18n initialization and
// freeze labels in English even after translations load.
const navIcons: Record<PageKey, React.ComponentType<{ className?: string }>> = {
  dashboard:     LayoutDashboard,
  backups:       Archive,
  restore:       RotateCcw,
  schedule:      Clock,
  destinations:  Cloud,
  notifications: Bell,
  migrate:       Send,
  logs:          ScrollText,
  system:        Activity,
  settings:      SettingsIcon,
};

export function Layout({
  page,
  setPage,
  children,
}: {
  page: PageKey;
  setPage: (k: PageKey) => void;
  children: React.ReactNode;
}) {
  // Translated nav labels. Re-evaluates each render so changes to wp.i18n
  // (e.g. async translation loads) are picked up on the next state change.
  const nav: { key: PageKey; label: string; icon: React.ComponentType<{ className?: string }> }[] = [
    { key: 'dashboard',     label: __( 'Dashboard' ),     icon: navIcons.dashboard },
    { key: 'backups',       label: __( 'Backups' ),       icon: navIcons.backups },
    { key: 'restore',       label: __( 'Restore' ),       icon: navIcons.restore },
    { key: 'migrate',       label: __( 'Migrate' ),       icon: navIcons.migrate },
    { key: 'schedule',      label: __( 'Schedule' ),      icon: navIcons.schedule },
    { key: 'destinations',  label: __( 'Destinations' ),  icon: navIcons.destinations },
    { key: 'notifications', label: __( 'Notifications' ), icon: navIcons.notifications },
    { key: 'logs',          label: __( 'Logs' ),          icon: navIcons.logs },
    { key: 'system',        label: __( 'System' ),        icon: navIcons.system },
    { key: 'settings',      label: __( 'Settings' ),      icon: navIcons.settings },
  ];

  const current = nav.find((n) => n.key === page)!;
  const [mobileOpen, setMobileOpen] = useState(false);

  // Read WordPress's actual admin-bar height once + on resize, expose as a CSS var
  // so the fixed header sits perfectly below it regardless of viewport breakpoint
  // or whether the user hid the bar entirely.
  useEffect(() => {
    const update = () => {
      const bar = document.getElementById('wpadminbar') as HTMLElement | null;
      const root = document.getElementById('backreload-root') as HTMLElement | null;
      const h = bar ? bar.offsetHeight : 0;
      if (root) root.style.setProperty('--backreload-admin-bar-h', h + 'px');
    };
    update();
    window.addEventListener('resize', update);
    return () => window.removeEventListener('resize', update);
  }, []);

  return (
    <div className="flex min-h-[calc(100vh-32px)] relative">
      {/* Mobile backdrop */}
      {mobileOpen && (
        <div
          className="lg:hidden fixed inset-0 z-40 bg-ink-900/30 backdrop-blur-sm"
          onClick={() => setMobileOpen(false)}
        />
      )}

      {/* Sidebar */}
      <aside
        className={cn(
          'bg-white border-r border-ink-200 flex flex-col shrink-0',
          // Mobile: fixed offcanvas; Desktop: in flow
          'fixed lg:static inset-y-0 left-0 z-50 w-64 transition-transform',
          mobileOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0',
        )}
      >
        <div className="px-5 h-14 flex items-center justify-between gap-2.5 border-b border-ink-100">
          {/* Brand mark — wordmark logo served from assets/logo.svg (URL
              localized into bk.logoUrl by class-admin.php). We size by
              HEIGHT (h-7, 28px) and let width auto so the ~7:1 viewBox
              stays in proportion no matter how the file is re-exported.
              The version number lives at the bottom of the sidebar instead
              of here, so this header row is purely brand and doesn't
              compete with the logo for visual weight. Falls back to the
              old icon+text combo if the logo URL hasn't been localized
              yet (e.g. legacy admin bootstrap before this commit). */}
          <div className="flex items-center gap-2 min-w-0">
            {bk.logoUrl ? (
              <img
                src={bk.logoUrl}
                alt="BackReload"
                className="h-7 w-auto select-none"
                draggable={false}
              />
            ) : (
              <>
                <div className="h-7 w-7 rounded-lg bg-brand-500 text-white grid place-items-center shadow-soft">
                  <ShieldCheck className="h-4 w-4" />
                </div>
                <span className="text-sm font-semibold text-ink-900 leading-tight">BackReload</span>
              </>
            )}
          </div>
          {/* Close button (mobile only) */}
          <button
            className="lg:hidden h-8 w-8 grid place-items-center rounded-md text-ink-500 hover:bg-ink-100"
            onClick={() => setMobileOpen(false)}
            aria-label="Close menu"
          >
            <XIcon className="h-4 w-4" />
          </button>
        </div>
        <nav className="flex-1 px-3 py-3 space-y-1 overflow-y-auto">
          {nav.map(({ key, label, icon: Icon }) => (
            <button
              key={key}
              onClick={() => { setPage(key); setMobileOpen(false); }}
              className={cn(
                'w-full !justify-start flex items-center gap-3 px-3 h-9 rounded-lg text-sm transition-colors',
                page === key
                  ? 'bg-ink-100 text-ink-900 font-medium'
                  : 'text-ink-600 hover:bg-ink-50 hover:text-ink-900',
              )}
            >
              <Icon className="h-4 w-4 shrink-0" />
              <span className="truncate">{label}</span>
            </button>
          ))}
        </nav>
        <div className="p-3 border-t border-ink-100 space-y-2">
          <div className="rounded-xl bg-ink-50 border border-ink-100 p-3">
            <div className="flex items-center gap-2 text-xs font-medium text-ink-800">
              <ShieldCheck className="h-3.5 w-3.5 text-emerald-600" />
              Site protected
            </div>
            <p className="text-[11px] text-ink-500 mt-1">Backup status shown on dashboard.</p>
          </div>
          {/* Build version pinned to the very bottom of the sidebar — out of
              the way of the brand mark up top, but still one glance away
              when a user needs to report a bug or check what they're on. */}
          {bk.version && (
            <p className="text-[10px] text-ink-400 text-center tabular-nums">
              v{bk.version}
            </p>
          )}
        </div>
      </aside>

      {/* Main */}
      <div className="flex-1 min-w-0 flex flex-col">
        {/* Header. In-flow on all viewports — sits at the top of the
            main column. On mobile, scrolls with the page; on desktop
            stays in place because the page is generally short enough
            to not scroll. This avoids every sticky/fixed quirk in the
            WP admin DOM (ancestor transforms breaking containing blocks
            for position:fixed, overflow:hidden killing sticky, etc.) by
            simply not relying on any of those mechanisms.
            Trade-off: on mobile, scroll-down hides the header. The
            hamburger is re-accessible by scrolling back to the top.
            Acceptable for an admin tool with a one-time daily visit
            per session. */}
        <header className="backreload-topbar h-14 bg-white border-b border-ink-200 flex items-center gap-2 px-3 sm:px-6">
          {/* Mobile/tablet: hamburger + brand. Hidden on lg+ where the
              sidebar already shows the brand and nav. */}
          <button
            className="lg:hidden flex items-center gap-2 h-10 pl-2 pr-3 rounded-lg text-ink-800 hover:bg-ink-100 active:bg-ink-200 transition-colors"
            onClick={() => setMobileOpen(true)}
            aria-label="Open navigation menu"
          >
            <MenuIcon className="h-5 w-5" />
            {bk.logoUrl ? (
              <img
                src={bk.logoUrl}
                alt="BackReload"
                className="h-5 w-auto select-none"
                draggable={false}
              />
            ) : (
              <>
                <span className="h-6 w-6 rounded-md bg-brand-500 text-white grid place-items-center shadow-soft">
                  <ShieldCheck className="h-3.5 w-3.5" />
                </span>
                <span className="text-sm font-semibold">BackReload</span>
              </>
            )}
          </button>
          <span className="lg:hidden text-sm text-ink-500 truncate">· {current.label}</span>
          <h1 className="hidden lg:block text-base font-semibold text-ink-900 truncate">{current.label}</h1>
          <div className="ml-auto"><MaintenanceBadge /></div>
        </header>

        <main className="backreload-main flex-1 p-4 sm:p-6 bg-ink-50">{children}</main>
      </div>
    </div>
  );
}
