import { createFileRoute } from '@tanstack/react-router'
import { useState } from 'react'
import { m, mKey, mExists } from '@/i18n/messages'
import { useLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import {
  ActionIcon,
  Alert,
  Box,
  Button,
  Checkbox,
  Container,
  Divider,
  Group,
  NumberInput,
  Paper,
  Select,
  SimpleGrid,
  Stack,
  Text,
  Textarea,
  TextInput,
  Tooltip,
} from '@pikku/mantine/core'
import { Info, Plus, Trash2 } from 'lucide-react'
import { usePikkuMutation } from '@project/functions-sdk/pikku/api.gen'
import { MarketingShell } from '../components/MarketingShell'
import { PageTitle } from '../components/AppLayout'

type DateOption = { startDate: string; endDate: string }

const MAX_DATE_OPTIONS = 3

type State = {
  eventName: string
  eventOutline: string
  description: string
  // 0–3 prioritized date options, in priority order (first = preferred).
  dateOptions: DateOption[]
  expectedPersons: string
  halfHouse: boolean
  clientName: string
  contactEmail: string
  contactPhone: string
  website: string
  notes: string
  agbAccepted: boolean
  privacyAccepted: boolean
}

const empty = (search?: { date?: string; from?: string; to?: string }): State => {
  const seedStart = search?.from ?? search?.date ?? ''
  const seedEnd = search?.to ?? search?.date ?? ''
  return {
    eventName: '',
    eventOutline: '',
    description: '',
    dateOptions: [{ startDate: seedStart, endDate: seedEnd }],
    expectedPersons: '',
    halfHouse: false,
    clientName: '',
    contactEmail: '',
    contactPhone: '',
    website: '',
    notes: '',
    agbAccepted: false,
    privacyAccepted: false,
  }
}

function EnquiryPage() {
  useLocale()
  const search = Route.useSearch()
  const [form, setForm] = useState<State>(() => empty(search))
  const [success, setSuccess] = useState<string | null>(null)

  const mutation = usePikkuMutation('submitEnquiry', {
    onSuccess: (data) => setSuccess(data.enquiryId),
  })

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

  const setOption = (i: number, patch: Partial<DateOption>) =>
    setForm((f) => ({
      ...f,
      dateOptions: f.dateOptions.map((o, idx) => (idx === i ? { ...o, ...patch } : o)),
    }))

  const addOption = () =>
    setForm((f) =>
      f.dateOptions.length >= MAX_DATE_OPTIONS
        ? f
        : { ...f, dateOptions: [...f.dateOptions, { startDate: '', endDate: '' }] },
    )

  const removeOption = (i: number) =>
    setForm((f) => ({ ...f, dateOptions: f.dateOptions.filter((_, idx) => idx !== i) }))

  // A row is "complete" only when both dates are set and ordered. Partially
  // filled or reversed rows block submission; fully empty form = no dates (ok).
  const rowState = (o: DateOption): 'empty' | 'complete' | 'invalid' => {
    if (!o.startDate && !o.endDate) return 'empty'
    if (o.startDate && o.endDate && o.startDate <= o.endDate) return 'complete'
    return 'invalid'
  }
  const optionsValid = form.dateOptions.every((o) => rowState(o) !== 'invalid')

  const submit = () => {
    const dateOptions = form.dateOptions
      .filter((o) => rowState(o) === 'complete')
      .map((o) => ({ startDate: o.startDate, endDate: o.endDate }))
    mutation.mutate({
      venueSlug: 'drawehn',
      contact: {
        name: form.clientName.trim() || undefined,
        contactEmail: form.contactEmail,
        contactPhone: form.contactPhone || undefined,
        website: form.website || undefined,
      },
      event: {
        eventName: form.eventName,
        eventOutline: form.eventOutline || undefined,
        description: form.description || undefined,
        expectedPersons: form.expectedPersons ? Number(form.expectedPersons) : undefined,
        halfHouse: form.halfHouse,
      },
      dateOptions: dateOptions.length ? dateOptions : undefined,
      notes: form.notes || undefined,
      privacyAccepted: form.privacyAccepted as true,
    })
  }

  if (success) {
    return (
      <MarketingShell>
        <Container size="sm" py="xl">
          <Alert color="green" title={m.common_pages_enquiry_success_title()}>
            {m.common_pages_enquiry_success_body({ enquiryId: success })}
          </Alert>
        </Container>
      </MarketingShell>
    )
  }

  const canSubmit =
    form.eventName.trim() &&
    form.contactEmail.trim() &&
    form.agbAccepted &&
    form.privacyAccepted &&
    optionsValid

  return (
    <MarketingShell>
    <Container size="md" py="xl">
      <Stack gap="lg">
        <PageTitle title={m.common_pages_enquiry_title()} />
        <Paper withBorder radius="md" p="lg">
          <Stack gap="lg">
            <Section title={m.common_pages_enquiry_sections_event()}>
              <TextInput
                data-testid="courseName"
                label={<FieldLabel label={m.common_pages_enquiry_fields_event_name()} hint="eventName" />}
                required
                value={form.eventName}
                onChange={(e) => set('eventName', e.currentTarget.value)}
              />
              <TextInput
                data-testid="eventOutline"
                label={<FieldLabel label={m.common_pages_enquiry_fields_event_outline()} hint="eventOutline" />}
                value={form.eventOutline}
                onChange={(e) => set('eventOutline', e.currentTarget.value)}
              />
              <Textarea
                data-testid="description"
                label={<FieldLabel label={m.common_pages_enquiry_fields_description()} hint="description" />}
                value={form.description}
                onChange={(e) => set('description', e.currentTarget.value)}
                autosize
                minRows={4}
              />
              <Stack gap="xs">
                <FieldLabel label={m.common_pages_enquiry_fields_date_options()} hint="dateOptions" />
                {form.dateOptions.length === 0 && (
                  <Text size="sm" c="dimmed">{m.common_pages_enquiry_date_options_none()}</Text>
                )}
                {form.dateOptions.map((opt, i) => {
                  const invalid = rowState(opt) === 'invalid'
                  return (
                    <Group key={i} gap="xs" align="flex-end" wrap="nowrap" data-testid={`date-option-${i}`}>
                      <TextInput
                        data-testid={i === 0 ? 'startDate' : `date-option-${i}-start`}
                        type="date"
                        flex={1}
                        label={i === 0 ? m.common_pages_enquiry_fields_start_date() : undefined}
                        value={opt.startDate}
                        onChange={(e) => setOption(i, { startDate: e.currentTarget.value })}
                        error={invalid ? m.common_pages_enquiry_date_options_invalid() : undefined}
                      />
                      <TextInput
                        data-testid={i === 0 ? 'endDate' : `date-option-${i}-end`}
                        type="date"
                        flex={1}
                        label={i === 0 ? m.common_pages_enquiry_fields_end_date() : undefined}
                        value={opt.endDate}
                        onChange={(e) => setOption(i, { endDate: e.currentTarget.value })}
                      />
                      <ActionIcon
                        variant="subtle"
                        color="gray"
                        size="lg"
                        aria-label={m.common_pages_enquiry_date_options_remove()}
                        data-testid={`date-option-${i}-remove`}
                        onClick={() => removeOption(i)}
                      >
                        <Trash2 size={16} />
                      </ActionIcon>
                    </Group>
                  )
                })}
                {form.dateOptions.length < MAX_DATE_OPTIONS && (
                  <Group>
                    <Button
                      variant="light"
                      color="plum"
                      size="xs"
                      leftSection={<Plus size={14} />}
                      onClick={addOption}
                      data-testid="add-date-option"
                    >
                      {m.common_pages_enquiry_date_options_add()}
                    </Button>
                  </Group>
                )}
              </Stack>
              <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
                <NumberInput
                  label={<FieldLabel label={m.common_pages_enquiry_fields_expected_persons()} hint="expectedPersons" />}
                  value={form.expectedPersons === '' ? '' : Number(form.expectedPersons)}
                  onChange={(v) => set('expectedPersons', v === '' ? '' : String(v))}
                  min={1}
                />
                <Select
                  label={<FieldLabel label={m.common_pages_enquiry_fields_half_house()} hint="halfHouse" />}
                  value={form.halfHouse ? 'true' : 'false'}
                  onChange={(v) => set('halfHouse', v === 'true')}
                  allowDeselect={false}
                  data={[
                    { value: 'false', label: m.common_pages_enquiry_fields_half_house_no() },
                    { value: 'true', label: m.common_pages_enquiry_fields_half_house_yes() },
                  ]}
                />
              </SimpleGrid>
            </Section>

            <Divider />
            <Section title={m.common_pages_enquiry_sections_client()}>
              <TextInput
                data-testid="organisationName"
                label={<FieldLabel label={m.common_pages_enquiry_fields_client_name()} hint="clientName" />}
                value={form.clientName}
                onChange={(e) => set('clientName', e.currentTarget.value)}
              />
              <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
                <TextInput
                  data-testid="contactEmail"
                  type="email"
                  label={<FieldLabel label={m.common_pages_enquiry_fields_contact_email()} hint="contactEmail" />}
                  required
                  value={form.contactEmail}
                  onChange={(e) => set('contactEmail', e.currentTarget.value)}
                />
                <TextInput
                  label={<FieldLabel label={m.common_pages_enquiry_fields_contact_phone()} hint="contactPhone" />}
                  value={form.contactPhone}
                  onChange={(e) => set('contactPhone', e.currentTarget.value)}
                />
                <TextInput
                  label={<FieldLabel label={m.common_pages_enquiry_fields_website()} hint="website" />}
                  value={form.website}
                  onChange={(e) => set('website', e.currentTarget.value)}
                />
              </SimpleGrid>
            </Section>

            <Divider />
            <Section title={m.common_pages_enquiry_sections_notes()}>
              <Textarea
                label={<FieldLabel label={m.common_pages_enquiry_fields_notes()} hint="notes" />}
                value={form.notes}
                onChange={(e) => set('notes', e.currentTarget.value)}
                autosize
                minRows={3}
              />
            </Section>

            <Divider />
            <Section title={m.common_pages_enquiry_sections_terms()}>
              <Checkbox
                data-testid="agbAccepted"
                label={m.common_pages_enquiry_agb_accept()}
                checked={form.agbAccepted}
                onChange={(e) => set('agbAccepted', e.currentTarget.checked)}
              />
              <Checkbox
                data-testid="privacyAccepted"
                label={<FieldLabel label={m.common_pages_enquiry_fields_privacy_accepted()} hint="privacyAccepted" />}
                checked={form.privacyAccepted}
                onChange={(e) => set('privacyAccepted', e.currentTarget.checked)}
              />
            </Section>

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

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

/**
 * Field label with an optional ℹ tooltip. The icon only renders when a hint
 * string exists at `pages.enquiry.hints.<hint>` — so adding/removing a hint key
 * in the locale files is all it takes to show or hide the tooltip per field.
 */
function FieldLabel({ label, hint }: { label: string; hint: string }) {
  useLocale()
  const key = `common.pages.enquiry.hints.${hint}`
  if (!mExists(key)) return <>{label}</>
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
      {label}
      <Tooltip
        label={mKey(key as any)}
        multiline
        w={240}
        withArrow
        events={{ hover: true, focus: true, touch: true }}
      >
        <Info
          size={14}
          aria-label={mKey(key as any)}
          tabIndex={0}
          style={{ cursor: 'help', opacity: 0.55, flexShrink: 0 }}
        />
      </Tooltip>
    </span>
  )
}

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('/enquiry')({
  component: EnquiryPage,
  validateSearch: (s: Record<string, unknown>): { date?: string; from?: string; to?: string } => ({
    date: typeof s.date === 'string' ? s.date : undefined,
    from: typeof s.from === 'string' ? s.from : undefined,
    to: typeof s.to === 'string' ? s.to : undefined,
  }),
})
