'use client';

import { useState } from 'react';
import Image from 'next/image';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import {
  LayoutDashboard,
  Users,
  Bookmark,
  Anchor,
  Ship,
  Building2,
  Receipt,
  FileText,
  Inbox,
  Camera,
  Globe,
  Settings,
  Shield,
  Home,
  ChevronLeft,
  ChevronRight,
  ChevronDown,
  ChevronUp,
} from 'lucide-react';

import { cn } from '@/lib/utils';
import { useUIStore } from '@/stores/ui-store';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { UserMenu } from '@/components/layout/user-menu';
import { useUmamiActive } from '@/components/website-analytics/use-website-analytics';
import type { UserPortRole } from '@/lib/db/schema/users';
import type { Role } from '@/lib/db/schema/users';
import type { Port } from '@/lib/db/schema/ports';

const LOGO_URL =
  'https://s3.portnimara.com/images/Port%20Nimara%20New%20Logo-Circular%20Frame_250px.png';

interface SidebarProps {
  portRoles: (UserPortRole & { port: { id: string; slug: string; name: string }; role: Role })[];
  isSuperAdmin?: boolean;
  user?: { name: string; email: string };
  /** Ports the user has access to. Drives the footer port switcher. */
  ports?: Port[];
}

/**
 * Turn a snake_cased DB role identifier (e.g. "super_admin") into a human
 * label ("Super Admin"). Empty/missing → "Staff" fallback.
 */
function humanizeRole(roleName: string | null | undefined): string {
  if (!roleName) return 'Staff';
  return roleName
    .split('_')
    .map((part) => (part ? part[0]!.toUpperCase() + part.slice(1) : part))
    .join(' ');
}

interface NavItem {
  href: string;
  label: string;
  icon: React.ElementType;
  exact?: boolean;
}

interface NavSection {
  title: string;
  items: NavItem[];
  adminRequired?: boolean;
  /** When true, only render if the user has marina-side access. */
  marinaRequired?: boolean;
  /** When true, only render if the user has residential-side access. */
  residentialRequired?: boolean;
  /** When true, only render if Umami analytics is wired up for the port. */
  umamiRequired?: boolean;
}

function buildNavSections(portSlug: string | undefined): NavSection[] {
  const base = portSlug ? `/${portSlug}` : '';

  return [
    {
      title: 'Main',
      marinaRequired: true,
      items: [
        { href: `${base}/dashboard`, label: 'Dashboard', icon: LayoutDashboard },
        { href: `${base}/clients`, label: 'Clients', icon: Users },
        { href: `${base}/yachts`, label: 'Yachts', icon: Ship },
        { href: `${base}/companies`, label: 'Companies', icon: Building2 },
        { href: `${base}/interests`, label: 'Interests', icon: Bookmark },
        { href: `${base}/berths`, label: 'Berths', icon: Anchor },
      ],
    },
    {
      title: 'Residential',
      residentialRequired: true,
      items: [
        {
          href: `${base}/residential/clients`,
          label: 'Residential Clients',
          icon: Home,
        },
        {
          href: `${base}/residential/interests`,
          label: 'Residential Interests',
          icon: Bookmark,
        },
      ],
    },
    {
      title: 'Documents',
      marinaRequired: true,
      items: [{ href: `${base}/documents`, label: 'Documents', icon: FileText }],
    },
    {
      title: 'Financial',
      marinaRequired: true,
      items: [
        { href: `${base}/expenses`, label: 'Expenses', icon: Receipt },
        // Invoices nav entry removed — the expense-to-PDF flow is the
        // only invoicing surface now (employee expense reports). The
        // standalone /invoices route still exists for any back-compat
        // links but is no longer surfaced in nav.
        // Dedicated explainer page covers "Add to Home Screen" install
        // + walkthrough; the mobile-only scanner UI itself lives at /scan
        // and is reached via the install or the explainer page button.
        {
          href: `${base}/invoices/upload-receipts`,
          label: 'How to upload receipts',
          icon: Camera,
        },
      ],
    },
    {
      title: 'Insights',
      marinaRequired: true,
      umamiRequired: true,
      items: [
        // Marketing / Umami integration. Distinct from the main dashboard
        // (which is sales-focused) so the audience and the metrics don't
        // compete for visual real estate. Whole section is hidden when
        // Umami isn't wired up — see SidebarContent.
        {
          href: `${base}/website-analytics`,
          label: 'Website analytics',
          icon: Globe,
        },
      ],
    },
    {
      title: 'Communication',
      marinaRequired: true,
      items: [
        // Email tab removed: deferred building a full inbox/threading
        // feature (would require Google OAuth + scope review + IMAP
        // syncing infra). This entry routes to the merged
        // Alerts + Reminders surface (2026-05-11) — explicit name so
        // reps don't mistake it for an email inbox.
        { href: `${base}/inbox`, label: 'Alerts & Reminders', icon: Inbox },
      ],
    },
    {
      title: 'Admin',
      adminRequired: true,
      items: [
        { href: `${base}/settings`, label: 'Settings', icon: Settings },
        { href: `${base}/admin`, label: 'Administration', icon: Shield },
      ],
    },
  ];
}

function NavItemLink({
  item,
  collapsed,
  active,
}: {
  item: NavItem;
  collapsed: boolean;
  active: boolean;
}) {
  const content = (
    <Link
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      href={item.href as any}
      className={cn(
        'relative flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-all duration-150',
        'text-slate-700 hover:bg-accent hover:text-foreground',
        active && 'bg-accent text-foreground pl-[14px]',
        collapsed && 'justify-center px-2',
      )}
    >
      {active && !collapsed && (
        <span
          aria-hidden
          className="absolute left-0 top-1 bottom-1 w-1 rounded-r-full bg-[#3a7bc8]"
        />
      )}
      <item.icon
        className={cn(
          'shrink-0',
          active ? 'text-[#3a7bc8]' : 'text-slate-500',
          collapsed ? 'w-5 h-5' : 'w-4 h-4',
        )}
      />
      {!collapsed && <span>{item.label}</span>}
    </Link>
  );

  if (collapsed) {
    return (
      <Tooltip>
        <TooltipTrigger asChild>{content}</TooltipTrigger>
        <TooltipContent side="right" className="font-medium">
          {item.label}
        </TooltipContent>
      </Tooltip>
    );
  }

  return content;
}

function SidebarContent({
  collapsed,
  portSlug,
  portRoles,
  isSuperAdmin,
  hasAdminAccess,
  hasMarinaAccess,
  hasResidentialAccess,
  user,
  ports,
  onToggleCollapse,
}: {
  collapsed: boolean;
  portSlug: string | undefined;
  portRoles: SidebarProps['portRoles'];
  isSuperAdmin: boolean;
  hasAdminAccess: boolean;
  hasMarinaAccess: boolean;
  hasResidentialAccess: boolean;
  user?: SidebarProps['user'];
  ports?: Port[];
  /** When provided, renders the collapse toggle row above the user footer (desktop). */
  onToggleCollapse?: () => void;
}) {
  const pathname = usePathname();
  const [adminExpanded, setAdminExpanded] = useState(true);
  const sections = buildNavSections(portSlug);
  const umami = useUmamiActive('today');
  const umamiConfigured = !umami.isLoading && umami.data?.notConfigured !== true;

  // Small label under the user identity when the user has access to more
  // than one port — disambiguates which port is currently active without
  // pulling the port name back into the breadcrumbs.
  const showPortLabel = !!ports && ports.length > 1;
  const currentPortName = showPortLabel
    ? (ports.find((p) => p.slug === portSlug)?.name ?? null)
    : null;

  // Pre-compute every nav href the sidebar offers across all sections so
  // the active-state check can do longest-prefix-match. Without this,
  // /invoices/upload-receipts would highlight both "Invoices" and "How to
  // upload receipts" - every ancestor prefix matches.
  const allHrefs = sections.flatMap((s) => s.items.map((i) => i.href));

  function isActive(href: string, exact?: boolean): boolean {
    if (exact) return pathname === href;
    if (!pathname.startsWith(href)) return false;
    // Active only if no other sidebar item has a strictly more-specific
    // prefix match. That makes the highlight follow the URL into the
    // deepest registered route (e.g. /invoices/upload-receipts wins over
    // /invoices when both are sidebar items).
    return !allHrefs.some((other) => other.length > href.length && pathname.startsWith(other));
  }

  // Sidebar header showcases the Port Nimara logo as the visual anchor of
  // the brand. Collapse toggle is a small overlay button so it doesn't
  // compete with the logo for attention.
  return (
    <TooltipProvider delayDuration={0}>
      <div className="flex flex-col h-full bg-white">
        {/* Brand header - logo centered. Soft hairline below echoes the
            inter-section separators in the nav so the eye reads the logo
            as a distinct top-row, not a floating element. */}
        <div
          className={cn(
            'relative flex items-center justify-center border-b border-slate-200',
            collapsed ? 'h-16 px-2' : 'h-24 px-4',
          )}
        >
          <Image
            src={LOGO_URL}
            alt="Port Nimara"
            width={collapsed ? 40 : 72}
            height={collapsed ? 40 : 72}
            className="rounded-full shadow-sm"
            unoptimized
            priority
          />
          {onToggleCollapse && (
            <button
              type="button"
              onClick={onToggleCollapse}
              aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
              className={cn(
                'absolute right-2 flex h-6 w-6 items-center justify-center rounded-md text-slate-400 hover:bg-slate-100 hover:text-slate-700 transition-colors',
                collapsed ? 'top-1' : 'top-2',
              )}
            >
              {collapsed ? (
                <ChevronRight className="w-4 h-4" />
              ) : (
                <ChevronLeft className="w-4 h-4" />
              )}
            </button>
          )}
        </div>

        {/* Nav */}
        <ScrollArea className="flex-1 py-2">
          <nav className="px-2 space-y-4">
            {sections.map((section) => {
              if (section.adminRequired && !hasAdminAccess) return null;
              if (section.marinaRequired && !hasMarinaAccess) return null;
              if (section.residentialRequired && !hasResidentialAccess) return null;
              if (section.umamiRequired && !umamiConfigured) return null;

              return (
                <div key={section.title}>
                  {!collapsed && (
                    <div className="flex items-center justify-between px-1 mb-1">
                      <span className="text-slate-500 text-[10px] font-semibold uppercase tracking-[0.12em]">
                        {section.title}
                      </span>
                      {section.adminRequired && (
                        <button
                          onClick={() => setAdminExpanded((v) => !v)}
                          className="text-slate-400 hover:text-slate-700 transition-colors"
                        >
                          {adminExpanded ? (
                            <ChevronUp className="w-3 h-3" />
                          ) : (
                            <ChevronDown className="w-3 h-3" />
                          )}
                        </button>
                      )}
                    </div>
                  )}
                  {(!section.adminRequired || adminExpanded || collapsed) && (
                    <ul className="space-y-0.5">
                      {section.items.map((item) => (
                        <li key={item.href}>
                          <NavItemLink
                            item={item}
                            collapsed={collapsed}
                            active={isActive(item.href, item.exact)}
                          />
                        </li>
                      ))}
                    </ul>
                  )}
                  <Separator className="mt-3 bg-slate-200" />
                </div>
              );
            })}
          </nav>
        </ScrollArea>

        {/* User footer - entire row is the trigger for the UserMenu so the
            user can click their name/avatar to access Profile / Settings /
            port-switcher / sign-out. The same UserMenu component drives the
            top-right avatar dropdown, so the menu items stay consistent. */}
        <div className={cn('border-t border-slate-200 p-2', collapsed && 'flex justify-center')}>
          {collapsed ? (
            <UserMenu
              align="start"
              user={user}
              ports={ports}
              trigger={
                <button
                  type="button"
                  aria-label="Open user menu"
                  className="rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3a7bc8] focus-visible:ring-offset-2 focus-visible:ring-offset-white"
                >
                  <Avatar className="w-8 h-8 cursor-pointer">
                    <AvatarImage src={undefined} />
                    <AvatarFallback className="bg-[#3a7bc8] text-white text-xs font-semibold">
                      {(user?.name ?? 'U').slice(0, 1).toUpperCase()}
                    </AvatarFallback>
                  </Avatar>
                </button>
              }
            />
          ) : (
            <UserMenu
              align="start"
              user={user}
              ports={ports}
              trigger={
                <button
                  type="button"
                  aria-label="Open user menu"
                  className="flex w-full items-center gap-3 rounded-md p-1.5 text-left transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3a7bc8] focus-visible:ring-offset-2 focus-visible:ring-offset-white"
                >
                  <Avatar className="w-8 h-8 shrink-0 shadow-sm ring-2 ring-slate-200">
                    <AvatarImage src={undefined} />
                    <AvatarFallback className="bg-[#3a7bc8] text-white text-xs font-semibold">
                      {(user?.name ?? 'U').slice(0, 1).toUpperCase()}
                    </AvatarFallback>
                  </Avatar>
                  <div className="flex-1 min-w-0">
                    <p className="text-foreground text-sm font-medium truncate">
                      {user?.name ?? 'User'}
                    </p>
                    <Badge
                      variant="outline"
                      className="text-[10px] px-1.5 py-0 text-slate-500 border-slate-300 mt-0.5"
                    >
                      {isSuperAdmin ? 'Super Admin' : humanizeRole(portRoles[0]?.role?.name)}
                    </Badge>
                    {currentPortName && (
                      <p className="mt-1 text-[10px] text-slate-400 truncate">{currentPortName}</p>
                    )}
                  </div>
                </button>
              }
            />
          )}
        </div>
      </div>
    </TooltipProvider>
  );
}

export function Sidebar({ portRoles, isSuperAdmin = false, user, ports }: SidebarProps) {
  // Sidebar collapse removed — design preference is the always-expanded
  // form. Forcibly false; the store flag stays for backwards-compat with
  // any code still reading it.
  const sidebarCollapsed = false;
  const currentPortSlug = useUIStore((s) => s.currentPortSlug);

  // Super admins see every section regardless of role rows.
  const hasAdminAccess =
    isSuperAdmin ||
    portRoles.some(
      (pr) =>
        pr.role?.permissions?.admin?.manage_users || pr.role?.permissions?.admin?.manage_settings,
    );

  const hasMarinaAccess =
    isSuperAdmin || portRoles.some((pr) => pr.role?.permissions?.clients?.view);

  const hasResidentialAccess =
    isSuperAdmin ||
    portRoles.some((pr) => pr.residentialAccess || pr.role?.permissions?.residential_clients?.view);

  return (
    <aside
      className={cn(
        'relative hidden md:flex flex-col h-screen border-r border-slate-200 transition-all duration-200 ease-in-out shrink-0 bg-white',
        sidebarCollapsed ? 'w-sidebar-collapsed' : 'w-sidebar',
      )}
    >
      <SidebarContent
        collapsed={sidebarCollapsed}
        portSlug={currentPortSlug ?? undefined}
        portRoles={portRoles}
        isSuperAdmin={isSuperAdmin}
        hasAdminAccess={hasAdminAccess}
        hasMarinaAccess={hasMarinaAccess}
        hasResidentialAccess={hasResidentialAccess}
        user={user}
        ports={ports}
      />
    </aside>
  );
}
