import { createFileRoute, Link } from '@tanstack/react-router'
import { useState } from 'react'
import {
  Stack,
  SimpleGrid,
  Card,
  Text,
  Group,
  Loader,
  Center,
  ActionIcon,
  Tooltip,
  Drawer,
  Textarea,
  Button,
  Select,
  TextInput,
} from '@pikku/mantine/core'
import { Sailboat, Play, Ban, Check, Plus } from 'lucide-react'
import { useQueryClient } from '@tanstack/react-query'
import { notifications } from '@mantine/notifications'
import { usePikkuQuery, usePikkuMutation } from '@perauset/functions-sdk/pikku/api.gen'
import { usePermission } from '@/lib/permissions'
import { PageHeader } from '@perauset/components'
import { StatusBadge } from '@perauset/components'
import { m } from '@/i18n/messages'
import { useLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'

export const Route = createFileRoute('/_authenticated/boats/')({
  component: BoatsPage,
})

type BoatTrip = {
  tripId: string
  boatId: string | null
  routeId: string
  status: string
  scheduledDepartureAt: string | Date
  scheduledArrivalAt: string | Date | null
  notes: string | null
}

function formatDateTime(dateStr: string | Date): string {
  try {
    return new Date(dateStr).toLocaleString('en-US', {
      month: 'short',
      day: 'numeric',
      year: 'numeric',
      hour: 'numeric',
      minute: '2-digit',
    })
  } catch {
    return String(dateStr)
  }
}

function BoatActions({ onCreateTrip }: { onCreateTrip?: () => void }) {
  const canManage = usePermission('boats.manage')
  return (
    <Group gap="sm">
      <Button component={Link} to="/boats/request" variant="light" color="teal" size="sm">
        {m.boats_request_seat()}
      </Button>
      {canManage && onCreateTrip && (
        <Button onClick={onCreateTrip} leftSection={<Plus size={16} />} color="teal" size="sm">
          {m.boats_create_trip()}
        </Button>
      )}
    </Group>
  )
}

function TripActions({ trip }: { trip: BoatTrip }) {
  const queryClient = useQueryClient()

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

  const openMutation = usePikkuMutation('openBoatTrip', {
    onSuccess: () => {
      invalidate()
      notifications.show({ title: 'Trip opened', message: 'Boat trip is now open for seat requests.', color: 'green' })
    },
    onError: (err) => notifications.show({ title: 'Error', message: err.message || 'Failed to open trip.', color: 'red' }),
  })

  const cancelMutation = usePikkuMutation('cancelBoatTrip', {
    onSuccess: () => {
      invalidate()
      notifications.show({ title: 'Trip cancelled', message: 'Boat trip has been cancelled.', color: 'orange' })
    },
    onError: (err) => notifications.show({ title: 'Error', message: err.message || 'Failed to cancel trip.', color: 'red' }),
  })

  const completeMutation = usePikkuMutation('completeBoatTrip', {
    onSuccess: () => {
      invalidate()
      notifications.show({ title: 'Trip completed', message: 'Boat trip has been marked as completed.', color: 'green' })
    },
    onError: (err) => notifications.show({ title: 'Error', message: err.message || 'Failed to complete trip.', color: 'red' }),
  })

  const canOpen = trip.status === 'planned'
  const canComplete = trip.status === 'open' || trip.status === 'in_progress'
  const canCancel = trip.status === 'planned' || trip.status === 'open'

  if (!canOpen && !canComplete && !canCancel) return null

  return (
    <Group gap="xs" onClick={(e) => e.preventDefault()}>
      {canOpen && (
        <Tooltip label={m.boats_open_for_requests()}>
          <ActionIcon
            variant="light"
            color="teal"
            size="sm"
            onClick={() => openMutation.mutate({ tripId: trip.tripId })}
            loading={openMutation.isPending}
          >
            <Play size={14} />
          </ActionIcon>
        </Tooltip>
      )}
      {canComplete && (
        <Tooltip label={m.boats_complete_trip()}>
          <ActionIcon
            variant="light"
            color="green"
            size="sm"
            onClick={() => completeMutation.mutate({ tripId: trip.tripId })}
            loading={completeMutation.isPending}
          >
            <Check size={14} />
          </ActionIcon>
        </Tooltip>
      )}
      {canCancel && (
        <Tooltip label={m.boats_cancel_trip()}>
          <ActionIcon
            variant="light"
            color="red"
            size="sm"
            onClick={() => cancelMutation.mutate({ tripId: trip.tripId })}
            loading={cancelMutation.isPending}
          >
            <Ban size={14} />
          </ActionIcon>
        </Tooltip>
      )}
    </Group>
  )
}

function CreateTripDrawer({
  opened,
  onClose,
  routeOptions,
  boatOptions,
}: {
  opened: boolean
  onClose: () => void
  routeOptions: Array<{ value: string; label: string }>
  boatOptions: Array<{ value: string; label: string }>
}) {
  const queryClient = useQueryClient()
  const [routeId, setRouteId] = useState<string | null>(null)
  const [boatId, setBoatId] = useState<string | null>(null)
  const [scheduledDepartureAt, setScheduledDepartureAt] = useState('')
  const [scheduledArrivalAt, setScheduledArrivalAt] = useState('')
  const [notes, setNotes] = useState('')

  const resetForm = () => {
    setRouteId(null)
    setBoatId(null)
    setScheduledDepartureAt('')
    setScheduledArrivalAt('')
    setNotes('')
  }

  const mutation = usePikkuMutation('createBoatTrip', {
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['listBoatTrips'] })
      notifications.show({ title: 'Trip created', message: 'Boat trip has been created successfully.', color: 'green' })
      resetForm()
      onClose()
    },
    onError: (err) => notifications.show({ title: 'Error', message: err.message || 'Failed to create boat trip.', color: 'red' }),
  })

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (!routeId || !scheduledDepartureAt) {
      notifications.show({ title: 'Missing fields', message: 'Route and departure time are required.', color: 'red' })
      return
    }
    mutation.mutate({
      routeId,
      boatId: boatId || undefined,
      scheduledDepartureAt: new Date(scheduledDepartureAt).toISOString(),
      scheduledArrivalAt: scheduledArrivalAt ? new Date(scheduledArrivalAt).toISOString() : undefined,
      notes: notes || undefined,
    })
  }

  return (
    <Drawer position="right" size="md" opened={opened} onClose={onClose} title={m.boats_create_trip()}>
      <form onSubmit={handleSubmit}>
        <Stack gap="md">
          <Select
            label={m.boats_route()}
            placeholder={m.boats_select_route()}
            data={routeOptions}
            value={routeId}
            onChange={setRouteId}
            searchable
            required
            nothingFoundMessage={m.boats_no_routes_available()}
          />
          <Select
            label={m.boats_boat()}
            placeholder={m.boats_select_boat_optional()}
            data={boatOptions}
            value={boatId}
            onChange={setBoatId}
            searchable
            clearable
            nothingFoundMessage={m.boats_no_boats_available()}
          />
          <TextInput
            label={m.boats_scheduled_departure()}
            type="datetime-local"
            value={scheduledDepartureAt}
            onChange={(e) => setScheduledDepartureAt(e.currentTarget.value)}
            required
          />
          <TextInput
            label={m.boats_scheduled_arrival()}
            type="datetime-local"
            value={scheduledArrivalAt}
            onChange={(e) => setScheduledArrivalAt(e.currentTarget.value)}
            min={scheduledDepartureAt || undefined}
          />
          <Textarea
            label={m.boats_notes()}
            placeholder={m.boats_additional_information()}
            value={notes}
            onChange={(e) => setNotes(e.currentTarget.value)}
            minRows={3}
          />
          <Group justify="flex-end" mt="sm">
            <Button variant="subtle" color="gray" onClick={onClose}>
              {m.common_cancel()}
            </Button>
            <Button type="submit" color="teal" loading={mutation.isPending}>
              {m.boats_create_trip()}
            </Button>
          </Group>
        </Stack>
      </form>
    </Drawer>
  )
}

function BoatsPage() {
  useLocale()
  const canManage = usePermission('boats.manage')
  const [createDrawerOpen, setCreateDrawerOpen] = useState(false)

  const { data, isLoading } = usePikkuQuery('listBoatTrips', { limit: 50, offset: 0 })
  const { data: routesData } = usePikkuQuery('listBoatRoutes', { limit: 100, offset: 0 })
  const { data: boatsData } = usePikkuQuery('listBoats', { limit: 100, offset: 0 })

  const trips = data?.items ?? []
  const routeMap = new Map((routesData?.items ?? []).map((r) => [r.routeId, r]))
  const boatMap = new Map((boatsData?.items ?? []).map((b) => [b.boatId, b]))

  if (isLoading) {
    return (
      <Center py="xl">
        <Loader color="teal" />
      </Center>
    )
  }

  return (
    <Stack gap="lg">
      <PageHeader
        title={m.boats_trips_title()}
        description={m.boats_trips_description()}
        action={<BoatActions onCreateTrip={() => setCreateDrawerOpen(true)} />}
      />

      {trips.length === 0 ? (
        <Card
          padding="xl"
          radius="md"
          style={{ backgroundColor: '#ffffff', boxShadow: '0 2px 12px rgba(61, 43, 31, 0.08), 0 1px 4px rgba(61, 43, 31, 0.04)' }}
        >
          <Text size="sm" c="dimmed" ta="center">
            {m.boats_no_trips()}
          </Text>
        </Card>
      ) : (
        <SimpleGrid cols={{ base: 1, md: 2 }} spacing="md">
          {trips.map((trip) => {
            const route = routeMap.get(trip.routeId)
            const boat = trip.boatId ? boatMap.get(trip.boatId) : null
            const routeLabel = route ? `${route.name} (${route.origin} - ${route.destination})` : 'Route'
            const boatLabel = boat ? boat.name : null

            return (
              <Card
                key={trip.tripId}
                component={Link}
                to="/boats/trips/$tripId"
                params={{ tripId: trip.tripId } as never}
                padding="lg"
                radius="md"
                className="card-hover"
                style={{
                  backgroundColor: '#ffffff',
                  boxShadow: '0 2px 12px rgba(61, 43, 31, 0.08), 0 1px 4px rgba(61, 43, 31, 0.04)',
                  textDecoration: 'none',
                  cursor: 'pointer',
                  transition: 'transform 0.15s ease, box-shadow 0.15s ease',
                }}
              >
                <Group justify="space-between" align="flex-start" mb="sm">
                  <Group gap="sm">
                    <Sailboat size={20} color="#2A7B88" />
                    <Text size="lg" fw={600} style={{ fontFamily: '"Cormorant", serif', color: '#3D2B1F' }}>
                      {asI18n(routeLabel)}
                    </Text>
                  </Group>
                  <Group gap="xs">
                    <StatusBadge status={trip.status} />
                    {canManage && <TripActions trip={trip} />}
                  </Group>
                </Group>

                <Group gap="lg" mt="md">
                  <div>
                    <Text size="xs" c="dimmed" tt="uppercase" fw={600}>
                      {m.boats_departure()}
                    </Text>
                    <Text size="sm">{asI18n(formatDateTime(trip.scheduledDepartureAt))}</Text>
                  </div>
                  {trip.scheduledArrivalAt && (
                    <div>
                      <Text size="xs" c="dimmed" tt="uppercase" fw={600}>
                        {m.boats_arrival()}
                      </Text>
                      <Text size="sm">{asI18n(formatDateTime(trip.scheduledArrivalAt))}</Text>
                    </div>
                  )}
                </Group>

                {boatLabel && (
                  <Text size="xs" c="dimmed" mt="sm">
                    {asI18n(`${m.boats_boat()}: ${boatLabel}`)}
                  </Text>
                )}
                {trip.boatId && !boatLabel && (
                  <Text size="xs" c="dimmed" mt="sm">
                    {asI18n(`${m.boats_boat()}: ${m.boats_assigned()}`)}
                  </Text>
                )}

                {trip.notes && (
                  <Text size="xs" c="dimmed" mt="xs" lineClamp={2}>
                    {asI18n(trip.notes)}
                  </Text>
                )}
              </Card>
            )
          })}
        </SimpleGrid>
      )}

      <CreateTripDrawer
        opened={createDrawerOpen}
        onClose={() => setCreateDrawerOpen(false)}
        routeOptions={(routesData?.items ?? []).map((r) => ({
          value: r.routeId,
          label: `${r.name} (${r.origin} - ${r.destination})`,
        }))}
        boatOptions={(boatsData?.items ?? []).map((b) => ({
          value: b.boatId,
          label: `${b.name} (${b.passengerCapacity} seats)`,
        }))}
      />
    </Stack>
  )
}
