import { Link, useLocation, useNavigate } from '@tanstack/react-router'
import {
  Avatar,
  AppShell,
  Burger,
  Divider,
  Group,
  Menu,
  NavLink,
  ScrollArea,
  Stack,
  Text,
  Title,
  UnstyledButton,
} from '@pikku/mantine/core'
import { useDisclosure } from '@mantine/hooks'
import { useQueryClient } from '@tanstack/react-query'
import { m, mKey } from '@/i18n/messages'
import { useLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import { createContext, useContext, useEffect, useState } from 'react'
import { signOut } from '../lib/auth'
import { BrandMark } from './Brand'

/**
 * Per-page title shown in the app header next to the brand mark. Pages opt in
 * via `usePageTitle(...)`; pages that don't call it leave the header showing
 * only the brand, so existing pages keep working unchanged.
 */
const PageTitleContext = createContext<
  ((title: string | undefined) => void) | null
>(null)

export function PageTitle({ title }: { title: string }) {
  usePageTitle(title)
  return null
}

export function usePageTitle(title: string | undefined) {
  const setTitle = useContext(PageTitleContext)
  useEffect(() => {
    // No-op safely if used outside the provider (e.g. unauthenticated pages).
    if (!setTitle) return
    setTitle(title)
    return () => setTitle(undefined)
  }, [setTitle, title])
}

type Role = 'client' | 'admin' | 'owner'

type NavItem = {
  to: string
  labelKey: string
  roles: Role[]
}

type Section = {
  titleKey: string
  items: NavItem[]
}

const SECTIONS: Section[] = [
  {
    titleKey: 'common.nav.sections.workspace',
    items: [
      { to: '/admin',           labelKey: 'common.nav.items.dashboard',   roles: ['admin', 'owner'] },
      { to: '/admin/bookings',  labelKey: 'common.nav.items.bookings',    roles: ['admin', 'owner'] },
      { to: '/admin/enquiries', labelKey: 'common.nav.items.enquiries',   roles: ['admin', 'owner'] },
      { to: '/kanban',          labelKey: 'common.nav.items.kanban',      roles: ['admin', 'owner'] },
    ],
  },
  {
    titleKey: 'common.nav.sections.public',
    items: [
      { to: '/availability', labelKey: 'common.nav.items.availability', roles: ['client', 'admin', 'owner'] },
      { to: '/enquiry',      labelKey: 'common.nav.items.enquiry',      roles: ['admin', 'owner'] },
      { to: '/events',       labelKey: 'common.nav.items.events',       roles: ['client', 'admin', 'owner'] },
    ],
  },
]

const initials = (name: string) =>
  name
    .split(/\s+/)
    .filter(Boolean)
    .slice(0, 2)
    .map((p) => p[0]?.toUpperCase() ?? '')
    .join('')

export function AppLayout({
  user,
  children,
}: {
  user: { name: string; role: string; email: string }
  children: React.ReactNode
}) {
  useLocale()
  const [opened, { toggle, close }] = useDisclosure()
  const [pageTitle, setPageTitle] = useState<string | undefined>(undefined)
  const location = useLocation()
  const navigate = useNavigate()
  const qc = useQueryClient()
  const role = user.role as Role

  const [logoutPending, setLogoutPending] = useState(false)
  const handleLogout = async () => {
    setLogoutPending(true)
    try {
      await signOut()
    } finally {
      await qc.invalidateQueries({ queryKey: ['me'] })
      navigate({ to: '/login' })
    }
  }

  return (
    <PageTitleContext.Provider value={setPageTitle}>
    <AppShell
      header={{ height: 72 }}
      navbar={{ width: 248, breakpoint: 'sm', collapsed: { mobile: !opened } }}
      padding={{ base: 'md', md: 'xl' }}
      styles={{
        header: {
          backgroundColor: '#ffffff',
          borderBottom: '1px solid var(--mantine-color-gray-2)',
        },
        navbar: {
          backgroundColor: '#FBF8FA',
          borderRight: '1px solid var(--mantine-color-gray-2)',
        },
        main: { backgroundColor: 'var(--brand-bg)' },
      }}
    >
      <AppShell.Header>
        <Group h="100%" px="md" gap="md" wrap="nowrap" justify="space-between">
          <Group gap="sm" wrap="nowrap">
            <Burger
              opened={opened}
              onClick={toggle}
              hiddenFrom="sm"
              size="sm"
              color="var(--brand-plum)"
              aria-label={m.common_nav_toggle()}
            />
            <Link to="/" style={{ textDecoration: 'none' }} onClick={close}>
              <Group gap="sm" wrap="nowrap" align="center">
                <BrandMark size={32} />
                <Title
                  order={5}
                  c="var(--brand-plum-dark)"
                  fw={600}
                  style={{ letterSpacing: '0.01em', lineHeight: 1 }}
                >
                  {m.common_brand_name()}
                </Title>
              </Group>
            </Link>
            {pageTitle && (
              <>
                <Divider orientation="vertical" my={8} visibleFrom="sm" />
                <Text
                  fw={600}
                  size="md"
                  c="var(--brand-plum-dark)"
                  visibleFrom="sm"
                  style={{ lineHeight: 1 }}
                >
                  {asI18n(`${pageTitle}`)}
                </Text>
              </>
            )}
          </Group>
          <Menu position="bottom-end" withArrow shadow="sm">
            <Menu.Target>
              <UnstyledButton
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: 12,
                  padding: '4px 8px',
                  borderRadius: 8,
                }}
              >
                <Stack gap={0} align="flex-end" visibleFrom="sm">
                  <Text size="sm" fw={600} style={{ lineHeight: 1.2 }}>{asI18n(`${user.name}`)}</Text>
                  <Text size="xs" c="dimmed" tt="capitalize" style={{ lineHeight: 1.2 }}>
                    {mKey(`common.nav.role.${user.role}` as any)}
                  </Text>
                </Stack>
                <Avatar
                  radius="xl"
                  color="plum"
                  variant="light"
                  size={36}
                >
                  {initials(user.name)}
                </Avatar>
              </UnstyledButton>
            </Menu.Target>
            <Menu.Dropdown>
              <Menu.Label>{asI18n(`${user.email}`)}</Menu.Label>
              <Menu.Divider />
              <Menu.Item
                color="red"
                onClick={handleLogout}
                disabled={logoutPending}
              >
                {m.common_nav_logout()}
              </Menu.Item>
            </Menu.Dropdown>
          </Menu>
        </Group>
      </AppShell.Header>

      <AppShell.Navbar p="md">
        <AppShell.Section grow component={ScrollArea}>
          <Stack gap="lg">
            {SECTIONS.map((section) => {
              const visible = section.items.filter((n) => n.roles.includes(role))
              if (visible.length === 0) return null
              return (
                <Stack key={section.titleKey} gap={4}>
                  <Text
                    size="xs"
                    tt="uppercase"
                    c="dimmed"
                    fw={600}
                    px="sm"
                    mb={4}
                    style={{ letterSpacing: '0.08em' }}
                  >
                    {asI18n(`${mKey(section.titleKey as any)}`)}
                  </Text>
                  {visible.map((item) => {
                    // '/admin' is the dashboard landing — match it exactly so it
                    // doesn't stay highlighted across every /admin/* sub-page.
                    const active =
                      item.to === '/admin'
                        ? location.pathname === '/admin' ||
                          location.pathname === '/admin/'
                        : location.pathname.startsWith(item.to)
                    return (
                      <NavLink
                        key={item.to}
                        component={Link}
                        to={item.to}
                        label={mKey(item.labelKey as any)}
                        active={active}
                        onClick={close}
                      />
                    )
                  })}
                </Stack>
              )
            })}
          </Stack>
        </AppShell.Section>
        <AppShell.Section
          pt="md"
          style={{ borderTop: '1px solid var(--mantine-color-gray-2)' }}
        >
          <Text size="xs" c="dimmed">{m.common_brand_tagline()}</Text>
        </AppShell.Section>
      </AppShell.Navbar>

      <AppShell.Main>{children}</AppShell.Main>
    </AppShell>
    </PageTitleContext.Provider>
  )
}
