import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { useMemo, useState } from 'react'
import { m, mKey } from '@/i18n/messages'
import { useLocale, getLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import { keepPreviousData, useQueryClient } from '@tanstack/react-query'
import { useDebouncedValue } from '@mantine/hooks'
import {
  Alert,
  Anchor,
  Badge,
  Box,
  Button,
  Container,
  Group,
  Loader,
  Modal,
  MultiSelect,
  Paper,
  SegmentedControl,
  Select,
  SimpleGrid,
  Stack,
  Table,
  Text,
  TextInput,
} from '@pikku/mantine/core'
import { Check, Clock, X } from 'lucide-react'
import { usePikkuMutation, usePikkuQuery } from '@project/functions-sdk/pikku/api.gen'
import { usePageTitle } from '../components/AppLayout'
import { RequireAuth } from '../auth'
import { fmtDate, fmtDateShort } from '../lib/dates'

const STATUS_KEYS = ['pending', 'approved', 'declined'] as const
type EnquiryStatus = (typeof STATUS_KEYS)[number]

type EnquiryDateOption = {
  optionId: string
  startDate: string
  endDate: string
  priority: number
}

type Enquiry = {
  enquiryId: string
  contactName: string | null
  contactEmail: string
  contactPhone: string | null
  website: string | null
  eventName: string
  eventOutline: string | null
  description: string | null
  dateOptions: EnquiryDateOption[]
  expectedPersons: number | null
  halfHouse: boolean
  notes: string | null
  status: string
  waitlistedAt: Date | null
  approvedAt: Date | null
  declinedAt: Date | null
  createdAt: Date
  bookingId: string | null
}

// The SDK's date reviver (transform-date.js) turns any 'YYYY-MM-DD…' response
// string into a Date — including these option dates, despite their string type.
// Normalize back to a plain 'YYYY-MM-DD' string so the date inputs and equality
// checks below work, and parse at local midnight for display.
const toYmd = (v: string | Date): string =>
  v instanceof Date ? v.toISOString().slice(0, 10) : v
const optDate = (s: string) => new Date(`${s}T00:00:00`)

function StatusBadge({ enquiry }: { enquiry: Enquiry }) {
  useLocale()
  const color =
    enquiry.status === 'approved' ? 'green' : enquiry.status === 'declined' ? 'red' : 'blue'
  return (
    <Group gap={6} wrap="nowrap">
      <Badge color={color} variant="light" size="sm">
        {mKey(`common.pages.admin.enquiries.status.${enquiry.status}` as any)}
      </Badge>
      {enquiry.status === 'pending' && enquiry.waitlistedAt && (
        <Badge color="orange" variant="light" size="sm">
          {m.common_pages_admin_enquiries_status_waitlisted()}
        </Badge>
      )}
    </Group>
  )
}

function AdminEnquiriesInner() {
  useLocale()
  const queryClient = useQueryClient()
  const navigate = useNavigate()

  usePageTitle(m.common_pages_admin_enquiries_title())

  const [statusFilter, setStatusFilter] = useState<string[]>(['pending'])

  const queryArgs = useMemo(
    () => ({
      venueSlug: 'drawehn',
      status: statusFilter.length ? statusFilter : undefined,
    }),
    [statusFilter],
  )

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

  const invalidate = () => queryClient.invalidateQueries({ queryKey: ['getEnquiries'] })

  // Which enquiry has an open transition modal, and which kind.
  const [modal, setModal] = useState<{ kind: 'approve' | 'waitlist' | 'decline'; enquiry: Enquiry } | null>(null)

  const statusOptions = useMemo(
    () =>
      STATUS_KEYS.map((s) => ({
        value: s,
        label: mKey(`common.pages.admin.enquiries.status.${s}` as any),
      })),
    [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 enquiries = (data.enquiries as Enquiry[]).map((e) => ({
    ...e,
    dateOptions: e.dateOptions.map((o) => ({
      ...o,
      startDate: toYmd(o.startDate),
      endDate: toYmd(o.endDate),
    })),
  }))

  return (
    <Container size="xl" py="md">
      <Stack gap="sm">
        <Group gap="sm" align="flex-end" wrap="wrap">
          <MultiSelect
            flex="1 1 240px"
            clearable
            placeholder={statusFilter.length ? undefined : m.common_pages_admin_enquiries_filters_status()}
            data={statusOptions}
            value={statusFilter}
            onChange={setStatusFilter}
          />
        </Group>

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

        <Paper withBorder radius="md" p={0}>
          {enquiries.length === 0 ? (
            <Box p="xl">
              <Text size="sm" c="dimmed" ta="center">
                {m.common_pages_admin_enquiries_empty()}
              </Text>
            </Box>
          ) : (
            <Table highlightOnHover>
              <Table.Thead>
                <Table.Tr>
                  <Table.Th>{m.common_pages_admin_enquiries_cols_received()}</Table.Th>
                  <Table.Th>{m.common_pages_admin_enquiries_cols_event()}</Table.Th>
                  <Table.Th>{m.common_pages_admin_enquiries_cols_contact()}</Table.Th>
                  <Table.Th>{m.common_pages_admin_enquiries_cols_dates()}</Table.Th>
                  <Table.Th>{m.common_pages_admin_enquiries_cols_persons()}</Table.Th>
                  <Table.Th>{m.common_pages_admin_enquiries_cols_status()}</Table.Th>
                  <Table.Th>{m.common_pages_admin_enquiries_cols_actions()}</Table.Th>
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {enquiries.map((e) => (
                  <Table.Tr key={e.enquiryId}>
                    <Table.Td>
                      <Text size="sm">{asI18n(`${fmtDateShort(e.createdAt, getLocale())}`)}</Text>
                    </Table.Td>
                    <Table.Td>
                      <Text size="sm" fw={500}>{asI18n(`${e.eventName}`)}</Text>
                      {e.eventOutline && (
                        <Text size="xs" c="dimmed" lineClamp={1}>{asI18n(`${e.eventOutline}`)}</Text>
                      )}
                    </Table.Td>
                    <Table.Td>
                      <Text size="sm">{asI18n(`${e.contactName ?? '—'}`)}</Text>
                      <Text size="xs" c="dimmed">{asI18n(`${e.contactEmail}`)}</Text>
                    </Table.Td>
                    <Table.Td>
                      {e.dateOptions.length === 0 ? (
                        <Text size="xs" c="dimmed">{m.common_pages_admin_enquiries_no_dates()}</Text>
                      ) : (
                        <Stack gap={2}>
                          {e.dateOptions.map((o, i) => (
                            <Text key={o.optionId} size="sm" c={i === 0 ? undefined : 'dimmed'}>
                              {asI18n(`${fmtDateShort(optDate(o.startDate), getLocale())} → ${fmtDateShort(optDate(o.endDate), getLocale())}`)}
                            </Text>
                          ))}
                        </Stack>
                      )}
                    </Table.Td>
                    <Table.Td>{e.expectedPersons ?? '—'}</Table.Td>
                    <Table.Td><StatusBadge enquiry={e} /></Table.Td>
                    <Table.Td>
                      {e.status === 'pending' ? (
                        <Group gap={4} wrap="nowrap">
                          <Button
                            size="compact-xs"
                            color="green"
                            variant="light"
                            leftSection={<Check size={14} />}
                            onClick={() => setModal({ kind: 'approve', enquiry: e })}
                          >
                            {m.common_pages_admin_enquiries_actions_approve()}
                          </Button>
                          <Button
                            size="compact-xs"
                            color="orange"
                            variant="light"
                            leftSection={<Clock size={14} />}
                            onClick={() => setModal({ kind: 'waitlist', enquiry: e })}
                          >
                            {m.common_pages_admin_enquiries_actions_waitlist()}
                          </Button>
                          <Button
                            size="compact-xs"
                            color="red"
                            variant="subtle"
                            leftSection={<X size={14} />}
                            onClick={() => setModal({ kind: 'decline', enquiry: e })}
                          >
                            {m.common_pages_admin_enquiries_actions_decline()}
                          </Button>
                        </Group>
                      ) : e.status === 'approved' && e.bookingId ? (
                        <Anchor
                          size="sm"
                          onClick={() =>
                            navigate({ to: '/admin/bookings/$bookingId', params: { bookingId: e.bookingId! } })
                          }
                        >
                          {m.common_pages_admin_enquiries_actions_view_booking()}
                        </Anchor>
                      ) : (
                        <Text size="xs" c="dimmed">{asI18n('—')}</Text>
                      )}
                    </Table.Td>
                  </Table.Tr>
                ))}
              </Table.Tbody>
            </Table>
          )}
        </Paper>
      </Stack>

      {modal?.kind === 'approve' && (
        <ApproveModal enquiry={modal.enquiry} onClose={() => setModal(null)} onDone={() => { setModal(null); invalidate() }} />
      )}
      {modal?.kind === 'waitlist' && (
        <WaitlistModal enquiry={modal.enquiry} onClose={() => setModal(null)} onDone={() => { setModal(null); invalidate() }} />
      )}
      {modal?.kind === 'decline' && (
        <DeclineModal enquiry={modal.enquiry} onClose={() => setModal(null)} onDone={() => { setModal(null); invalidate() }} />
      )}
    </Container>
  )
}

// ─── Approve modal ──────────────────────────────────────────────────────────

function ApproveModal({ enquiry, onClose, onDone }: { enquiry: Enquiry; onClose: () => void; onDone: () => void }) {
  useLocale()

  const [mode, setMode] = useState<'existing' | 'new'>('existing')
  // Prefill from the visitor's preferred (first) date option; the admin can
  // pick a different option or override the inputs entirely.
  const topOption = enquiry.dateOptions[0]
  const [startDate, setStartDate] = useState(topOption?.startDate ?? '')
  const [endDate, setEndDate] = useState(topOption?.endDate ?? '')

  // Existing-client search (server-side via getClients).
  const [clientId, setClientId] = useState<string | null>(null)
  const [search, setSearch] = useState('')
  const [debouncedSearch] = useDebouncedValue(search, 250)
  const { data: clientData, isFetching: clientsFetching } = usePikkuQuery(
    'getClients',
    { venueSlug: 'drawehn', q: debouncedSearch.trim() || undefined },
    { placeholderData: keepPreviousData, enabled: mode === 'existing' },
  )
  const clientOptions = useMemo(
    () =>
      (clientData?.clients ?? []).map((c) => ({
        value: c.clientId,
        label: c.name ? `${c.name}${c.contactEmail ? ` · ${c.contactEmail}` : ''}` : (c.contactEmail ?? c.clientId),
      })),
    [clientData],
  )

  // New-client fields, pre-filled from the enquiry contact.
  const [name, setName] = useState(enquiry.contactName ?? '')
  const [email, setEmail] = useState(enquiry.contactEmail)
  const [phone, setPhone] = useState(enquiry.contactPhone ?? '')
  const [website, setWebsite] = useState(enquiry.website ?? '')
  const [billingAddress, setBillingAddress] = useState('')

  const mutation = usePikkuMutation('approveEnquiry', { onSuccess: onDone })

  const datesValid = !!startDate && !!endDate && startDate <= endDate
  const clientValid = mode === 'existing' ? !!clientId : !!email.trim()
  const canSubmit = datesValid && clientValid

  const submit = () => {
    mutation.mutate({
      enquiryId: enquiry.enquiryId,
      startDate,
      endDate,
      client:
        mode === 'existing'
          ? { clientId: clientId! }
          : {
              name: name.trim() || undefined,
              contactEmail: email.trim() || undefined,
              contactPhone: phone.trim() || undefined,
              website: website.trim() || undefined,
              billingAddress: billingAddress.trim() || undefined,
            },
    })
  }

  return (
    <Modal opened onClose={onClose} title={m.common_pages_admin_enquiries_approve_modal_title()} size="lg">
      <Stack gap="md">
        <Text size="sm" c="dimmed">{asI18n(`${enquiry.eventName}`)}</Text>

        {enquiry.dateOptions.length > 0 && (
          <Box>
            <Text size="xs" c="dimmed" fw={600} tt="uppercase" mb={6}>
              {m.common_pages_admin_enquiries_approve_modal_date_options()}
            </Text>
            <Group gap="xs">
              {enquiry.dateOptions.map((o, i) => {
                const selected = o.startDate === startDate && o.endDate === endDate
                return (
                  <Badge
                    key={o.optionId}
                    variant={selected ? 'filled' : 'light'}
                    color={selected ? 'plum' : 'gray'}
                    style={{ cursor: 'pointer', textTransform: 'none' }}
                    onClick={() => {
                      setStartDate(o.startDate)
                      setEndDate(o.endDate)
                    }}
                  >
                    {asI18n(`${i + 1}. ${fmtDateShort(optDate(o.startDate), getLocale())} → ${fmtDateShort(optDate(o.endDate), getLocale())}`)}
                  </Badge>
                )
              })}
            </Group>
          </Box>
        )}

        <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
          <TextInput
            data-testid="approve-start-date"
            type="date"
            label={m.common_pages_admin_enquiries_approve_modal_start_date()}
            required
            value={startDate}
            onChange={(e) => setStartDate(e.currentTarget.value)}
          />
          <TextInput
            data-testid="approve-end-date"
            type="date"
            label={m.common_pages_admin_enquiries_approve_modal_end_date()}
            required
            value={endDate}
            onChange={(e) => setEndDate(e.currentTarget.value)}
            error={startDate && endDate && startDate > endDate ? m.common_pages_admin_enquiries_approve_modal_date_error() : undefined}
          />
        </SimpleGrid>

        <SegmentedControl
          fullWidth
          value={mode}
          onChange={(v) => setMode(v as 'existing' | 'new')}
          data={[
            { value: 'existing', label: m.common_pages_admin_enquiries_approve_modal_existing_client() },
            { value: 'new', label: m.common_pages_admin_enquiries_approve_modal_new_client() },
          ]}
        />

        {mode === 'existing' ? (
          <Select
            data-testid="approve-client-select"
            label={m.common_pages_admin_enquiries_approve_modal_select_client()}
            placeholder={m.common_pages_admin_enquiries_approve_modal_search_client()}
            searchable
            data={clientOptions}
            value={clientId}
            onChange={setClientId}
            searchValue={search}
            onSearchChange={setSearch}
            rightSection={clientsFetching ? <Loader size="xs" /> : undefined}
            nothingFoundMessage={m.common_pages_admin_enquiries_approve_modal_no_clients()}
            filter={({ options }) => options}
          />
        ) : (
          <Stack gap="sm">
            <TextInput
              data-testid="approve-new-name"
              label={m.common_pages_admin_enquiries_approve_modal_client_name()}
              value={name}
              onChange={(e) => setName(e.currentTarget.value)}
            />
            <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
              <TextInput
                data-testid="approve-new-email"
                type="email"
                label={m.common_pages_admin_enquiries_approve_modal_client_email()}
                required
                value={email}
                onChange={(e) => setEmail(e.currentTarget.value)}
              />
              <TextInput
                label={m.common_pages_admin_enquiries_approve_modal_client_phone()}
                value={phone}
                onChange={(e) => setPhone(e.currentTarget.value)}
              />
            </SimpleGrid>
            <TextInput
              label={m.common_pages_admin_enquiries_approve_modal_client_website()}
              value={website}
              onChange={(e) => setWebsite(e.currentTarget.value)}
            />
            <TextInput
              label={m.common_pages_admin_enquiries_approve_modal_client_billing_address()}
              value={billingAddress}
              onChange={(e) => setBillingAddress(e.currentTarget.value)}
            />
          </Stack>
        )}

        {mutation.error && (
          <Alert color="red">{asI18n(`${mutation.error.message || m.common_pages_admin_enquiries_transition_error()}`)}</Alert>
        )}

        <Group justify="flex-end">
          <Button variant="default" onClick={onClose}>{m.common_actions_cancel()}</Button>
          <Button
            data-testid="approve-confirm"
            color="green"
            onClick={submit}
            disabled={!canSubmit || mutation.isPending}
            loading={mutation.isPending}
          >
            {m.common_pages_admin_enquiries_actions_approve()}
          </Button>
        </Group>
      </Stack>
    </Modal>
  )
}

// ─── Waitlist modal ─────────────────────────────────────────────────────────

function WaitlistModal({ enquiry, onClose, onDone }: { enquiry: Enquiry; onClose: () => void; onDone: () => void }) {
  useLocale()
  const mutation = usePikkuMutation('waitlistEnquiry', { onSuccess: onDone })

  const hasOptions = enquiry.dateOptions.length > 0

  return (
    <Modal opened onClose={onClose} title={m.common_pages_admin_enquiries_waitlist_modal_title()} size="md">
      <Stack gap="md">
        <Text size="sm" c="dimmed">{m.common_pages_admin_enquiries_waitlist_modal_intro()}</Text>
        {hasOptions ? (
          <Stack gap={4}>
            {enquiry.dateOptions.map((o, i) => (
              <Text key={o.optionId} size="sm">
                {asI18n(`${i + 1}. ${fmtDateShort(optDate(o.startDate), getLocale())} → ${fmtDateShort(optDate(o.endDate), getLocale())}`)}
              </Text>
            ))}
          </Stack>
        ) : (
          <Alert color="orange">{m.common_pages_admin_enquiries_waitlist_modal_no_options()}</Alert>
        )}
        {mutation.error && (
          <Alert color="red">{asI18n(`${mutation.error.message || m.common_pages_admin_enquiries_transition_error()}`)}</Alert>
        )}
        <Group justify="flex-end">
          <Button variant="default" onClick={onClose}>{m.common_actions_cancel()}</Button>
          <Button
            data-testid="waitlist-confirm"
            color="orange"
            onClick={() => mutation.mutate({ enquiryId: enquiry.enquiryId })}
            disabled={!hasOptions || mutation.isPending}
            loading={mutation.isPending}
          >
            {m.common_pages_admin_enquiries_actions_waitlist()}
          </Button>
        </Group>
      </Stack>
    </Modal>
  )
}

// ─── Decline modal ──────────────────────────────────────────────────────────

function DeclineModal({ enquiry, onClose, onDone }: { enquiry: Enquiry; onClose: () => void; onDone: () => void }) {
  useLocale()
  const mutation = usePikkuMutation('declineEnquiry', { onSuccess: onDone })

  return (
    <Modal opened onClose={onClose} title={m.common_pages_admin_enquiries_decline_modal_title()} size="md">
      <Stack gap="md">
        <Text size="sm">
          {m.common_pages_admin_enquiries_decline_modal_confirm({
            event: enquiry.eventName,
            date: enquiry.createdAt ? fmtDate(enquiry.createdAt, getLocale()) : '',
          })}
        </Text>
        {mutation.error && (
          <Alert color="red">{asI18n(`${mutation.error.message || m.common_pages_admin_enquiries_transition_error()}`)}</Alert>
        )}
        <Group justify="flex-end">
          <Button variant="default" onClick={onClose}>{m.common_actions_cancel()}</Button>
          <Button
            data-testid="decline-confirm"
            color="red"
            onClick={() => mutation.mutate({ enquiryId: enquiry.enquiryId })}
            disabled={mutation.isPending}
            loading={mutation.isPending}
          >
            {m.common_pages_admin_enquiries_actions_decline()}
          </Button>
        </Group>
      </Stack>
    </Modal>
  )
}

function AdminEnquiriesPage() {
  return (
    <RequireAuth roles={['admin', 'owner']}>
      <AdminEnquiriesInner />
    </RequireAuth>
  )
}

export const Route = createFileRoute('/admin/enquiries')({
  component: AdminEnquiriesPage,
})
