import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { m, mKey } from '@/i18n/messages'
import { useLocale, getLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import {
  Badge,
  Box,
  Container,
  Grid,
  Group,
  Paper,
  SimpleGrid,
  Stack,
  Text,
  ThemeIcon,
  Title,
} from '@pikku/mantine/core'
import {
  CalendarDays,
  FileClock,
  FileText,
  Inbox,
  Wallet,
  type LucideIcon,
} from 'lucide-react'
import { usePikkuQuery } from '@project/functions-sdk/pikku/api.gen'
import { RequireAuth } from '../auth'
import { usePageTitle } from '../components/AppLayout'
import { fmtDateShort } from '../lib/dates'

// One row inside an action card: clickable, navigates to the relevant workspace.
function Row({
  primary,
  secondary,
  date,
  trailing,
  onClick,
}: {
  primary: string
  secondary?: string | null
  date: string
  trailing?: React.ReactNode
  onClick: () => void
}) {
  return (
    <Group
      justify="space-between"
      wrap="nowrap"
      gap="sm"
      px="xs"
      py={6}
      onClick={onClick}
      style={{ cursor: 'pointer', borderRadius: 8 }}
      className="dash-row"
    >
      <Box style={{ minWidth: 0 }}>
        <Text size="sm" fw={500} truncate>
          {asI18n(`${primary}`)}
        </Text>
        {secondary && (
          <Text size="xs" c="dimmed" truncate>
            {asI18n(`${secondary}`)}
          </Text>
        )}
      </Box>
      <Group gap={8} wrap="nowrap" style={{ flex: '0 0 auto' }}>
        {trailing}
        <Text size="xs" c="dimmed">
          {asI18n(`${date}`)}
        </Text>
      </Group>
    </Group>
  )
}

function ActionCard({
  icon: Icon,
  label,
  count,
  children,
}: {
  icon: LucideIcon
  label: string
  count: number
  children: React.ReactNode
}) {
  const empty = count === 0
  return (
    <Paper withBorder radius="md" p="md">
      <Group justify="space-between" wrap="nowrap" mb={children ? 'xs' : 0}>
        <Group gap="xs" wrap="nowrap">
          <ThemeIcon
            variant="light"
            color={empty ? 'gray' : 'plum'}
            size="md"
            radius="md"
          >
            <Icon size={16} />
          </ThemeIcon>
          <Text size="sm" fw={600}>
            {asI18n(`${label}`)}
          </Text>
        </Group>
        <Badge
          color={empty ? 'gray' : 'plum'}
          variant={empty ? 'light' : 'filled'}
          radius="sm"
        >
          {count}
        </Badge>
      </Group>
      {!empty && <Stack gap={2}>{children}</Stack>}
    </Paper>
  )
}

function DashboardInner() {
  useLocale()
  const navigate = useNavigate()
  usePageTitle(m.common_pages_admin_dashboard_title())

  const { data, isLoading, error } = usePikkuQuery('getAdminDashboard', {
    venueSlug: 'drawehn',
  })

  if (isLoading && !data) {
    return (
      <Container py="xl">
        <Text>{m.common_states_loading()}</Text>
      </Container>
    )
  }
  if (error && !data) {
    return (
      <Container py="xl">
        <Text c="red">{m.common_states_error()}</Text>
      </Container>
    )
  }
  if (!data) return null

  const goEnquiries = () => navigate({ to: '/admin/enquiries' })
  const goBooking = (bookingId: string) =>
    navigate({ to: '/admin/bookings/$bookingId', params: { bookingId } })

  const tk = (k: string, opts?: Record<string, unknown>) =>
    mKey(`common.pages.admin.dashboard.${k}` as any, opts ?? {})
  const more = (bucket: { count: number; items: unknown[] }) =>
    bucket.count > bucket.items.length ? (
      <Text size="xs" c="dimmed" px="xs" pt={4}>
        {tk('more', { count: bucket.count - bucket.items.length })}
      </Text>
    ) : null

  const noAction =
    data.pendingEnquiries.count === 0 &&
    data.contractsToSend.count === 0 &&
    data.contractsAwaitingResponse.count === 0 &&
    data.depositsOutstanding.count === 0

  // A "needs action" hub should only surface what needs action — zero-count
  // cards are noise, so we drop them and let `noAction` cover the empty state.
  const bookingCard = (
    key: string,
    icon: LucideIcon,
    label: string,
    bucket: typeof data.contractsToSend,
  ) =>
    bucket.count === 0 ? null : (
      <ActionCard key={key} icon={icon} label={label} count={bucket.count}>
        {bucket.items.map((b) => (
          <Row
            key={b.bookingId}
            primary={b.eventName}
            secondary={b.clientName}
            date={fmtDateShort(b.startDate, getLocale())}
            onClick={() => goBooking(b.bookingId)}
          />
        ))}
        {more(bucket)}
      </ActionCard>
    )

  const actionCards = [
    data.pendingEnquiries.count === 0 ? null : (
      <ActionCard
        key="enq"
        icon={Inbox}
        label={tk('cards.pendingEnquiries')}
        count={data.pendingEnquiries.count}
      >
        {data.pendingEnquiries.items.map((e) => (
          <Row
            key={e.enquiryId}
            primary={e.eventName}
            secondary={e.contactName}
            date={fmtDateShort(e.startDate, getLocale())}
            trailing={
              e.waitlisted ? (
                <Badge size="xs" color="orange" variant="light">
                  {tk('waitlisted')}
                </Badge>
              ) : null
            }
            onClick={goEnquiries}
          />
        ))}
        {more(data.pendingEnquiries)}
      </ActionCard>
    ),
    bookingCard('send', FileText, tk('cards.contractsToSend'), data.contractsToSend),
    bookingCard(
      'await',
      FileClock,
      tk('cards.contractsAwaiting'),
      data.contractsAwaitingResponse,
    ),
    bookingCard('dep', Wallet, tk('cards.depositsOutstanding'), data.depositsOutstanding),
  ].filter(Boolean)

  return (
    <Container size="xl" py="md">
      <Grid gap="lg">
        {/* Needs action */}
        <Grid.Col span={{ base: 12, md: 7 }}>
          <Stack gap="sm">
            <Title order={4}>{tk('needsAction')}</Title>
            {noAction ? (
              <Paper withBorder radius="md" p="lg">
                <Text size="sm" c="dimmed" ta="center">
                  {tk('allClear')}
                </Text>
              </Paper>
            ) : (
              <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="sm">
                {actionCards}
              </SimpleGrid>
            )}
          </Stack>
        </Grid.Col>

        {/* Upcoming events */}
        <Grid.Col span={{ base: 12, md: 5 }}>
          <Stack gap="sm">
            <Group gap="xs" align="baseline">
              <Title order={4}>{tk('upcoming')}</Title>
              <Text size="xs" c="dimmed">
                {tk('upcomingWindow')}
              </Text>
            </Group>
            <Paper withBorder radius="md" p={data.upcomingEvents.count ? 'xs' : 'lg'}>
              {data.upcomingEvents.count === 0 ? (
                <Text size="sm" c="dimmed" ta="center">
                  {tk('noUpcoming')}
                </Text>
              ) : (
                <Stack gap={2}>
                  {data.upcomingEvents.items.map((b) => (
                    <Group
                      key={b.bookingId}
                      justify="space-between"
                      wrap="nowrap"
                      gap="sm"
                      px="xs"
                      py={8}
                      onClick={() => goBooking(b.bookingId)}
                      style={{ cursor: 'pointer', borderRadius: 8 }}
                      className="dash-row"
                    >
                      <Group gap="sm" wrap="nowrap" style={{ minWidth: 0 }}>
                        <ThemeIcon
                          variant="light"
                          color="plum"
                          size="lg"
                          radius="md"
                        >
                          <CalendarDays size={18} />
                        </ThemeIcon>
                        <Box style={{ minWidth: 0 }}>
                          <Text size="sm" fw={500} truncate>
                            {asI18n(`${b.eventName}`)}
                          </Text>
                          <Text size="xs" c="dimmed" truncate>
                            {asI18n(
                              `${b.clientName}${b.expectedPersons != null ? ` · ${tk('persons', { count: b.expectedPersons })}` : ''}`,
                            )}
                          </Text>
                        </Box>
                      </Group>
                      <Text size="xs" c="dimmed" style={{ flex: '0 0 auto' }}>
                        {asI18n(`${fmtDateShort(b.startDate, getLocale())}`)}
                      </Text>
                    </Group>
                  ))}
                </Stack>
              )}
            </Paper>
          </Stack>
        </Grid.Col>
      </Grid>
    </Container>
  )
}

export const Route = createFileRoute('/admin/')({
  component: () => (
    <RequireAuth roles={['admin', 'owner']}>
      <DashboardInner />
    </RequireAuth>
  ),
})
