import { useState } from "react";
import { Link, useLocation } from "react-router";
import { Home, LogOut, Plus, Settings } from "lucide-react";
import { useQuery } from "@tanstack/react-query";

import { client, type WorkspaceResponse } from "@/client";
import { CreateWorkspaceDialog } from "@/page/workspace/create";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { cn } from "@/lib/utils";
import { workspaceColor, workspaceInitial } from "./shared";
import { useSettingsModal } from "@/components/settings/SettingsModalContext";
import { useAuth } from "@/context/auth-context";

function WorkspaceIcon({
  active,
  workspace,
}: {
  active: boolean;
  workspace: WorkspaceResponse;
}) {
  return (
    <Link
      aria-label={workspace.name}
      className="group relative grid size-10 place-items-center"
      title={workspace.name}
      to={`/${workspace.name}/repos`}
    >
      <span
        className={cn(
          "absolute -left-[11px] h-2 w-[3px] rounded-r-full bg-foreground opacity-0 transition-[height,opacity] group-hover:h-4 group-hover:opacity-60",
          active && "h-6 opacity-100",
        )}
      />
      <span
        className={cn(
          "grid size-9 place-items-center overflow-hidden rounded-xl bg-gradient-to-br text-[12px] font-bold text-white ring-1 ring-black/[0.06] transition-[border-radius,box-shadow]",
          workspaceColor(workspace.name),
          active && "rounded-lg ring-2 ring-primary/20",
        )}
      >
        {workspace.avatar_url ? (
          <img
            alt=""
            className="size-full object-cover"
            src={workspace.avatar_url}
          />
        ) : (
          workspaceInitial(workspace.name)
        )}
      </span>
    </Link>
  );
}

function UserAvatar({ name, avatarUrl }: { name: string; avatarUrl?: string | null }) {
  const initial = name.charAt(0).toUpperCase();

  if (avatarUrl) {
    return <img alt={name} className="size-full object-cover" src={avatarUrl} />;
  }

  return (
    <span className="flex size-full items-center justify-center bg-gradient-to-br from-purple-500 via-pink-500 to-orange-400 text-[12px] font-bold text-white">
      {initial}
    </span>
  );
}

function SettingsRailButton() {
  const [isOpen, setIsOpen] = useState(false);
  const { openSettingsModal } = useSettingsModal();
  const { me } = useAuth();

  const userName = me?.display_name || me?.username || "User";
  const userHandle = me?.username ? `@${me.username}` : "Personal account";

  const handleLogout = () => {
    void client.authLogout().finally(() => {
      window.location.href = "/";
    });
  };

  return (
    <DropdownMenu onOpenChange={setIsOpen}>
      <div className="group relative">
        <DropdownMenuTrigger
          render={
            <button
              aria-label="Account menu"
              className="inline-flex size-9 shrink-0 cursor-pointer items-center justify-center rounded-xl border border-border bg-card p-1 transition-[background-color,border-color,box-shadow] duration-200 hover:bg-accent hover:shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/30"
              title="Account menu"
              type="button"
            />
          }
        >
          <span className="size-7 overflow-hidden rounded-full ring-1 ring-black/[0.06] dark:ring-white/[0.06]">
            <UserAvatar avatarUrl={me?.avatar_url} name={userName} />
          </span>
        </DropdownMenuTrigger>

        <div
          className={cn(
            "absolute top-1/2 -right-2.5 -translate-y-1/2 transition-opacity duration-200",
            isOpen ? "opacity-100" : "opacity-0 group-hover:opacity-60",
          )}
        >
          <svg
            aria-hidden="true"
            className={cn(
              "transition-[color,transform] duration-200",
              isOpen
                ? "scale-110 text-primary"
                : "text-muted-foreground/50 group-hover:text-muted-foreground",
            )}
            fill="none"
            height="20"
            viewBox="0 0 12 24"
            width="10"
          >
            <path
              d="M2 4C6 8 6 16 2 20"
              fill="none"
              stroke="currentColor"
              strokeLinecap="round"
              strokeWidth="1.5"
            />
          </svg>
        </div>

        <DropdownMenuContent
          align="end"
          className="w-64 origin-bottom-left rounded-2xl border border-border bg-popover/95 p-2 text-popover-foreground shadow-xl shadow-foreground/5 backdrop-blur-sm"
          side="right"
          sideOffset={12}
        >
          <div className="flex items-center gap-3 rounded-xl p-3">
            <div className="size-10 shrink-0 overflow-hidden rounded-full ring-1 ring-black/[0.06] dark:ring-white/[0.06]">
              <UserAvatar avatarUrl={me?.avatar_url} name={userName} />
            </div>
            <div className="min-w-0 flex-1">
              <div className="truncate text-sm font-medium leading-tight tracking-tight text-foreground">
                {userName}
              </div>
              <div className="truncate text-xs leading-tight tracking-tight text-muted-foreground">
                {userHandle}
              </div>
            </div>
          </div>

          <DropdownMenuSeparator className="my-2 bg-gradient-to-r from-transparent via-zinc-200 to-transparent dark:via-zinc-800" />

          <DropdownMenuItem
            className="group flex cursor-pointer items-center gap-3 rounded-xl border border-transparent p-3 transition-[background-color,border-color,box-shadow] duration-200 hover:border-border hover:bg-accent hover:shadow-sm"
            onClick={() => window.setTimeout(() => openSettingsModal(), 0)}
          >
            <Settings className="size-4 text-muted-foreground transition-colors group-hover:text-foreground" />
            <span className="text-sm font-medium leading-tight tracking-tight text-foreground transition-colors group-hover:text-foreground">
              Settings
            </span>
          </DropdownMenuItem>

          <DropdownMenuSeparator className="my-2 bg-gradient-to-r from-transparent via-zinc-200 to-transparent dark:via-zinc-800" />

          <DropdownMenuItem
            className="group flex cursor-pointer items-center gap-3 rounded-xl border border-transparent bg-destructive/10 p-3 transition-[background-color,border-color,box-shadow] duration-200 hover:border-destructive/30 hover:bg-destructive/15 hover:shadow-sm"
            onClick={handleLogout}
          >
            <LogOut className="size-4 text-destructive transition-colors" />
            <span className="text-sm font-medium leading-tight text-destructive">
              Logout
            </span>
          </DropdownMenuItem>
        </DropdownMenuContent>
      </div>
    </DropdownMenu>
  );
}

function RailButton({
  label,
  to,
  children,
}: {
  label: string;
  to: string;
  children: React.ReactNode;
}) {
  return (
    <Link
      aria-label={label}
      className="inline-flex size-9 shrink-0 items-center justify-center rounded-xl border border-border bg-card text-muted-foreground transition-[background-color,color,border-color] hover:bg-accent hover:text-foreground"
      title={label}
      to={to}
    >
      {children}
    </Link>
  );
}

function WorkspaceSkeleton() {
  return (
    <div className="grid gap-2">
      {Array.from({ length: 4 }).map((_, index) => (
        <div
          className="size-9 animate-pulse rounded-xl bg-muted"
          key={index}
        />
      ))}
    </div>
  );
}

export function WorkspaceRail() {
  const location = useLocation();
  const { data: workspaces = [], isLoading } = useQuery({
    queryKey: ["workspace", "my"],
    queryFn: async () => {
      const response = await client.workspaceMyWorkspaces();
      return response.data;
    },
    retry: false,
  });

  return (
    <aside className="flex h-svh w-[72px] shrink-0 flex-col items-center border-r border-border bg-background py-5">
      <RailButton label="Home" to="/">
        <Home className="size-[18px]" />
      </RailButton>

      <div className="my-3 h-px w-7 bg-border" />

      <nav
        aria-label="Workspaces"
        className="flex min-h-0 flex-1 flex-col items-center gap-2.5 overflow-y-auto overscroll-contain px-2"
      >
        {isLoading ? (
          <WorkspaceSkeleton />
        ) : (
          workspaces.map((workspace) => (
            <WorkspaceIcon
              active={location.pathname.startsWith(`/${workspace.name}`)}
              key={workspace.name}
              workspace={workspace}
            />
          ))
        )}

        <CreateWorkspaceDialog>
          <Button
            aria-label="Create workspace"
            className="size-9 rounded-xl border-border bg-card text-muted-foreground transition-[background-color,color,border-color] hover:bg-accent hover:text-foreground"
            size="icon"
            variant="outline"
          >
            <Plus className="size-[18px]" />
          </Button>
        </CreateWorkspaceDialog>
      </nav>

      <div className="mt-3">
        <SettingsRailButton />
      </div>
    </aside>
  );
}

export default function NavShell({ children }: { children?: React.ReactNode }) {
  return (
    <div className="flex h-svh overflow-hidden bg-background text-foreground">
      <WorkspaceRail />
      <div className="min-w-0 flex-1">{children}</div>
    </div>
  );
}
