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 { 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)

  return (
    <aside className="hidden lg:flex w-[220px] shrink-0 flex-col border-r border-line bg-surface">
      {/* Logo block */}
      <div className="h-14 flex items-center px-5 border-b border-line">
        <Link to="/" className="font-display text-base tracking-wider text-navy hover:opacity-80 transition-opacity">
          ORDINIS
        </Link>
      </div>

      {/* Nav sections */}
      <nav className="flex-1 overflow-y-auto py-3 px-2 flex flex-col gap-4">
        {visibleSections.map((section, idx) => (
          <div key={idx} className="flex flex-col gap-0.5">
            {section.label && (
              <div className="px-3 py-1 font-display uppercase tracking-[0.10em] text-mute text-[10.5px] leading-none">
                {section.label}
              </div>
            )}
            {section.items.map((item) => (
              <SidebarLink key={item.to} {...item} />
            ))}
          </div>
        ))}
      </nav>

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

function SidebarLink({ to, label, icon: Icon, badge }: NavItem) {
  const location = useLocation()
  const active =
    to === '/'
      ? location.pathname === '/'
      : location.pathname === to || location.pathname.startsWith(to + '/')

  return (
    <Link
      to={to}
      className={cn(
        // 13px per handoff spec для workhorse body text. text-sm = 14px (Tailwind),
        // text-[13px] = exact handoff value.
        'group flex items-center gap-2.5 px-3 py-1.5 rounded-md text-[13px] transition-colors',
        active
          ? 'bg-accent-bg text-accent font-medium'
          : 'text-ink-2 hover:text-ink hover:bg-surface-2',
      )}
    >
      <Icon size={15} strokeWidth={1.75} className="shrink-0" />
      <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-[11px] font-mono',
            active
              ? 'bg-accent text-on-accent'
              : 'bg-surface-2 text-ink-2 group-hover:bg-line',
          )}
        >
          {badge}
        </span>
      )}
    </Link>
  )
}
