import type { NavTarget, ViewName } from "./lib/useHashView";
import { useCompany } from "./lib/company";
import { useChecksQueueCount } from "./checks/checksQueueCount";
import { useItemsPresence } from "./items/useItemsPresence";

// Sentinel value for the switcher's "Add company" option — never a real
// company id (uuid), so it can't collide with one.
const ADD_COMPANY_VALUE = "__add_company__";

// `stocked: true` means "only show this once the company actually keeps stock"
// (Inventory Task 5). A service business has nothing to build and nothing to
// count, and two nav entries onto empty screens is exactly the clutter
// CLAUDE.md §9 exists to prevent — same "invisible until it applies" rule the
// Sales tax report tab already follows.
const NAV_ITEMS: { view: ViewName; label: string; stocked?: true }[] = [
  { view: "home", label: "Home" },
  { view: "dashboard", label: "Dashboard" },
  { view: "reports", label: "Reports" },
  { view: "transactions", label: "Transactions" },
  { view: "chart", label: "Chart of Accounts" },
  { view: "items", label: "Items" },
  { view: "record", label: "Record" },
  { view: "customers", label: "Customers" },
  { view: "invoices", label: "Invoices" },
  { view: "vendors", label: "Vendors" },
  { view: "bills", label: "Bills" },
  { view: "purchase-orders", label: "Purchase orders" },
  { view: "builds", label: "Builds", stocked: true },
  { view: "stock-adjustments", label: "Stock adjustments", stocked: true },
  { view: "checks", label: "Checks to print" },
  { view: "close", label: "Year-end close" },
  { view: "settings", label: "Settings" },
];

export function Sidebar({
  view,
  onNavigate,
}: {
  view: ViewName | null;
  // NavTarget, not ViewName: "+ Add company…" navigates to the setup wizard
  // WITH its intent attached (#/setup?new=1), which is a target shape rather
  // than a bare view name. The nav buttons still pass plain view names.
  onNavigate: (target: NavTarget) => void;
}) {
  const { companies, selectedCompanyId, selectCompany } = useCompany();
  // AP Task 5: a count badge on "Checks to print" when the queue is
  // non-empty — see checksQueueCount.ts's header for why this is a
  // best-effort client-side sum rather than a dedicated endpoint.
  const checksQueueCount = useChecksQueueCount(selectedCompanyId);
  // Inventory Task 5: Builds and Stock adjustments appear only once at least
  // one stocked item exists. A screen the user is currently ON stays in the
  // nav regardless, so its highlight can't vanish out from under them.
  //
  // The Sidebar never unmounts, so this subscribes to a shared answer that the
  // item screens refresh when they change it (items/useItemsPresence.ts's
  // itemsChanged) — creating your first stocked item makes the entries appear
  // where you are standing, and turning off the last one takes them away again.
  const { hasStockedItems } = useItemsPresence(selectedCompanyId);
  const navItems = NAV_ITEMS.filter(
    (item) => !item.stocked || hasStockedItems || view === item.view,
  );

  return (
    <nav className="shell-sidebar">
      <div className="shell-brand">Ledger</div>
      <div className="shell-nav">
        {navItems.map((item) => (
          <button
            key={item.view}
            type="button"
            aria-current={view === item.view ? "page" : undefined}
            onClick={() => onNavigate(item.view)}
          >
            {item.label}
            {item.view === "checks" && checksQueueCount > 0 && (
              <span className="nav-badge">{checksQueueCount}</span>
            )}
          </button>
        ))}
      </div>
      {companies.length >= 1 && (
        <div className="shell-switcher">
          <label htmlFor="company-switcher">Company</label>
          <select
            id="company-switcher"
            value={selectedCompanyId ?? ""}
            onChange={(ev) => {
              // "Add company" (Task 10) is a sentinel option at the bottom
              // of the same dropdown, not a real company id — routes to the
              // setup wizard instead of selecting anything.
              //
              // It goes to #/setup?new=1, not a bare #setup: this click SAYS
              // "add a company", and the wizard used to throw that away and
              // re-derive an intent from whatever company was selected —
              // greeting someone who asked to add a company with "Welcome
              // back, <other company>, want to resume?". The intent rides in
              // the hash so it survives F5 and Back (setup/setupEntry.ts).
              if (ev.target.value === ADD_COMPANY_VALUE) {
                onNavigate({ view: "setup", intent: "new-company" });
                return;
              }
              selectCompany(ev.target.value);
            }}
          >
            <option value="" disabled>
              Choose a company&hellip;
            </option>
            {companies.map((c) => (
              <option key={c.id} value={c.id}>
                {c.name}
                {c.isSample ? " (Sample)" : ""}
              </option>
            ))}
            <option value={ADD_COMPANY_VALUE}>+ Add company&hellip;</option>
          </select>
          {/* <select> options can't carry styled chips, so the currently
              selected sample company gets a subtle badge just below the
              dropdown itself — visible whenever a sample company is active,
              same "explore freely, real companies untouched" reassurance the
              wizard's success screen gives right after creating it. */}
          {companies.find((c) => c.id === selectedCompanyId)?.isSample && (
            <span className="chip chip-info sample-chip">Sample</span>
          )}
        </div>
      )}
    </nav>
  );
}
