import { useState } from 'react'
import { Link, useLocation } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import {
  Home,
  Database,
  FileText,
  ClipboardList,
  Inbox,
  Webhook,
  ScrollText,
  Search,
  GitBranch,
  type LucideIcon,
} from 'lucide-react'
import { useAuth } from 'react-oidc-context'
import { useCanMutate } from '@/auth/useCanMutate'
import { useDictionaries, useMyDrafts } from '@/api/queries'
import { Sheet, SheetContent } from '@/ui'
import { cn } from '@/lib/utils'

/**
 * Sidebar — 220px nav rail per handoff design system.
 *
 * Structure (top-to-bottom):
 *  - Logo block (ORDINIS wordmark в Tektur)
 *  - Section: navigation rail (Home, Справочники [count], Поиск, Граф)
 *  - Section: admin-only (Мои черновики, На ревью [count], Аудит, Outbox, Webhooks)
 *  - User profile (bottom, sticky)
 *
 * Responsive: на <1024px collapse в icon-only rail (56px). Smaller — overlay
 * drawer (TODO Stage 3.x). Сейчас always-visible — main grid сам адаптирует.
 */

type NavSection = {
  /** Optional .cap header above items. */
  label?: string
  items: NavItem[]
}

type NavItem = {
  to: string
  label: string
  icon: LucideIcon
  /** Badge content справа (число pending / counts). */
  badge?: React.ReactNode
  /** Только аутентифицированным пользователям. */
  authRequired?: boolean
}

export function Sidebar() {
  const { t } = useTranslation()
  const auth = useAuth()
  const canMutate = useCanMutate()
  const dictsQuery = useDictionaries()
  // Loaded just for сидбар counter — light request, кэшируется.
  const myDrafts = useMyDrafts(0, 1)

  const dictsCount = dictsQuery.data?.length ?? 0
  const myDraftsCount = myDrafts.data?.totalElements ?? 0
  // Reviews count бэйдж — TODO когда будет cheap endpoint /drafts/pending/count.
  // Сейчас GET /drafts/pending возвращает page, paged запрос на каждый mount
  // sidebar'а — overkill. Skip badge.
  const reviewsCount = 0

  const sections: NavSection[] = [
    {
      items: [
        { to: '/', label: t('nav.home'), icon: Home },
        {
          to: '/dictionaries',
          label: t('nav.dictionaries'),
          icon: Database,
          badge: dictsCount > 0 ? dictsCount : undefined,
        },
        { to: '/search', label: t('nav.search'), icon: Search },
        // Graph view — Stage 3.3 placeholder. Когда d3-force готов.
        { to: '/graph', label: t('nav.graph'), icon: GitBranch },
      ],
    },
    {
      label: t('nav.section.workflow'),
      items: [
        {
          to: '/my-drafts',
          label: t('nav.myDrafts'),
          icon: FileText,
          badge: myDraftsCount > 0 ? myDraftsCount : undefined,
          authRequired: true,
        },
        {
          to: '/reviews',
          label: t('nav.reviews'),
          icon: ClipboardList,
          badge: reviewsCount > 0 ? reviewsCount : undefined,
          authRequired: true,
        },
      ],
    },
    {
      label: t('nav.section.admin'),
      items: [
        { to: '/audit', label: t('nav.audit'), icon: ScrollText, authRequired: true },
        { to: '/outbox', label: t('nav.outbox'), icon: Inbox, authRequired: true },
        { to: '/webhooks', label: t('nav.webhooks'), icon: Webhook, authRequired: true },
      ],
    },
  ]

  const visibleSections = sections
    .map((s) => ({
      ...s,
      items: s.items.filter((i) => !i.authRequired || canMutate),
    }))
    .filter((s) => s.items.length > 0)

  // Sidebar collapsed mode — per handoff prototype 'Свернуть' button bottom-left.
  // Persists в localStorage. Collapsed = icon-only 56px rail, expanded = 220px.
  const [collapsed, setCollapsed] = useState<boolean>(() => {
    if (typeof window === 'undefined') return false
    return window.localStorage.getItem('ord-sidebar-collapsed') === '1'
  })
  const toggleCollapsed = () => {
    setCollapsed((prev) => {
      const next = !prev
      try {
        window.localStorage.setItem('ord-sidebar-collapsed', next ? '1' : '0')
      } catch {
        // localStorage может быть disabled
      }
      return next
    })
  }

  return (
    <aside
      className={cn(
        'hidden lg:flex shrink-0 flex-col border-r border-line bg-surface transition-[width] duration-200',
        collapsed ? 'w-[56px]' : 'w-[220px]',
      )}
    >
      <SidebarContent
        sections={visibleSections}
        auth={auth}
        collapsed={collapsed}
        onToggleCollapsed={toggleCollapsed}
      />
    </aside>
  )
}

/**
 * SidebarContent — внутренности (logo + nav + user). Используется в desktop
 * rail (Sidebar) И в mobile drawer (MobileSidebar) — DRY.
 */
function SidebarContent({
  sections,
  auth,
  onNavigate,
  collapsed = false,
  onToggleCollapsed,
}: {
  sections: NavSection[]
  auth: ReturnType<typeof useAuth>
  /** Called после клика на nav item — для close drawer в mobile mode. */
  onNavigate?: () => void
  /** Desktop collapse state — affects labels visibility и width. */
  collapsed?: boolean
  /** Toggle button handler. When undefined — collapse button hidden (mobile). */
  onToggleCollapsed?: () => void
}) {
  const { t } = useTranslation()
  return (
    <>
      {/* Logo block per redesign prototype: circle (accent) + ORDINIS + MDM mute */}
      <div
        className={cn(
          'h-14 flex items-center border-b border-line shrink-0',
          collapsed ? 'justify-center px-2' : 'px-5 gap-2',
        )}
      >
        <Link
          to="/"
          className="flex items-center gap-2 hover:opacity-80 transition-opacity focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm"
          onClick={onNavigate}
          title="ORDINIS MDM"
        >
          {/* Brand orbit icon per redesign/ui-kit.html .brand SVG:
              outer ring r=13 + inner faded ring r=6 + orbit dot offset right cx=22.5. */}
          <svg
            width="24"
            height="24"
            viewBox="0 0 32 32"
            fill="none"
            xmlns="http://www.w3.org/2000/svg"
            aria-hidden
            className="shrink-0 text-accent"
          >
            <circle cx="16" cy="16" r="13" stroke="currentColor" strokeWidth="1.6" />
            <circle cx="16" cy="16" r="6" stroke="currentColor" strokeWidth="1" opacity="0.45" />
            <circle cx="22.5" cy="16" r="2.2" fill="currentColor" />
          </svg>
          {!collapsed && (
            <span className="font-display text-[15px] font-semibold leading-none tracking-[0.22em] text-ink inline-flex items-baseline gap-1.5">
              ORDINIS
              <span className="text-mute font-normal tracking-[0.32em] text-[0.78em]">MDM</span>
            </span>
          )}
        </Link>
      </div>

      {/* Nav sections */}
      <nav className="flex-1 overflow-y-auto py-3 px-2 flex flex-col gap-4">
        {sections.map((section, idx) => (
          <div key={idx} className="flex flex-col gap-0.5">
            {section.label && !collapsed && (
              <div className="text-cap px-3 py-1 text-mute">{section.label}</div>
            )}
            {section.items.map((item) => (
              <SidebarLink key={item.to} {...item} onClick={onNavigate} collapsed={collapsed} />
            ))}
          </div>
        ))}
      </nav>

      {/* User block — sticky bottom */}
      {auth.isAuthenticated && auth.user?.profile && (
        <div
          className={cn(
            'border-t border-line py-3 flex items-center gap-2 shrink-0',
            collapsed ? 'px-2 justify-center' : 'px-3',
          )}
          title={String(
            auth.user.profile.preferred_username ||
              auth.user.profile.name ||
              auth.user.profile.email ||
              'user',
          )}
        >
          <div className="size-8 rounded-full bg-accent text-on-accent inline-flex items-center justify-center text-cell font-semibold shrink-0">
            {String(
              auth.user.profile.preferred_username ||
                auth.user.profile.name ||
                'U',
            )
              .charAt(0)
              .toUpperCase()}
          </div>
          {!collapsed && (
            <div className="min-w-0 flex-1">
              <div className="text-cell font-medium text-ink truncate">
                {String(
                  auth.user.profile.preferred_username ||
                    auth.user.profile.name ||
                    auth.user.profile.email ||
                    'user',
                )}
              </div>
              {auth.user.profile.email && (
                <div className="text-cell text-mute truncate">{String(auth.user.profile.email)}</div>
              )}
            </div>
          )}
        </div>
      )}

      {/* Collapse toggle — desktop only (mobile uses Sheet close ×) */}
      {onToggleCollapsed && (
        <button
          type="button"
          onClick={onToggleCollapsed}
          aria-label={collapsed
            ? t('sidebar.expand', { defaultValue: 'Развернуть' })
            : t('sidebar.collapse', { defaultValue: 'Свернуть' })
          }
          title={collapsed ? t('sidebar.expand', { defaultValue: 'Развернуть' }) : t('sidebar.collapse', { defaultValue: 'Свернуть' })}
          className={cn(
            'border-t border-line shrink-0 h-8 flex items-center gap-2 text-cap text-mute hover:text-ink hover:bg-surface-2 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
            collapsed ? 'justify-center' : 'px-4',
          )}
        >
          <span aria-hidden>{collapsed ? '›' : '‹'}</span>
          {!collapsed && (
            <span>{t('sidebar.collapse', { defaultValue: 'Свернуть' })}</span>
          )}
        </button>
      )}
    </>
  )
}

/**
 * MobileSidebar — Sheet с тем же содержимым что desktop Sidebar. Открывается
 * через hamburger button в TopBar (<1024px), закрывается на: backdrop click,
 * Escape, или клик на любой nav item (auto-close, привычная mobile UX).
 *
 * <p>Hooks logic дублируется (auth, dictsCount etc.) — нужно для filter
 * auth-required sections. Можно вынести в useSidebarSections() hook
 * следующим refactor.
 */
export function MobileSidebar({ open, onClose }: { open: boolean; onClose: () => void }) {
  const { t } = useTranslation()
  const auth = useAuth()
  const canMutate = useCanMutate()
  const dictsQuery = useDictionaries()
  const myDrafts = useMyDrafts(0, 1)

  const dictsCount = dictsQuery.data?.length ?? 0
  const myDraftsCount = myDrafts.data?.totalElements ?? 0
  const reviewsCount = 0

  const sections: NavSection[] = [
    {
      items: [
        { to: '/', label: t('nav.home'), icon: Home },
        {
          to: '/dictionaries',
          label: t('nav.dictionaries'),
          icon: Database,
          badge: dictsCount > 0 ? dictsCount : undefined,
        },
        { to: '/search', label: t('nav.search'), icon: Search },
        { to: '/graph', label: t('nav.graph'), icon: GitBranch },
      ],
    },
    {
      label: t('nav.section.workflow'),
      items: [
        {
          to: '/my-drafts',
          label: t('nav.myDrafts'),
          icon: FileText,
          badge: myDraftsCount > 0 ? myDraftsCount : undefined,
          authRequired: true,
        },
        {
          to: '/reviews',
          label: t('nav.reviews'),
          icon: ClipboardList,
          badge: reviewsCount > 0 ? reviewsCount : undefined,
          authRequired: true,
        },
      ],
    },
    {
      label: t('nav.section.admin'),
      items: [
        { to: '/audit', label: t('nav.audit'), icon: ScrollText, authRequired: true },
        { to: '/outbox', label: t('nav.outbox'), icon: Inbox, authRequired: true },
        { to: '/webhooks', label: t('nav.webhooks'), icon: Webhook, authRequired: true },
      ],
    },
  ]
  const visibleSections = sections
    .map((s) => ({ ...s, items: s.items.filter((i) => !i.authRequired || canMutate) }))
    .filter((s) => s.items.length > 0)

  return (
    <Sheet open={open} onOpenChange={(v) => { if (!v) onClose() }}>
      <SheetContent
        side="left"
        size="md"
        className="!w-[260px] !max-w-[260px] !p-0 !gap-0 flex flex-col bg-surface"
      >
        <SidebarContent sections={visibleSections} auth={auth} onNavigate={onClose} />
      </SheetContent>
    </Sheet>
  )
}

function SidebarLink({
  to,
  label,
  icon: Icon,
  badge,
  onClick,
  collapsed = false,
}: NavItem & { onClick?: () => void; collapsed?: boolean }) {
  const location = useLocation()
  const active =
    to === '/'
      ? location.pathname === '/'
      : location.pathname === to || location.pathname.startsWith(to + '/')

  return (
    <Link
      to={to}
      onClick={onClick}
      title={collapsed ? (typeof label === 'string' ? label : undefined) : undefined}
      className={cn(
        // text-body = 13px workhorse per handoff (см. styles.css @utility).
        'group flex items-center rounded-md text-body transition-colors',
        collapsed ? 'justify-center h-9 mx-1' : 'gap-2.5 px-3 py-1.5',
        active
          ? 'bg-accent-bg text-accent font-medium'
          : 'text-ink-2 hover:text-ink hover:bg-surface-2',
      )}
    >
      <Icon size={collapsed ? 18 : 15} strokeWidth={1.75} className="shrink-0" />
      {!collapsed && (
        <>
          <span className="flex-1 truncate">{label}</span>
          {badge !== undefined && (
            <span
              className={cn(
                'inline-flex items-center justify-center min-w-5 h-5 px-1.5 rounded-sm text-mono',
                active
                  ? 'bg-accent text-on-accent'
                  : 'bg-surface-2 text-ink-2 group-hover:bg-line',
              )}
            >
              {badge}
            </span>
          )}
        </>
      )}
    </Link>
  )
}
