import { Link, createFileRoute, useNavigate } from '@tanstack/react-router'
import { useMemo, useState } from 'react'
import { m } from '@/i18n/messages'
import { bookingStatus } from '@/i18n/i18n-enum.gen'
import { useLocale, getLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import { keepPreviousData } from '@tanstack/react-query'
import {
  Badge,
  Box,
  Button,
  Checkbox,
  Container,
  Group,
  Loader,
  MultiSelect,
  Paper,
  Stack,
  Table,
  Text,
  TextInput,
} from '@pikku/mantine/core'
import { Search } from 'lucide-react'
import { usePikkuQuery } from '@project/functions-sdk/pikku/api.gen'
import { StatusPill } from '../components/StatusPill'
import { usePageTitle } from '../components/AppLayout'
import { BOOKING_STATUS, type BookingStatus } from '../lib/status'
import { fmtDateShort } from '../lib/dates'

const STATUS_KEYS: BookingStatus[] = [
  'enquiry',
  'reserved',
  'confirmed',
  'ended',
  'cancelled',
]

function StatusDot({ color }: { color: string }) {
  return (
    <Box
      component="span"
      style={{
        display: 'inline-block',
        width: 8,
        height: 8,
        borderRadius: 4,
        background: color,
        flex: '0 0 auto',
      }}
    />
  )
}

function AdminBookingsInner() {
  useLocale()
  const navigate = useNavigate()

  usePageTitle(m.common__pages__admin__bookings__title())

  const [years, setYears] = useState<string[]>([])
  const [statusFilter, setStatusFilter] = useState<string[]>([])
  const [search, setSearch] = useState('')
  const [halfHouseOnly, setHalfHouseOnly] = useState(false)

  const queryArgs = useMemo(
    () => ({
      venueSlug: 'drawehn',
      years: years.length ? years.map(Number) : undefined,
      status: statusFilter.length ? statusFilter : undefined,
      search: search.trim() || undefined,
      halfHouseOnly: halfHouseOnly || undefined,
    }),
    [years, statusFilter, search, halfHouseOnly],
  )

  const normalizedSearch = search.trim().toLocaleLowerCase(getLocale())

  const { data, isLoading, isFetching, error } = usePikkuQuery(
    'getAdminBookings',
    queryArgs,
    { placeholderData: keepPreviousData },
  )

  const statusOptions = useMemo(
    () =>
      STATUS_KEYS.map((s) => ({
        value: s,
        label: bookingStatus[s](),
      })),
    [getLocale()],
  )

  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 bookings = [...data.bookings].sort((a, b) => {
    if (!normalizedSearch) return 0

    const rank = (value: string | null | undefined) => {
      const text = value?.toLocaleLowerCase(getLocale()) ?? ''
      if (text === normalizedSearch) return 0
      if (text.startsWith(normalizedSearch)) return 1
      if (text.includes(normalizedSearch)) return 2
      return 3
    }

    const aRank = Math.min(rank(a.eventName), rank(a.clientName))
    const bRank = Math.min(rank(b.eventName), rank(b.clientName))

    if (aRank !== bRank) return aRank - bRank
    return a.eventName.localeCompare(b.eventName, getLocale())
  })

  return (
    <Container size="xl" py="md">
      <Stack gap="sm">
        <Group gap="sm" align="flex-end" wrap="wrap">
            <TextInput
              flex="1 1 220px"
              leftSection={<Search size={16} />}
              placeholder={m.common__pages__admin__bookings__search_placeholder()}
              value={search}
              onChange={(e) => setSearch(e.currentTarget.value)}
            />
            <MultiSelect
              flex="0 1 200px"
              clearable
              placeholder={
                years.length ? undefined : m.common__pages__admin__bookings__filters__year()
              }
              data={data.yearOptions.map((y) => String(y))}
              value={years}
              onChange={setYears}
            />
            <MultiSelect
              flex="1 1 240px"
              clearable
              placeholder={
                statusFilter.length
                  ? undefined
                  : m.common__pages__admin__bookings__filters__status()
              }
              data={statusOptions}
              value={statusFilter}
              onChange={setStatusFilter}
              renderOption={({ option }) => (
                <Group gap="xs" wrap="nowrap">
                  <StatusDot color={BOOKING_STATUS[option.value as BookingStatus].dot} />
                  <span>{option.label}</span>
                </Group>
              )}
            />
            <Checkbox
              color="plum"
              label={m.common__pages__admin__bookings__filters__half_house_only()}
              checked={halfHouseOnly}
              onChange={(e) => setHalfHouseOnly(e.currentTarget.checked)}
              styles={{ root: { alignSelf: 'center' } }}
            />
            <Button
              component={Link}
              to="/enquiry"
              color="plum"
              variant="filled"
              ml="auto"
            >
              {m.common__pages__admin__bookings__new_booking()}
            </Button>
        </Group>

        <Group gap="xs" align="center">
          <Text size="sm" c="dimmed">
            {m.common__pages__admin__bookings__stats__showing({ count: data.totalCount })}
          </Text>
          {isFetching && <Loader size="xs" color="plum" />}
        </Group>

        <Paper withBorder radius="md" p={0}>
          {bookings.length === 0 ? (
            <Box p="xl">
              <Text size="sm" c="dimmed" ta="center">
                {m.common__pages__admin__bookings__empty()}
              </Text>
            </Box>
          ) : (
            <Table highlightOnHover stickyHeader>
              <Table.Thead>
                <Table.Tr>
                  <Table.Th>{m.common__pages__admin__bookings__cols__dates()}</Table.Th>
                  <Table.Th>{m.common__pages__admin__bookings__cols__course()}</Table.Th>
                  <Table.Th>{m.common__pages__admin__bookings__cols__client()}</Table.Th>
                  <Table.Th>{m.common__pages__admin__bookings__cols__status()}</Table.Th>
                  <Table.Th>{m.common__pages__admin__bookings__cols__persons()}</Table.Th>
                  <Table.Th ta="center">{m.common__pages__admin__bookings__cols__half_house()}</Table.Th>
                  <Table.Th>{m.common__pages__admin__bookings__cols__deposit()}</Table.Th>
                  <Table.Th>{m.common__pages__admin__bookings__cols__final()}</Table.Th>
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {bookings.map((b) => (
                  <Table.Tr
                    key={b.bookingId}
                    style={{ cursor: 'pointer' }}
                    onClick={() =>
                      navigate({ to: '/admin/bookings/$bookingId', params: { bookingId: b.bookingId } })
                    }
                  >
                    <Table.Td>
                      <Text size="sm">{asI18n(`${fmtDateShort(b.startDate, getLocale())}`)}</Text>
                      <Text size="xs" c="dimmed">{asI18n(`→ ${fmtDateShort(b.endDate, getLocale())}`)}</Text>
                    </Table.Td>
                    <Table.Td>{asI18n(`${b.eventName}`)}</Table.Td>
                    <Table.Td>
                      <Group gap={4}>
                        {b.isStammgruppe && (
                          <Text size="xs" c="yellow" title={m.common__pages__admin__bookings__cols__regular_group()}>{asI18n('★')}</Text>
                        )}
                        {asI18n(`${b.clientName}`)}
                      </Group>
                    </Table.Td>
                    <Table.Td>
                      <StatusPill kind="booking" status={b.status as BookingStatus} />
                    </Table.Td>
                    <Table.Td>
                      {b.participantCount} / {b.expectedPersons ?? '?'}
                    </Table.Td>
                    <Table.Td ta="center">{b.halfHouse ? '½' : ''}</Table.Td>
                    <Table.Td>
                      {!b.hasDeposit
                        ? <Text size="xs" c="dimmed">{m.common__pages__admin__bookings__deposit__missing()}</Text>
                        : <Badge size="xs" color={b.depositPaid ? 'green' : 'orange'} variant="light">
                            {(b.depositPaid ? m.common__pages__admin__bookings__deposit__paid : m.common__pages__admin__bookings__deposit__outstanding)()}
                          </Badge>}
                    </Table.Td>
                    <Table.Td>
                      {!b.hasFinal
                        ? <Text size="xs" c="dimmed">{m.common__pages__admin__bookings__deposit__missing()}</Text>
                        : <Badge size="xs" color={b.finalPaid ? 'green' : 'orange'} variant="light">
                            {(b.finalPaid ? m.common__pages__admin__bookings__deposit__paid : m.common__pages__admin__bookings__deposit__outstanding)()}
                          </Badge>}
                    </Table.Td>
                  </Table.Tr>
                ))}
              </Table.Tbody>
            </Table>
          )}
        </Paper>
      </Stack>
    </Container>
  )
}

export const Route = createFileRoute('/admin/bookings/')({
  component: AdminBookingsInner,
})
