import { LayoutGrid, LogOut, Menu, Search, User as UserIcon, X } from 'lucide-react'
import { useEffect, useState } from 'react'
import { Link, NavLink, useLocation, useNavigate } from 'react-router-dom'

import { Logo } from './Logo'
import { Button, ThemeToggle } from '@/components/ui'
import { useAuth } from '@/features/auth/AuthProvider'
import { cn } from '@/lib/cn'

/** Public navigation. Browsing needs no account, so these are always shown. */
const PUBLIC_LINKS = [
  { to: '/domains', label: 'Browse domains' },
  { to: '/categories', label: 'Categories' },
  { to: '/sell', label: 'Sell a domain' },
  { to: '/pricing', label: 'Pricing' },
]

export function Header() {
  const { isAuthenticated, user, logout } = useAuth()
  const [isMenuOpen, setIsMenuOpen] = useState(false)
  const location = useLocation()
  const navigate = useNavigate()

  // Navigating with the mobile sheet open should close it.
  useEffect(() => {
    setIsMenuOpen(false)
  }, [location.pathname])

  // Escape closes the sheet, matching the expectation for any overlay.
  useEffect(() => {
    if (!isMenuOpen) {
      return
    }

    const onKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        setIsMenuOpen(false)
      }
    }

    document.addEventListener('keydown', onKeyDown)

    return () => document.removeEventListener('keydown', onKeyDown)
  }, [isMenuOpen])

  const handleSignOut = async () => {
    await logout()
    navigate('/')
  }

  return (
    <header
      /*
       * A pill that floats clear of the viewport edge, rather than a bar welded
       * to it.
       *
       * The padding sits on the sticky element and not on the pill, so the gap
       * above the pill belongs to the sticky box: content scrolls up through it
       * and behind the glass, which is what makes the bar read as floating over
       * the page. Put the offset on the pill as a margin instead and the sticky
       * box no longer covers that strip, so content passes over it untouched.
       */
      className="sticky top-0 z-40 pt-3 sm:pt-4"
    >
      <div className="container-page">
        <div
          /*
           * Glass is spent here deliberately: content passes underneath on every
           * scroll, which makes this the one surface in the application where the
           * effect is doing work rather than decorating.
           *
           * Narrower than the page's content column, also on purpose. A pill
           * stretched to the full 90rem leaves a corridor of dead space between
           * the navigation and the account actions, which stops reading as a
           * self-contained object and starts reading as a bar with a hole in it.
           */
          className="glass mx-auto flex h-14 max-w-6xl items-center justify-between gap-4 rounded-full border border-border-subtle pr-2 pl-5"
        >
          <div className="flex items-center gap-6">
            <Link to="/" className="rounded-md" aria-label="Domainsansar home">
              <Logo />
            </Link>

            <nav aria-label="Main" className="hidden items-center gap-1 lg:flex">
              {PUBLIC_LINKS.map((link) => (
                <NavLink
                  key={link.to}
                  to={link.to}
                  className={({ isActive }) =>
                    cn(
                      // Fully rounded to match the container: a square active
                      // pill inside a rounded bar reads as an oversight.
                      'rounded-full px-3.5 py-2 text-sm font-medium transition-colors duration-150',
                      isActive
                        ? 'bg-surface-sunken text-text-primary'
                        : 'text-text-secondary hover:bg-surface-hover hover:text-text-primary',
                    )
                  }
                >
                  {link.label}
                </NavLink>
              ))}
            </nav>
          </div>

          <div className="flex items-center gap-2">
            <Link
              to="/domains"
              aria-label="Search domains"
              className="flex size-9 items-center justify-center rounded-full text-text-secondary transition-colors duration-150 hover:bg-surface-hover hover:text-text-primary lg:hidden"
            >
              <Search aria-hidden className="size-4" />
            </Link>

            <ThemeToggle className="hidden sm:inline-flex" />

            {isAuthenticated ? (
              <div className="hidden items-center gap-2 lg:flex">
                <Button
                  variant="ghost"
                  size="sm"
                  shape="pill"
                  leadingIcon={<LayoutGrid aria-hidden className="size-4" />}
                  onClick={() => navigate('/dashboard')}
                >
                  Dashboard
                </Button>
                <Button
                  variant="secondary"
                  size="sm"
                  shape="pill"
                  leadingIcon={<UserIcon aria-hidden className="size-4" />}
                  onClick={() => navigate('/settings')}
                >
                  {user?.profile?.display_name ?? user?.name ?? 'Account'}
                </Button>
              </div>
            ) : (
              <div className="hidden items-center gap-2 lg:flex">
                <Button variant="ghost" size="sm" shape="pill" onClick={() => navigate('/login')}>
                  Sign in
                </Button>
                <Button size="sm" shape="pill" onClick={() => navigate('/register')}>
                  Create account
                </Button>
              </div>
            )}

            <button
              type="button"
              aria-expanded={isMenuOpen}
              aria-controls="mobile-navigation"
              aria-label={isMenuOpen ? 'Close menu' : 'Open menu'}
              onClick={() => setIsMenuOpen((open) => !open)}
              className="flex size-9 items-center justify-center rounded-full text-text-secondary transition-colors duration-150 hover:bg-surface-hover hover:text-text-primary lg:hidden"
            >
              {isMenuOpen ? (
                <X aria-hidden className="size-5" />
              ) : (
                <Menu aria-hidden className="size-5" />
              )}
            </button>
          </div>
        </div>

        {/*
          The mobile menu is a purpose-built panel rather than the desktop nav
          squeezed narrow: on a phone the primary actions are browsing and
          account, and they get full-width targets.

          It floats below the pill as its own rounded card, and it is opaque
          rather than glass. A full panel of navigation with page text showing
          through it is unreadable, which is exactly the overuse the brief warns
          about.
        */}
        {isMenuOpen && (
          <div
            id="mobile-navigation"
            className="mx-auto mt-2 max-w-6xl rounded-2xl border border-border-subtle bg-surface shadow-lg lg:hidden"
          >
            <nav aria-label="Mobile" className="flex flex-col gap-1 p-3">
              {PUBLIC_LINKS.map((link) => (
                <NavLink
                  key={link.to}
                  to={link.to}
                  className={({ isActive }) =>
                    cn(
                      'rounded-lg px-3 py-2.5 text-sm font-medium',
                      isActive
                        ? 'bg-surface-sunken text-text-primary'
                        : 'text-text-secondary hover:bg-surface-hover',
                    )
                  }
                >
                  {link.label}
                </NavLink>
              ))}

              <div className="my-2 h-px bg-border-subtle" />

              {isAuthenticated ? (
                <>
                  <NavLink
                    to="/dashboard"
                    className="rounded-lg px-3 py-2.5 text-sm font-medium text-text-secondary hover:bg-surface-hover"
                  >
                    Dashboard
                  </NavLink>
                  <NavLink
                    to="/settings"
                    className="rounded-lg px-3 py-2.5 text-sm font-medium text-text-secondary hover:bg-surface-hover"
                  >
                    Account settings
                  </NavLink>
                  <button
                    type="button"
                    onClick={handleSignOut}
                    className="flex items-center gap-2 rounded-lg px-3 py-2.5 text-left text-sm font-medium text-text-secondary hover:bg-surface-hover"
                  >
                    <LogOut aria-hidden className="size-4" />
                    Sign out
                  </button>
                </>
              ) : (
                <div className="flex flex-col gap-2 pt-1">
                  <Button
                    variant="secondary"
                    shape="pill"
                    fullWidth
                    onClick={() => navigate('/login')}
                  >
                    Sign in
                  </Button>
                  <Button shape="pill" fullWidth onClick={() => navigate('/register')}>
                    Create account
                  </Button>
                </div>
              )}

              <div className="px-3 pt-3 sm:hidden">
                <ThemeToggle />
              </div>
            </nav>
          </div>
        )}
      </div>
    </header>
  )
}
