import { createFileRoute } from '@tanstack/react-router'
import { useEffect, useRef, useState } from 'react'
import { m } from '@/i18n/messages'
import { useLocale, getLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import { useQueryClient } from '@tanstack/react-query'
import {
  Alert,
  Box,
  Button,
  Checkbox,
  Container,
  Divider,
  Group,
  Loader,
  NumberInput,
  Paper,
  Radio,
  SimpleGrid,
  Stack,
  Text,
  Textarea,
  TextInput,
  Title,
} from '@pikku/mantine/core'
import { usePikkuMutation, usePikkuQuery } from '@project/functions-sdk/pikku/api.gen'
import { PageTitle } from '../components/AppLayout'
import { fmtDate } from '../lib/dates'

type FormState = {
  name: string
  billingAddress: string
  contactPhone: string
  website: string
  paymentMethod: 'cash' | 'transfer'
  expectedPersons: string
  arrivalTime: string
  departureTime: string
  dailyPlan: string
  onlineAd: boolean
  notes: string
  acceptTerms: boolean
  acceptPrivacy: boolean
}

/**
 * Public landing for the passwordless booking-form magic link. Consumes the
 * token (which issues a client session cookie), then renders the binding form.
 * The token IS the auth — this route is intentionally not behind RequireAuth.
 */
function BookingFormLanding() {
  const { token } = Route.useParams()
  useLocale()
  const qc = useQueryClient()
  const [bookingId, setBookingId] = useState<string | null>(null)
  // Outcome is tracked in component state (not the mutation observer) so it
  // survives StrictMode's mount→unmount→mount and the consumedRef guard below.
  const [phase, setPhase] = useState<'pending' | 'ready' | 'error'>('pending')
  const consumedRef = useRef(false)

  const consume = usePikkuMutation('consumeBookingFormLink', {
    onSuccess: async (data) => {
      await qc.invalidateQueries({ queryKey: ['me'] })
      setBookingId(data.bookingId)
      setPhase('ready')
    },
    onError: () => setPhase('error'),
  })

  useEffect(() => {
    if (consumedRef.current) return
    consumedRef.current = true
    consume.mutate({ token })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [token])

  if (phase === 'error') {
    return (
      <Container size="sm" py="xl">
        <PageTitle title={m.common__pages__booking_form__title()} />
        <Alert color="red" title={m.common__pages__booking_form__link_invalid__title()}>
          {m.common__pages__booking_form__link_invalid__body()}
        </Alert>
      </Container>
    )
  }

  if (!bookingId) {
    return (
      <Container size="sm" py="xl">
        <Group justify="center" py="xl">
          <Loader color="plum" />
          <Text c="dimmed">{m.common__states__loading()}</Text>
        </Group>
      </Container>
    )
  }

  return <BookingFormInner bookingId={bookingId} />
}

function BookingFormInner({ bookingId }: { bookingId: string }) {
  useLocale()
  const [form, setForm] = useState<FormState | null>(null)
  const [success, setSuccess] = useState(false)

  const { data, isLoading, error } = usePikkuQuery('getBookingFormData', { bookingId })

  const submit = usePikkuMutation('submitBookingForm', {
    onSuccess: () => setSuccess(true),
  })

  // Seed editable state once the prefill data arrives.
  useEffect(() => {
    if (data && !form) {
      setForm({
        name: data.client.name ?? '',
        billingAddress: data.client.billingAddress ?? '',
        contactPhone: data.client.contactPhone ?? '',
        website: data.client.website ?? '',
        paymentMethod: (data.paymentMethod as 'cash' | 'transfer') ?? 'cash',
        expectedPersons: data.expectedPersons != null ? String(data.expectedPersons) : '',
        arrivalTime: data.arrivalTime ?? '',
        departureTime: data.departureTime ?? '',
        dailyPlan: data.dailyPlan ?? '',
        onlineAd: data.onlineAd,
        notes: data.notes ?? '',
        acceptTerms: false,
        acceptPrivacy: false,
      })
    }
  }, [data, form])

  if (isLoading || !form) {
    if (error) {
      return (
        <Container size="sm" py="xl">
          <Alert color="red">{m.common__states__error()}</Alert>
        </Container>
      )
    }
    return (
      <Container size="sm" py="xl">
        <Group justify="center" py="xl">
          <Loader color="plum" />
        </Group>
      </Container>
    )
  }

  const set = <K extends keyof FormState>(key: K, value: FormState[K]) =>
    setForm((f) => (f ? { ...f, [key]: value } : f))

  if (success) {
    return (
      <Container size="sm" py="xl">
        <PageTitle title={m.common__pages__booking_form__title()} />
        <Alert color="green" title={m.common__pages__booking_form__success__title()}>
          {m.common__pages__booking_form__success__body()}
        </Alert>
      </Container>
    )
  }

  const canSubmit =
    form.name.trim() &&
    form.billingAddress.trim() &&
    form.acceptTerms &&
    form.acceptPrivacy

  const submitForm = () => {
    submit.mutate({
      bookingId,
      name: form.name.trim(),
      billingAddress: form.billingAddress.trim(),
      contactPhone: form.contactPhone || undefined,
      website: form.website || undefined,
      paymentMethod: form.paymentMethod,
      expectedPersons: form.expectedPersons ? Number(form.expectedPersons) : undefined,
      arrivalTime: form.arrivalTime || undefined,
      departureTime: form.departureTime || undefined,
      dailyPlan: form.dailyPlan || undefined,
      onlineAd: form.onlineAd,
      notes: form.notes || undefined,
      acceptTerms: form.acceptTerms,
      acceptPrivacy: form.acceptPrivacy,
    })
  }

  return (
    <Container size="md" py="xl">
      <PageTitle title={m.common__pages__booking_form__title()} />
      <Stack gap="lg">
        <Box>
          <Title order={2}>{m.common__pages__booking_form__heading()}</Title>
          <Text c="dimmed" mt={4}>
            {asI18n(
              `${data!.eventName}${data!.startDate ? ` · ${fmtDate(new Date(data!.startDate), getLocale())}` : ''}${data!.endDate ? ` → ${fmtDate(new Date(data!.endDate), getLocale())}` : ''}`,
            )}
          </Text>
        </Box>

        <Paper withBorder radius="md" p="lg">
          <Stack gap="lg">
            <Section title={m.common__pages__booking_form__sections__billing()}>
              <TextInput
                label={m.common__pages__booking_form__fields__name()}
                required
                value={form.name}
                onChange={(e) => set('name', e.currentTarget.value)}
              />
              <Textarea
                label={m.common__pages__booking_form__fields__billing_address()}
                required
                autosize
                minRows={3}
                value={form.billingAddress}
                onChange={(e) => set('billingAddress', e.currentTarget.value)}
              />
              <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
                <TextInput
                  label={m.common__pages__booking_form__fields__contact_phone()}
                  value={form.contactPhone}
                  onChange={(e) => set('contactPhone', e.currentTarget.value)}
                />
                <TextInput
                  label={m.common__pages__booking_form__fields__website()}
                  value={form.website}
                  onChange={(e) => set('website', e.currentTarget.value)}
                />
              </SimpleGrid>
              <Radio.Group
                label={m.common__pages__booking_form__fields__payment_method()}
                value={form.paymentMethod}
                onChange={(v) => set('paymentMethod', v as 'cash' | 'transfer')}
                required
              >
                <Group mt="xs" gap="lg">
                  <Radio value="cash" label={m.common__pages__booking_form__payment__cash()} />
                  <Radio value="transfer" label={m.common__pages__booking_form__payment__transfer()} />
                </Group>
              </Radio.Group>
            </Section>

            <Divider />
            <Section title={m.common__pages__booking_form__sections__event()}>
              <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
                <NumberInput
                  label={m.common__pages__booking_form__fields__expected_persons()}
                  value={form.expectedPersons === '' ? '' : Number(form.expectedPersons)}
                  onChange={(v) => set('expectedPersons', v === '' ? '' : String(v))}
                  min={1}
                />
                <TextInput
                  label={m.common__pages__booking_form__fields__arrival_time()}
                  value={form.arrivalTime}
                  onChange={(e) => set('arrivalTime', e.currentTarget.value)}
                />
                <TextInput
                  label={m.common__pages__booking_form__fields__departure_time()}
                  value={form.departureTime}
                  onChange={(e) => set('departureTime', e.currentTarget.value)}
                />
              </SimpleGrid>
              <Textarea
                label={m.common__pages__booking_form__fields__daily_plan()}
                autosize
                minRows={2}
                value={form.dailyPlan}
                onChange={(e) => set('dailyPlan', e.currentTarget.value)}
              />
              <Checkbox
                label={m.common__pages__booking_form__fields__online_ad()}
                checked={form.onlineAd}
                onChange={(e) => set('onlineAd', e.currentTarget.checked)}
              />
              <Textarea
                label={m.common__pages__booking_form__fields__notes()}
                autosize
                minRows={2}
                value={form.notes}
                onChange={(e) => set('notes', e.currentTarget.value)}
              />
            </Section>

            <Divider />
            <Section title={m.common__pages__booking_form__sections__terms()}>
              <Checkbox
                label={m.common__pages__booking_form__fields__accept_terms()}
                checked={form.acceptTerms}
                onChange={(e) => set('acceptTerms', e.currentTarget.checked)}
              />
              <Checkbox
                label={m.common__pages__booking_form__fields__accept_privacy()}
                checked={form.acceptPrivacy}
                onChange={(e) => set('acceptPrivacy', e.currentTarget.checked)}
              />
            </Section>

            {submit.error && <Alert color="red">{m.common__pages__booking_form__error()}</Alert>}

            <Group justify="flex-end">
              <Button
                color="plum"
                onClick={submitForm}
                disabled={!canSubmit || submit.isPending}
                loading={submit.isPending}
              >
                {m.common__pages__booking_form__submit()}
              </Button>
            </Group>
          </Stack>
        </Paper>
      </Stack>
    </Container>
  )
}

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <Stack gap="sm">
      <Text size="xs" c="dimmed" fw={600} tt="uppercase">
        {asI18n(`${title}`)}
      </Text>
      <Box>
        <Stack gap="md">{children}</Stack>
      </Box>
    </Stack>
  )
}

export const Route = createFileRoute('/booking-form/$token')({
  component: BookingFormLanding,
})
