"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import Image from "next/image";
import { useAuth } from "@/lib/auth/auth-context";
import { fetchUserWorkspaces } from "@/lib/api/workspaces";
import { useSidebar } from "./SidebarContext";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface NavBadge {
  label: string;
  pulse?: boolean;
}

interface NavItemConfig {
  href: string;
  label: string;
  icon: React.JSX.Element;
  badge?: NavBadge;
}

interface NavGroup {
  label: string;
  items: NavItemConfig[];
}

interface QueueNotification {
  id: string;
}

// ---------------------------------------------------------------------------
// SVG Icons (16x16 viewBox, stroke="currentColor", strokeWidth="1.5")
// ---------------------------------------------------------------------------

function IconDashboard(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <rect x="1" y="1" width="6" height="6" rx="1" />
      <rect x="9" y="1" width="6" height="6" rx="1" />
      <rect x="1" y="9" width="6" height="6" rx="1" />
      <rect x="9" y="9" width="6" height="6" rx="1" />
    </svg>
  );
}

function IconProjects(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <rect x="1" y="4" width="14" height="10" rx="1.5" />
      <path d="M1 7h14" />
      <path d="M5 4V2.5A.5.5 0 0 1 5.5 2h5a.5.5 0 0 1 .5.5V4" />
    </svg>
  );
}

function IconProjectWorkspace(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <circle cx="8" cy="4" r="2" />
      <circle cx="3" cy="12" r="2" />
      <circle cx="13" cy="12" r="2" />
      <path d="M8 6v2M5 12h6M6 8l-2 2M10 8l2 2" />
    </svg>
  );
}

function IconKanban(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <rect x="1" y="2" width="4" height="12" rx="1" />
      <rect x="6" y="2" width="4" height="12" rx="1" />
      <rect x="11" y="2" width="4" height="12" rx="1" />
    </svg>
  );
}

function IconFileManager(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <path d="M2 3.5A1.5 1.5 0 0 1 3.5 2h4l2 2h3A1.5 1.5 0 0 1 14 5.5v7A1.5 1.5 0 0 1 12.5 14h-9A1.5 1.5 0 0 1 2 12.5v-9z" />
    </svg>
  );
}

function IconLogs(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <path d="M2 4h12M2 8h8M2 12h10" />
    </svg>
  );
}

function IconTerminal(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <rect x="1" y="2" width="14" height="12" rx="1.5" />
      <path d="M4 6l3 3-3 3M9 12h3" />
    </svg>
  );
}

function IconMissionControl(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <circle cx="8" cy="8" r="1.5" />
      <path d="M11 5a4.25 4.25 0 0 1 0 6" />
      <path d="M5 5a4.25 4.25 0 0 0 0 6" />
      <path d="M13.5 2.5a7.75 7.75 0 0 1 0 11" />
      <path d="M2.5 2.5a7.75 7.75 0 0 0 0 11" />
    </svg>
  );
}

function IconSettings(): React.JSX.Element {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      aria-hidden="true"
    >
      <circle cx="8" cy="8" r="2.5" />
      <path d="M8 1v2M8 13v2M1 8h2M13 8h2M3.05 3.05l1.41 1.41M11.54 11.54l1.41 1.41M3.05 12.95l1.41-1.41M11.54 4.46l1.41-1.41" />
    </svg>
  );
}

function IconChevronLeft(): React.JSX.Element {
  return (
    <svg
      width="14"
      height="14"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.75"
      aria-hidden="true"
    >
      <path d="M10 3L5 8l5 5" />
    </svg>
  );
}

function IconChevronRight(): React.JSX.Element {
  return (
    <svg
      width="14"
      height="14"
      viewBox="0 0 16 16"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.75"
      aria-hidden="true"
    >
      <path d="M6 3l5 5-5 5" />
    </svg>
  );
}

// ---------------------------------------------------------------------------
// Nav groups definition
// ---------------------------------------------------------------------------

const NAV_GROUPS: NavGroup[] = [
  {
    label: "Overview",
    items: [
      {
        href: "/",
        label: "Dashboard",
        icon: <IconDashboard />,
        badge: { label: "live", pulse: true },
      },
    ],
  },
  {
    label: "Workspace",
    items: [
      {
        href: "/projects",
        label: "Projects",
        icon: <IconProjects />,
      },
      {
        href: "/workspace",
        label: "Project Workspace",
        icon: <IconProjectWorkspace />,
      },
      {
        href: "/kanban",
        label: "Kanban",
        icon: <IconKanban />,
      },
      {
        href: "/files",
        label: "File Manager",
        icon: <IconFileManager />,
      },
    ],
  },
  {
    label: "Operations",
    items: [
      {
        href: "/logs",
        label: "Logs & Telemetry",
        icon: <IconLogs />,
        badge: { label: "live", pulse: true },
      },
      {
        href: "/terminal",
        label: "Terminal",
        icon: <IconTerminal />,
      },
      {
        href: "/mission-control",
        label: "Mission Control",
        icon: <IconMissionControl />,
      },
    ],
  },
  {
    label: "System",
    items: [
      {
        href: "/settings",
        label: "Settings",
        icon: <IconSettings />,
      },
    ],
  },
];

// ---------------------------------------------------------------------------
// Helper: derive initials from display name
// ---------------------------------------------------------------------------

function getInitials(name: string): string {
  const parts = name.trim().split(/\s+/);
  const first = parts[0] ?? "";
  if (parts.length === 1) {
    return first.slice(0, 2).toUpperCase();
  }
  const last = parts[parts.length - 1] ?? "";
  return ((first[0] ?? "") + (last[0] ?? "")).toUpperCase();
}

// ---------------------------------------------------------------------------
// NavBadge component
// ---------------------------------------------------------------------------

interface NavBadgeProps {
  badge: NavBadge;
}

function NavBadgeChip({ badge }: NavBadgeProps): React.JSX.Element {
  const pulseStyle: React.CSSProperties = badge.pulse
    ? {
        background: "rgba(47,128,255,0.15)",
        color: "var(--primary-l)",
      }
    : {
        background: "var(--surface-2)",
        color: "var(--muted)",
      };

  return (
    <span
      style={{
        marginLeft: "auto",
        fontSize: "0.68rem",
        fontFamily: "var(--mono)",
        padding: "1px 6px",
        borderRadius: "10px",
        display: "inline-flex",
        alignItems: "center",
        gap: "4px",
        flexShrink: 0,
        ...pulseStyle,
      }}
      aria-label={badge.pulse ? `${badge.label} indicator` : badge.label}
    >
      {badge.pulse && (
        <span
          style={{
            display: "inline-block",
            width: "5px",
            height: "5px",
            borderRadius: "50%",
            background: "var(--primary-l)",
            boxShadow: "0 0 4px var(--primary)",
            animation: "pulse 2s cubic-bezier(0.4,0,0.6,1) infinite",
          }}
          aria-hidden="true"
        />
      )}
      {badge.label}
    </span>
  );
}

// ---------------------------------------------------------------------------
// NavItem component
// ---------------------------------------------------------------------------

interface NavItemProps {
  item: NavItemConfig;
  isActive: boolean;
  collapsed: boolean;
}

function NavItem({ item, isActive, collapsed }: NavItemProps): React.JSX.Element {
  const baseStyle: React.CSSProperties = {
    display: "flex",
    alignItems: "center",
    gap: "11px",
    padding: "9px 10px",
    borderRadius: "var(--r-sm)",
    fontSize: "0.875rem",
    fontWeight: 500,
    color: isActive ? "var(--text)" : "var(--muted)",
    background: isActive ? "var(--surface)" : "transparent",
    position: "relative",
    transition: "background 0.12s ease, color 0.12s ease",
    textDecoration: "none",
    justifyContent: collapsed ? "center" : undefined,
    whiteSpace: "nowrap",
    overflow: "hidden",
  };

  const iconStyle: React.CSSProperties = {
    width: "16px",
    height: "16px",
    flexShrink: 0,
    opacity: isActive ? 1 : 0.7,
    transition: "opacity 0.12s ease",
  };

  const content = (
    <>
      {/* Active left accent bar */}
      {isActive && (
        <span
          style={{
            position: "absolute",
            left: 0,
            top: "6px",
            bottom: "6px",
            width: "3px",
            background: "var(--primary)",
            borderRadius: "0 2px 2px 0",
          }}
          aria-hidden="true"
        />
      )}

      {/* Icon */}
      <span style={iconStyle}>{item.icon}</span>

      {/* Label and badge — hidden when collapsed */}
      {!collapsed && (
        <>
          <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis" }}>
            {item.label}
          </span>
          {item.badge !== undefined && <NavBadgeChip badge={item.badge} />}
        </>
      )}
    </>
  );

  const sharedProps = {
    style: baseStyle,
    "aria-current": isActive ? ("page" as const) : undefined,
    title: collapsed ? item.label : undefined,
    onMouseEnter: (e: React.MouseEvent<HTMLElement>): void => {
      if (!isActive) {
        (e.currentTarget as HTMLElement).style.background = "var(--surface)";
        (e.currentTarget as HTMLElement).style.color = "var(--text-2)";
        const iconEl = (e.currentTarget as HTMLElement).querySelector<HTMLElement>(
          "[data-nav-icon]"
        );
        if (iconEl) iconEl.style.opacity = "1";
      }
    },
    onMouseLeave: (e: React.MouseEvent<HTMLElement>): void => {
      if (!isActive) {
        (e.currentTarget as HTMLElement).style.background = "transparent";
        (e.currentTarget as HTMLElement).style.color = "var(--muted)";
        const iconEl = (e.currentTarget as HTMLElement).querySelector<HTMLElement>(
          "[data-nav-icon]"
        );
        if (iconEl) iconEl.style.opacity = "0.7";
      }
    },
  };

  if (item.href.startsWith("#")) {
    return (
      <a href={item.href} {...sharedProps}>
        {content}
      </a>
    );
  }

  return (
    <Link href={item.href} {...sharedProps}>
      {content}
    </Link>
  );
}

// ---------------------------------------------------------------------------
// UserCard component
// ---------------------------------------------------------------------------

interface UserCardProps {
  collapsed: boolean;
}

function UserCard({ collapsed }: UserCardProps): React.JSX.Element {
  const { user } = useAuth();
  const [roleLabel, setRoleLabel] = useState<string>("Member");

  useEffect(() => {
    if (user === null) return;
    fetchUserWorkspaces()
      .then((workspaces) => {
        if (workspaces.length === 0) return;
        const first = workspaces[0];
        if (!first) return;
        const role = first.role;
        setRoleLabel(role.charAt(0) + role.slice(1).toLowerCase());
      })
      .catch(() => {
        // keep default
      });
  }, [user]);

  const displayName = user?.name ?? "User";
  const initials = getInitials(displayName);
  const role = roleLabel;

  return (
    <footer
      style={{
        padding: "12px 10px",
        borderTop: "1px solid var(--border)",
        flexShrink: 0,
      }}
    >
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: "10px",
          padding: "8px 10px",
          borderRadius: "6px",
          cursor: "pointer",
          transition: "background 0.12s ease",
          justifyContent: collapsed ? "center" : undefined,
        }}
        role="button"
        tabIndex={0}
        title={collapsed ? `${displayName} — ${role}` : undefined}
        onMouseEnter={(e): void => {
          (e.currentTarget as HTMLElement).style.background = "var(--surface)";
        }}
        onMouseLeave={(e): void => {
          (e.currentTarget as HTMLElement).style.background = "transparent";
        }}
        onKeyDown={(e): void => {
          if (e.key === "Enter" || e.key === " ") {
            e.preventDefault();
          }
        }}
        aria-label={`User: ${displayName}, Role: ${role}`}
      >
        {/* Avatar */}
        <div
          style={{
            width: "30px",
            height: "30px",
            borderRadius: "50%",
            background: "linear-gradient(135deg, var(--ms-blue-500), var(--ms-purple-500))",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            fontSize: "0.75rem",
            fontWeight: 700,
            color: "#fff",
            flexShrink: 0,
            overflow: "hidden",
          }}
        >
          {user?.image ? (
            <Image
              src={user.image}
              alt={`${displayName} avatar`}
              width={30}
              height={30}
              style={{ width: "100%", height: "100%", objectFit: "cover", borderRadius: "50%" }}
            />
          ) : (
            <span aria-hidden="true">{initials}</span>
          )}
        </div>

        {/* Name and role — hidden when collapsed */}
        {!collapsed && (
          <>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div
                style={{
                  fontSize: "0.83rem",
                  fontWeight: 600,
                  overflow: "hidden",
                  textOverflow: "ellipsis",
                  whiteSpace: "nowrap",
                  color: "var(--text)",
                }}
              >
                {displayName}
              </div>
              <div
                style={{
                  fontSize: "0.72rem",
                  color: "var(--muted)",
                  overflow: "hidden",
                  textOverflow: "ellipsis",
                  whiteSpace: "nowrap",
                }}
              >
                {role}
              </div>
            </div>

            {/* Online status dot */}
            <div
              style={{
                marginLeft: "auto",
                width: "7px",
                height: "7px",
                borderRadius: "50%",
                background: "var(--success)",
                boxShadow: "0 0 6px var(--success)",
                flexShrink: 0,
              }}
              aria-label="Online"
              role="img"
            />
          </>
        )}
      </div>
    </footer>
  );
}

// ---------------------------------------------------------------------------
// CollapseToggle component
// ---------------------------------------------------------------------------

interface CollapseToggleProps {
  collapsed: boolean;
  onToggle: () => void;
}

function CollapseToggle({ collapsed, onToggle }: CollapseToggleProps): React.JSX.Element {
  return (
    <div
      style={{
        padding: "4px 10px 8px",
        display: "flex",
        justifyContent: collapsed ? "center" : "flex-end",
      }}
    >
      <button
        type="button"
        onClick={onToggle}
        aria-label={collapsed ? "Expand sidebar" : "Collapse sidebar"}
        title={collapsed ? "Expand sidebar" : "Collapse sidebar"}
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          width: "26px",
          height: "26px",
          borderRadius: "6px",
          color: "var(--muted)",
          transition: "background 0.12s ease, color 0.12s ease",
          cursor: "pointer",
          flexShrink: 0,
        }}
        onMouseEnter={(e): void => {
          (e.currentTarget as HTMLElement).style.background = "var(--surface)";
          (e.currentTarget as HTMLElement).style.color = "var(--text-2)";
        }}
        onMouseLeave={(e): void => {
          (e.currentTarget as HTMLElement).style.background = "transparent";
          (e.currentTarget as HTMLElement).style.color = "var(--muted)";
        }}
      >
        {collapsed ? <IconChevronRight /> : <IconChevronLeft />}
      </button>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main AppSidebar component
// ---------------------------------------------------------------------------

/**
 * Application sidebar — navigation groups, collapse toggle, and user card.
 * Logo lives in AppHeader per MS15 design spec.
 */
export function AppSidebar(): React.JSX.Element {
  const pathname = usePathname();
  const { collapsed, toggleCollapsed, mobileOpen, setMobileOpen, isMobile } = useSidebar();
  const [missionControlBadgeCount, setMissionControlBadgeCount] = useState<number>(0);

  useEffect(() => {
    let isActive = true;

    const loadNotificationCount = async (): Promise<void> => {
      try {
        const response = await fetch("/api/orchestrator/api/queue/notifications", {
          method: "GET",
        });

        if (!response.ok) {
          return;
        }

        const payload = (await response.json()) as QueueNotification[];
        if (isActive) {
          setMissionControlBadgeCount(Array.isArray(payload) ? payload.length : 0);
        }
      } catch {
        // Ignore badge failures in the nav.
      }
    };

    void loadNotificationCount();

    if (typeof EventSource === "undefined") {
      return (): void => {
        isActive = false;
      };
    }

    const source = new EventSource("/api/orchestrator/queue/notifications/stream");

    source.onmessage = (event: MessageEvent<string>): void => {
      try {
        const payload = JSON.parse(event.data) as QueueNotification[];
        if (isActive) {
          setMissionControlBadgeCount(Array.isArray(payload) ? payload.length : 0);
        }
      } catch {
        // Ignore malformed badge updates.
      }
    };

    return (): void => {
      isActive = false;
      source.close();
    };
  }, []);

  const navGroups = useMemo(
    () =>
      NAV_GROUPS.map((group) => ({
        ...group,
        items: group.items.map((item) =>
          item.href === "/mission-control" && missionControlBadgeCount > 0
            ? {
                ...item,
                badge: { label: String(missionControlBadgeCount) },
              }
            : item
        ),
      })),
    [missionControlBadgeCount]
  );

  return (
    <>
      {/* Mobile backdrop — rendered behind the sidebar when open on mobile */}
      {isMobile && mobileOpen && (
        <div
          aria-hidden="true"
          onClick={() => {
            setMobileOpen(false);
          }}
          style={{
            position: "fixed",
            inset: 0,
            top: "var(--topbar-h)",
            background: "rgba(0,0,0,0.5)",
            zIndex: 140,
          }}
        />
      )}

      <aside
        id="app-sidebar"
        className="app-sidebar"
        data-collapsed={collapsed ? "true" : undefined}
        data-mobile-open={mobileOpen ? "true" : undefined}
        aria-label="Application navigation"
      >
        {/* Sidebar body — scrollable nav area */}
        <nav
          style={{
            flex: 1,
            overflowY: "auto",
            overflowX: "hidden",
            padding: "10px 10px",
          }}
          aria-label="Main navigation"
        >
          {navGroups.map((group) => (
            <div key={group.label} style={{ marginBottom: "18px" }}>
              {/* Group label — hidden when collapsed */}
              {!collapsed && (
                <p
                  style={{
                    fontSize: "0.67rem",
                    fontWeight: 600,
                    textTransform: "uppercase",
                    letterSpacing: "0.09em",
                    color: "var(--muted)",
                    padding: "0 10px",
                    marginBottom: "4px",
                    userSelect: "none",
                  }}
                >
                  {group.label}
                </p>
              )}

              {/* Nav items */}
              <ul style={{ listStyle: "none", margin: 0, padding: 0 }}>
                {group.items.map((item) => {
                  const isActive =
                    item.href === "/"
                      ? pathname === "/"
                      : item.href.startsWith("#")
                        ? false
                        : pathname === item.href || pathname.startsWith(item.href + "/");

                  return (
                    <li key={item.href}>
                      <NavItem item={item} isActive={isActive} collapsed={collapsed} />
                    </li>
                  );
                })}
              </ul>
            </div>
          ))}

          {/* Collapse toggle — anchored at bottom of nav */}
          <CollapseToggle collapsed={collapsed} onToggle={toggleCollapsed} />
        </nav>

        {/* User card footer */}
        <UserCard collapsed={collapsed} />
      </aside>
    </>
  );
}
