// AppShell with Sidebar + TopBar — light Apple-style
const NavLink = ReactRouterDOM.NavLink;
const useLocation = ReactRouterDOM.useLocation;
const useNavigate = ReactRouterDOM.useNavigate;
const Outlet = ReactRouterDOM.Outlet;

const NAV = [
  { to: "/app/dashboard",   label: "Dashboard",     icon: "layout-dashboard" },
  { to: "/app/calendar",    label: "Calendar",      icon: "calendar" },
  { to: "/app/bookings",    label: "Bookings",      icon: "list" },
  { to: "/app/forms",       label: "Booking Forms", icon: "file-text" },
  { to: "/app/events",      label: "Events",        icon: "ticket" },
  { to: "/app/customers",   label: "Customers",     icon: "users" },
  { to: "/app/install",     label: "Website",       icon: "globe" },
  { to: "/app/automations", label: "Automations",   icon: "send" },
  { to: "/app/settings",    label: "Settings",      icon: "settings" }
];

function Sidebar({ open, onClose, business }) {
  const auth = useAuth();
  const ws = auth.currentWorkspace;
  const wsName = business?.name || ws?.name || "Pick a workspace";
  const wsUrl  = business?.url  || (ws?.slug ? `/${ws.slug}` : "—");
  const wsInitials = (wsName || "")
    .split(" ").filter(Boolean).slice(0, 2).map((w) => w[0]).join("").toUpperCase() || "?";

  // Live count of pending bookings (drives the badge on the Bookings nav).
  // Refetches whenever the workspace changes or the user navigates — accept/
  // decline pages live under /app/bookings so navigating back to the dashboard
  // gives us a fresh count.
  const location = useLocation();
  const [pendingCount, setPendingCount] = useState(0);
  useEffect(() => {
    if (!ws?.id) { setPendingCount(0); return; }
    let cancelled = false;
    (async () => {
      const res = await SB.from('bookings')
        .select('id', { count: 'exact', head: true })
        .eq('workspace_id', ws.id)
        .in('status', ['requested', 'reschedule_proposed']);
      if (!cancelled) setPendingCount(res.count || 0);
    })();
    return () => { cancelled = true; };
  }, [ws?.id, location.pathname]);

  return (
    <>
      {open && <div className="lg:hidden fixed inset-0 z-30 bg-ink/30 backdrop-blur-sm" onClick={onClose} />}
      <aside
        className={`fixed lg:static z-40 inset-y-0 left-0 w-[256px] flex flex-col bg-paper border-r border-ink/[0.06]
        transform transition-transform lg:transform-none ${open ? "translate-x-0" : "-translate-x-full lg:translate-x-0"}`}
      >
        {/* Brand */}
        <div className="px-5 pt-5 pb-3 flex items-center gap-2.5">
          <div className="h-8 w-8 grid place-items-center rounded-xl bg-ink text-white">
            <VMark size={15} color="#FFFFFF" />
          </div>
          <span className="font-display text-[19px] leading-none tracking-tight">Vale</span>
          <span className="text-[10px] uppercase tracking-[0.16em] text-ink/40 mt-1">Booking</span>
        </div>

        {/* Workspace switcher */}
        <div className="px-3 mt-1">
          <button className="w-full flex items-center justify-between gap-2 px-2.5 py-2 rounded-xl bg-white border border-ink/[0.06] hover:bg-ink/[0.02] transition group">
            <div className="flex items-center gap-2.5 min-w-0">
              <div className="h-7 w-7 rounded-lg grid place-items-center bg-ink text-white text-[10px] font-semibold uppercase tracking-wider">
                {wsInitials}
              </div>
              <div className="text-left min-w-0">
                <div className="text-[13px] truncate font-medium">{wsName}</div>
                <div className="text-[11px] text-ink/45 truncate">{wsUrl}</div>
              </div>
            </div>
            <Icon name="chevrons-up-down" size={13} className="text-ink/40 group-hover:text-ink/70" />
          </button>
        </div>

        {/* Nav */}
        <nav className="mt-5 px-2 flex-1 overflow-y-auto">
          <div className="text-[10.5px] uppercase tracking-[0.12em] text-ink/35 px-3 mb-1.5">Workspace</div>
          <div className="flex flex-col gap-0.5">
            {NAV.map((item) => (
              <NavLink
                key={item.to}
                to={item.to}
                onClick={onClose}
                className={({ isActive }) =>
                  `flex items-center gap-2.5 px-3 py-[7px] rounded-lg text-[13.5px] transition ${
                    isActive ? "bg-white text-ink shadow-card" : "text-ink/70 hover:text-ink hover:bg-ink/[0.04]"
                  }`
                }
              >
                {({ isActive }) => (
                  <>
                    <Icon name={item.icon} size={16} strokeWidth={1.5} className={isActive ? "text-ink" : "text-ink/55"} />
                    <span className="flex-1">{item.label}</span>
                    {item.label === "Bookings" && pendingCount > 0 && (
                      <Badge tone="accent" className="!px-1.5 !py-0 !text-[10px]">{pendingCount}</Badge>
                    )}
                  </>
                )}
              </NavLink>
            ))}
          </div>

          <div className="text-[10.5px] uppercase tracking-[0.12em] text-ink/35 px-3 mt-6 mb-1.5">Agency</div>
          <NavLink
            to="/agency"
            onClick={onClose}
            className={({ isActive }) =>
              `flex items-center gap-2.5 px-3 py-[7px] rounded-lg text-[13.5px] transition ${
                isActive ? "bg-white text-ink shadow-card" : "text-ink/70 hover:text-ink hover:bg-ink/[0.04]"
              }`
            }
          >
            <Icon name="building-2" size={16} strokeWidth={1.5} className="text-ink/55" />
            <span>Admin Console</span>
          </NavLink>
        </nav>

        {/* Bottom */}
        <div className="px-3 pb-4 pt-3 border-t border-ink/[0.06]">
          <div className="flex items-center justify-between px-2.5 py-2 rounded-lg bg-white border border-ink/[0.06]">
            <div className="flex items-center gap-2">
              <span className="h-1.5 w-1.5 rounded-full bg-[#34C759] pulse-dot" />
              <span className="text-[11.5px] text-ink/70">Google Calendar synced</span>
            </div>
          </div>
          <UserChip />
        </div>
      </aside>
    </>
  );
}

// Bottom-of-sidebar user chip: name, role/email, and a sign-out button.
function UserChip() {
  const auth = useAuth();
  const user = auth.session?.user;
  const ws = auth.currentWorkspace;
  const memberHere = ws ? auth.memberships.find(m => m.workspace_id === ws.id) : null;
  const displayName = displayNameFor(auth) || "Signed in";
  const subline = memberHere?.role === "owner"
    ? "Owner"
    : memberHere?.role
    ? memberHere.role
    : auth.isAgencyAdmin
    ? "Agency admin"
    : user?.email;
  return (
    <div className="mt-3 px-2 flex items-center gap-2.5">
      <Avatar name={displayName} size={28} />
      <div className="flex-1 min-w-0">
        <div className="text-[12.5px] truncate">{displayName}</div>
        <div className="text-[10.5px] text-ink/45 truncate">{subline}</div>
      </div>
      <button
        onClick={() => signOut()}
        title="Sign out"
        className="text-ink/40 hover:text-ink h-7 w-7 grid place-items-center rounded-full hover:bg-ink/[0.05]"
      >
        <Icon name="log-out" size={14} />
      </button>
    </div>
  );
}

function TopBar({ onOpenSidebar, breadcrumbs }) {
  const auth = useAuth();
  const ws = auth.currentWorkspace;
  return (
    <header className="sticky top-0 z-20 bg-paper/80 backdrop-blur-lg border-b border-ink/[0.06]">
      <div className="flex items-center gap-3 h-14 px-5 lg:px-7">
        <button onClick={onOpenSidebar} className="lg:hidden -ml-2 h-9 w-9 grid place-items-center rounded-full text-ink/70 hover:text-ink hover:bg-ink/[0.05]">
          <Icon name="menu" size={18} />
        </button>
        {breadcrumbs && (
          <div className="hidden md:flex items-center gap-2 text-[12.5px] text-ink/45">
            {breadcrumbs.map((b, i) => (
              <React.Fragment key={i}>
                {i > 0 && <Icon name="chevron-right" size={11} />}
                <span className={i === breadcrumbs.length - 1 ? "text-ink/80" : ""}>{b}</span>
              </React.Fragment>
            ))}
          </div>
        )}
        <div className="ml-auto flex items-center gap-2">
          <NotificationBell />
          {ws?.slug && (
            <button
              onClick={() => window.open(`#/public/${ws.slug}`, "_blank")}
              className="ml-1 hidden md:inline-flex items-center gap-1.5 h-9 px-3 rounded-full border border-ink/10 hover:bg-ink/[0.03] text-[12.5px] text-ink/80 bg-white"
            >
              <Icon name="external-link" size={12} />
              View public page
            </button>
          )}
        </div>
      </div>
    </header>
  );
}

// Bell with pending-request badge + activity popover.
function NotificationBell() {
  const auth = useAuth();
  const ws = auth.currentWorkspace;
  const navigate = useNavigate();
  const [open, setOpen] = useState(false);
  const [pending, setPending] = useState([]);
  const [activity, setActivity] = useState([]);
  const [loading, setLoading] = useState(false);
  const wrapRef = useRef(null);

  const reload = useCallback(async () => {
    if (!ws?.id) return;
    setLoading(true);
    const [pRes, aRes] = await Promise.all([
      SB.from('bookings')
        .select('id, starts_at, status, customers ( name )')
        .eq('workspace_id', ws.id)
        .in('status', ['requested', 'reschedule_proposed'])
        .order('starts_at')
        .limit(20),
      SB.from('activity')
        .select('id, kind, text, created_at, ref_id')
        .eq('workspace_id', ws.id)
        .order('created_at', { ascending: false })
        .limit(12)
    ]);
    setLoading(false);
    setPending(pRes.data || []);
    setActivity(aRes.data || []);
  }, [ws?.id]);

  // Refresh on mount + when the popover opens.
  useEffect(() => { reload(); }, [reload]);
  useEffect(() => { if (open) reload(); }, [open, reload]);

  // Click outside to close.
  useEffect(() => {
    if (!open) return;
    const handler = (e) => { if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);

  const pendingCount = pending.length;
  const hasUnread = pendingCount > 0;

  const openBookings = () => {
    setOpen(false);
    navigate("/app/bookings");
  };

  return (
    <div className="relative" ref={wrapRef}>
      <button
        onClick={() => setOpen(o => !o)}
        title="Notifications"
        aria-label={hasUnread ? `${pendingCount} pending requests` : "Notifications"}
        className="relative h-9 w-9 grid place-items-center rounded-full hover:bg-ink/[0.05] text-ink/65 hover:text-ink"
      >
        <Icon name="bell" size={16} />
        {hasUnread && (
          <span className="absolute top-1.5 right-1.5 min-w-[14px] h-[14px] px-1 grid place-items-center rounded-full bg-[#FF3B30] ring-2 ring-paper text-white text-[9.5px] font-semibold leading-none">
            {pendingCount > 9 ? "9+" : pendingCount}
          </span>
        )}
      </button>

      {open && (
        <div className="absolute right-0 top-full mt-2 w-[360px] rounded-xl border border-ink/[0.08] bg-white shadow-lift overflow-hidden z-50">
          {/* Header */}
          <div className="flex items-center justify-between px-4 py-3 border-b border-ink/[0.06]">
            <div className="text-[13px] font-medium">Notifications</div>
            <button onClick={reload} title="Refresh" className="text-ink/45 hover:text-ink h-6 w-6 grid place-items-center rounded-md hover:bg-ink/[0.04]">
              <Icon name="refresh-cw" size={11} />
            </button>
          </div>

          {/* Pending requests highlight */}
          <button
            onClick={openBookings}
            className="w-full text-left px-4 py-3 border-b border-ink/[0.06] hover:bg-ink/[0.02] transition"
          >
            <div className="flex items-center gap-2.5">
              <div className={`h-8 w-8 rounded-md grid place-items-center ${pendingCount > 0 ? "bg-warn/15 text-warn" : "bg-ink/[0.04] text-ink/40"}`}>
                <Icon name="clock" size={14} />
              </div>
              <div className="flex-1 min-w-0">
                <div className="text-[13px] font-medium">
                  {pendingCount === 0 ? "No pending requests" : `${pendingCount} pending request${pendingCount === 1 ? "" : "s"}`}
                </div>
                <div className="text-[11.5px] text-ink/55 truncate">
                  {pendingCount === 0 ? "You're all caught up." : pending.slice(0, 2).map(p => p.customers?.name || "—").join(", ") + (pendingCount > 2 ? ` +${pendingCount - 2}` : "")}
                </div>
              </div>
              <Icon name="chevron-right" size={13} className="text-ink/40" />
            </div>
          </button>

          {/* Activity feed */}
          <div className="max-h-[320px] overflow-y-auto">
            {loading && activity.length === 0 ? (
              <div className="px-4 py-6 text-center text-[12px] text-ink/45">Loading…</div>
            ) : activity.length === 0 ? (
              <div className="px-4 py-6 text-center text-[12px] text-ink/45">No activity yet.</div>
            ) : (
              <div className="px-2 py-1">
                {activity.map(a => (
                  <div key={a.id} className="flex items-start gap-2.5 px-2.5 py-2 rounded-md hover:bg-ink/[0.02]">
                    <div className={`h-6 w-6 rounded-full grid place-items-center flex-shrink-0 mt-0.5 ${activityTone(a.kind).bg}`}>
                      <Icon name={activityTone(a.kind).icon} size={10} className={activityTone(a.kind).text} />
                    </div>
                    <div className="flex-1 min-w-0">
                      <div className="text-[12.5px] text-ink/85 leading-snug">{a.text}</div>
                      <div className="text-[10.5px] text-ink/45 mt-0.5">{relTime(new Date(a.created_at))}</div>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>

          <div className="border-t border-ink/[0.06] px-4 py-2.5 flex items-center justify-end">
            <button onClick={openBookings} className="text-[11.5px] text-ink/65 hover:text-ink inline-flex items-center gap-1">
              View all bookings <Icon name="arrow-right" size={11} />
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function AppShell() {
  const [sidebar, setSidebar] = useState(false);
  const loc = useLocation();
  const current = NAV.find((n) => loc.pathname.startsWith(n.to)) || { label: "Dashboard" };

  return (
    <div className="flex h-full min-h-screen bg-paper text-ink">
      <Sidebar open={sidebar} onClose={() => setSidebar(false)} />
      <div className="flex-1 flex flex-col min-w-0">
        <TopBar onOpenSidebar={() => setSidebar(true)} breadcrumbs={["Northstone Powersports", current.label]} />
        <main className="flex-1 overflow-y-auto">
          <Outlet />
        </main>
      </div>
    </div>
  );
}

// Top-right cluster of the agency shell: "exit to client view" link (only when
// the admin also belongs to a workspace), avatar, and sign-out.
function AgencyTopRight() {
  const auth = useAuth();
  const displayName = displayNameFor(auth) || "Vale Admin";
  const canExitToClient = auth.memberships.length > 0;
  return (
    <div className="ml-auto flex items-center gap-3">
      {canExitToClient && (
        <NavLink to="/app/dashboard" className="text-[12.5px] text-ink/65 hover:text-ink inline-flex items-center gap-1.5">
          <Icon name="arrow-left" size={12} />
          Exit to client view
        </NavLink>
      )}
      <Avatar name={displayName} size={28} />
      <button
        onClick={() => signOut()}
        title="Sign out"
        className="h-8 w-8 grid place-items-center rounded-full text-ink/55 hover:text-ink hover:bg-ink/[0.05]"
      >
        <Icon name="log-out" size={14} />
      </button>
    </div>
  );
}

// ── Agency Shell — same light style, distinguished by header label ────────
function AgencyShell() {
  return (
    <div className="min-h-screen bg-paper text-ink">
      <header className="sticky top-0 z-20 bg-paper/80 backdrop-blur-lg border-b border-ink/[0.06]">
        <div className="max-w-[1400px] mx-auto px-6 lg:px-10 h-14 flex items-center gap-4">
          <div className="flex items-center gap-2.5">
            <div className="h-7 w-7 grid place-items-center rounded-lg bg-ink text-white">
              <VMark size={14} color="#FFFFFF" />
            </div>
            <span className="font-display text-[17px] leading-none tracking-tight">Vale</span>
            <span className="text-[10px] uppercase tracking-[0.14em] text-ink/55 ml-1 px-2 py-0.5 rounded-full bg-ink/[0.05]">Agency</span>
          </div>
          <nav className="hidden md:flex items-center gap-1 ml-6 text-[13px]">
            {[
              ["clients","Clients"],["templates","Templates"],["embed","Embed Settings"]
            ].map(([p,l]) => (
              <NavLink key={p} to={`/agency/${p}`} className={({isActive}) => `px-3.5 py-1.5 rounded-full ${isActive ? "bg-ink text-white" : "text-ink/65 hover:text-ink hover:bg-ink/[0.04]"}`}>{l}</NavLink>
            ))}
          </nav>
          <AgencyTopRight />
        </div>
      </header>
      <main><Outlet /></main>
    </div>
  );
}

Object.assign(window, { AppShell, AgencyShell, NAV });
