import { ChevronRight, Home, LogOut, Plus, Settings, User } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { Link, Outlet, useLocation } from 'react-router-dom';

import { CreateWorkspaceModal } from '@/components/CreateWorkspaceModal';
import { SettingsModal } from '@/components/SettingsModal';
import { useUserContext } from '@/contexts/UserContext';
import { useLogout } from '@/hooks/auth/useLogout';
import { useWorkspaceList } from '@/hooks/workspace/useWorkspaceList';
import { cn } from '@/lib/utils';

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

const RESERVED_PATHS = new Set(['auth', 'api', 'vite']);

/** Extract workspace name from `/:name` or `/:name/...` */
function activeWorkspaceName(pathname: string): string | null {
  const first = pathname.split('/').filter(Boolean)[0];
  if (!first || RESERVED_PATHS.has(first)) return null;
  return first;
}

// ---------------------------------------------------------------------------
// WorkspaceIcon
// ---------------------------------------------------------------------------

interface WorkspaceIconProps {
  name: string;
  avatarUrl?: string | null;
  active?: boolean;
}

function WorkspaceIcon({ name, avatarUrl, active }: WorkspaceIconProps) {
  const initials = name
    .split(/\s+/)
    .slice(0, 2)
    .map((w) => w[0])
    .join('')
    .toUpperCase();

  return (
    <Link
      to={`/${name}`}
      className={cn(
        'group relative flex size-12 shrink-0 items-center justify-center rounded-3xl transition-all duration-200',
        'hover:rounded-2xl hover:bg-sidebar-primary hover:text-sidebar-primary-foreground',
        active
          ? 'rounded-2xl bg-sidebar-primary text-sidebar-primary-foreground'
          : 'bg-sidebar-accent text-sidebar-foreground/60',
      )}
    >
      {active && (
        <span className="absolute -left-3 top-1/2 h-10 w-1 -translate-y-1/2 rounded-r-full bg-sidebar-foreground" />
      )}
      {avatarUrl ? (
        <img src={avatarUrl} alt={name} className="size-full rounded-[inherit] object-cover" />
      ) : (
        <span className="text-[13px] font-semibold">{initials}</span>
      )}
    </Link>
  );
}

// ---------------------------------------------------------------------------
// WorkspaceSidebar (leftmost icon bar)
// ---------------------------------------------------------------------------

function WorkspaceSidebar({
  onSettingsOpen,
  onCreateWorkspace,
  className,
}: {
  onSettingsOpen: () => void;
  onCreateWorkspace: () => void;
  className?: string;
}) {
  const { data: workspaces } = useWorkspaceList();
  const location = useLocation();
  const activeWsName = activeWorkspaceName(location.pathname);

  const list = workspaces ?? [];

  return (
    <div
      className={cn(
        'flex h-full w-[72px] shrink-0 flex-col items-center gap-2 bg-sidebar px-3 py-3',
        className,
      )}
    >
      {/* Home */}
      <Link
        to="/"
        className={cn(
          'flex size-12 shrink-0 items-center justify-center rounded-3xl transition-all duration-200',
          'hover:rounded-2xl hover:bg-sidebar-primary hover:text-sidebar-primary-foreground',
          'bg-sidebar-accent text-sidebar-foreground/60',
        )}
      >
        <Home className="size-6" />
      </Link>

      <div className="h-px w-8 shrink-0 bg-sidebar-border" />

      {/* Workspace list */}
      <div className="flex flex-1 flex-col items-center gap-2 overflow-y-auto py-1">
        {list.map((ws) => (
          <WorkspaceIcon
            key={ws.id}
            name={ws.name}
            avatarUrl={ws.avatar_url}
            active={activeWsName === ws.name}
          />
        ))}
      </div>

      {/* Add workspace */}
      <button
        type="button"
        onClick={onCreateWorkspace}
        className="flex size-12 shrink-0 items-center justify-center rounded-3xl bg-sidebar-accent text-sidebar-primary transition-all duration-200 hover:rounded-2xl hover:bg-sidebar-primary hover:text-sidebar-primary-foreground"
      >
        <Plus className="size-5" />
      </button>

      {/* User area */}
      <UserArea onSettingsOpen={onSettingsOpen} />
    </div>
  );
}

// ---------------------------------------------------------------------------
// UserPanel (popover)
// ---------------------------------------------------------------------------

function UserPanel({
  open,
  onClose,
  onSettingsOpen,
}: {
  open: boolean;
  onClose: () => void;
  onSettingsOpen: () => void;
}) {
  const { user } = useUserContext();
  const logoutMutation = useLogout();
  const panelRef = useRef<HTMLDivElement>(null);

  const avatarUrl = user?.avatar_url;
  const username = user?.username ?? 'User';
  const displayName = user?.display_name ?? username;
  const initials = username.slice(0, 2).toUpperCase();

  useEffect(() => {
    if (!open) return;

    function handleClickOutside(e: MouseEvent) {
      if (panelRef.current && !panelRef.current.contains(e.target as Node)) {
        onClose();
      }
    }

    function handleEscape(e: KeyboardEvent) {
      if (e.key === 'Escape') onClose();
    }

    document.addEventListener('mousedown', handleClickOutside);
    document.addEventListener('keydown', handleEscape);
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
      document.removeEventListener('keydown', handleEscape);
    };
  }, [open, onClose]);

  if (!open) return null;

  return (
    <>
      <button
        type="button"
        aria-label="Close user panel"
        className="fixed inset-0 z-40 cursor-default border-0 bg-transparent p-0"
        onClick={onClose}
      />
      <div
        ref={panelRef}
        className="absolute left-14 bottom-0 z-50 flex w-[320px] flex-col overflow-hidden rounded-2xl bg-sidebar shadow-2xl ring-1 ring-sidebar-border animate-in zoom-in-95 fade-in origin-bottom-left"
      >
        {/* Header */}
        <div className="bg-sidebar-accent px-4 pb-4 pt-5">
          <div className="flex items-center gap-4">
            <div className="flex size-[60px] shrink-0 items-center justify-center rounded-full bg-sidebar-primary">
              {avatarUrl ? (
                <img
                  src={avatarUrl}
                  alt={username}
                  className="size-full rounded-full object-cover"
                />
              ) : (
                <span className="text-xl font-semibold text-sidebar-primary-foreground">
                  {initials}
                </span>
              )}
            </div>
            <div className="min-w-0 flex-1">
              <p className="truncate text-base font-semibold text-sidebar-foreground">
                {displayName}
              </p>
              <p className="truncate text-sm text-sidebar-foreground/60">@{username}</p>
            </div>
          </div>

          <button
            type="button"
            onClick={() => {
              onClose();
              onSettingsOpen();
            }}
            className="mt-3 flex w-full items-center justify-between rounded-xl bg-sidebar px-4 py-2.5 text-sm text-sidebar-foreground transition-colors hover:bg-sidebar-accent"
          >
            <span>Manage your account</span>
            <ChevronRight className="size-4 text-sidebar-foreground/60" />
          </button>
        </div>

        {/* Menu items */}
        <div className="px-2 py-1.5">
          <button
            type="button"
            className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-sidebar-foreground transition-colors hover:bg-sidebar-accent"
            onClick={onClose}
          >
            <div className="flex size-9 items-center justify-center rounded-full bg-sidebar-accent">
              <User className="size-[18px] text-sidebar-foreground/60" />
            </div>
            <span>Profile</span>
          </button>

          <button
            type="button"
            className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-sidebar-foreground transition-colors hover:bg-sidebar-accent"
            onClick={() => {
              onClose();
              onSettingsOpen();
            }}
          >
            <div className="flex size-9 items-center justify-center rounded-full bg-sidebar-accent">
              <Settings className="size-[18px] text-sidebar-foreground/60" />
            </div>
            <span>Settings</span>
          </button>
        </div>

        <div className="mx-3 border-t border-sidebar-border" />

        {/* Log out */}
        <div className="px-2 py-1.5">
          <button
            type="button"
            onClick={() => logoutMutation.mutate()}
            disabled={logoutMutation.isPending}
            className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-sidebar-foreground transition-colors hover:bg-sidebar-accent"
          >
            <div className="flex size-9 items-center justify-center rounded-full bg-sidebar-accent">
              <LogOut className="size-[18px] text-destructive" />
            </div>
            <span>{logoutMutation.isPending ? 'Logging out…' : 'Log out'}</span>
          </button>
        </div>

        {/* Footer */}
        <div className="px-3 pb-3">
          <p className="text-center text-[11px] text-sidebar-foreground/30">
            GitDataAi &middot; Privacy &middot; Terms
          </p>
        </div>
      </div>
    </>
  );
}

// ---------------------------------------------------------------------------
// UserArea (avatar button at bottom of icon sidebar)
// ---------------------------------------------------------------------------

function UserArea({ onSettingsOpen }: { onSettingsOpen: () => void }) {
  const { user } = useUserContext();
  const [panelOpen, setPanelOpen] = useState(false);

  const avatarUrl = user?.avatar_url;
  const username = user?.username ?? 'User';
  const initials = username.slice(0, 2).toUpperCase();

  return (
    <div className="relative mt-auto">
      <button
        type="button"
        onClick={() => setPanelOpen((v) => !v)}
        className="flex size-12 shrink-0 items-center justify-center rounded-3xl bg-sidebar-accent text-sidebar-foreground/60 transition-all duration-200 hover:rounded-2xl hover:bg-sidebar-primary hover:text-sidebar-primary-foreground"
      >
        {avatarUrl ? (
          <img
            src={avatarUrl}
            alt={username}
            className="size-full rounded-[inherit] object-cover"
          />
        ) : (
          <span className="text-[13px] font-semibold">{initials}</span>
        )}
      </button>

      <UserPanel
        open={panelOpen}
        onClose={() => setPanelOpen(false)}
        onSettingsOpen={onSettingsOpen}
      />
    </div>
  );
}

// ---------------------------------------------------------------------------
// RootLayout
// ---------------------------------------------------------------------------

export function RootLayout() {
  const [settingsOpen, setSettingsOpen] = useState(false);
  const [createWsOpen, setCreateWsOpen] = useState(false);

  return (
    <div className="flex h-screen overflow-hidden bg-sidebar">
      <WorkspaceSidebar
        onSettingsOpen={() => setSettingsOpen(true)}
        onCreateWorkspace={() => setCreateWsOpen(true)}
        className="border-r border-sidebar-border"
      />
      <div className="flex flex-1 flex-col min-w-0 pt-0.5">
        <Outlet />
      </div>
      <SettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} />
      <CreateWorkspaceModal open={createWsOpen} onClose={() => setCreateWsOpen(false)} />
    </div>
  );
}
