import { createFileRoute, Link } from '@tanstack/react-router'
import { useState } from 'react'
import {
  Stack,
  SimpleGrid,
  Card,
  Text,
  Group,
  Badge,
  Loader,
  Center,
  Drawer,
  TextInput,
  NumberInput,
  Select,
  Textarea,
  Button,
  ActionIcon,
  Tooltip,
} from '@pikku/mantine/core'
import { Pencil, Search, 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 { m } from '@/i18n/messages'
import { useLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'

type RoomType = 'dorm' | 'facilitator' | 'private' | 'shared' | 'staff'

export const Route = createFileRoute('/_authenticated/rooms/')({
  component: RoomsPage,
})

type Room = {
  roomId: string
  code: string
  name: string
  roomType: string
  capacity: number
  pricePerNight: number | null
  isActive: boolean
  notes: string | null
}

const ROOM_TYPES = [
  { value: 'dorm', label: 'Dorm' },
  { value: 'facilitator', label: 'Facilitator' },
  { value: 'private', label: 'Private' },
  { value: 'shared', label: 'Shared' },
  { value: 'staff', label: 'Staff' },
]

const cardStyle = {
  backgroundColor: '#ffffff',
  boxShadow: '0 2px 12px rgba(61, 43, 31, 0.08), 0 1px 4px rgba(61, 43, 31, 0.04)',
}

function formatType(type: string): string {
  return type.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase())
}

function RoomActions({ onCreateRoom }: { onCreateRoom?: () => void }) {
  const canManage = usePermission('rooms.manage')
  if (!canManage) return null
  return (
    <Group gap="sm">
      <Button component={Link} to="/rooms/allocations" variant="light" color="teal" size="sm">
        {m.rooms_view_allocations()}
      </Button>
      <Button leftSection={<Plus size={16} />} color="teal" size="sm" onClick={onCreateRoom}>
        {m.rooms_create_room()}
      </Button>
    </Group>
  )
}

function CreateRoomDrawer({ opened, onClose }: { opened: boolean; onClose: () => void }) {
  const queryClient = useQueryClient()
  const [code, setCode] = useState('')
  const [name, setName] = useState('')
  const [roomType, setRoomType] = useState<RoomType | null>(null)
  const [capacity, setCapacity] = useState<number>(1)
  const [pricePerNight, setPricePerNight] = useState<number | undefined>(undefined)
  const [notes, setNotes] = useState('')

  const resetForm = () => {
    setCode('')
    setName('')
    setRoomType(null)
    setCapacity(1)
    setPricePerNight(undefined)
    setNotes('')
  }

  const mutation = usePikkuMutation('createRoom', {
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['listRooms'] })
      notifications.show({ title: 'Room created', message: 'New room has been added.', color: 'green' })
      resetForm()
      onClose()
    },
    onError: (err) => notifications.show({ title: 'Error', message: err.message || 'Failed to create room.', color: 'red' }),
  })

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (!code || !name || !roomType) {
      notifications.show({ title: 'Missing fields', message: 'Code, name, and room type are required.', color: 'red' })
      return
    }
    mutation.mutate({
      code,
      name,
      roomType,
      capacity,
      pricePerNight: pricePerNight || undefined,
      notes: notes || undefined,
    })
  }

  return (
    <Drawer position="right" size="md" opened={opened} onClose={onClose} title={m.rooms_create_room()}>
      <form onSubmit={handleSubmit}>
        <Stack gap="md">
          <TextInput label={m.rooms_room_code()} placeholder={m.rooms_room_code_placeholder()} value={code} onChange={(e) => setCode(e.currentTarget.value)} required />
          <TextInput label={m.rooms_room_name()} placeholder={m.rooms_room_name_placeholder()} value={name} onChange={(e) => setName(e.currentTarget.value)} required />
          <Select label={m.rooms_room_type()} placeholder={m.rooms_select_type()} data={ROOM_TYPES} value={roomType} onChange={(v) => setRoomType(v as RoomType | null)} required />
          <NumberInput label={m.rooms_capacity()} value={capacity} onChange={(val) => setCapacity(Number(val) || 1)} min={1} />
          <NumberInput label={m.rooms_price_per_night()} placeholder={m.rooms_price_placeholder()} value={pricePerNight} onChange={(val) => setPricePerNight(val ? Number(val) : undefined)} min={0} decimalScale={2} prefix={asI18n('€')} />
          <Textarea label={m.rooms_notes()} placeholder={m.rooms_notes_placeholder()} value={notes} onChange={(e) => setNotes(e.currentTarget.value)} minRows={2} />
          <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.rooms_save_room()}</Button>
          </Group>
        </Stack>
      </form>
    </Drawer>
  )
}

function EditRoomDrawer({ room, onClose }: { room: Room | null; onClose: () => void }) {
  const queryClient = useQueryClient()
  const [name, setName] = useState(room?.name ?? '')
  const [roomType, setRoomType] = useState<string | null>(room?.roomType ?? null)
  const [capacity, setCapacity] = useState<number>(room?.capacity ?? 1)
  const [notes, setNotes] = useState(room?.notes ?? '')

  const mutation = usePikkuMutation('updateRoom', {
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['listRooms'] })
      notifications.show({ title: 'Room updated', message: 'Room details have been saved.', color: 'green' })
      onClose()
    },
    onError: (err) => notifications.show({ title: 'Error', message: err.message || 'Failed to update room.', color: 'red' }),
  })

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (!room) return
    mutation.mutate({
      roomId: room.roomId,
      name,
      roomType: roomType ?? undefined,
      capacity,
      notes: notes || undefined,
    })
  }

  if (!room) return null

  return (
    <Drawer position="right" size="md" opened={!!room} onClose={onClose} title={m.rooms_edit_room()}>
      <form onSubmit={handleSubmit}>
        <Stack gap="md">
          <TextInput label={m.rooms_room_name()} value={name} onChange={(e) => setName(e.currentTarget.value)} required />
          <Select label={m.rooms_room_type()} data={ROOM_TYPES} value={roomType} onChange={setRoomType} required />
          <NumberInput label={m.rooms_capacity()} value={capacity} onChange={(val) => setCapacity(Number(val) || 1)} min={1} />
          <Textarea label={m.rooms_notes()} value={notes} onChange={(e) => setNotes(e.currentTarget.value)} minRows={2} />
          <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.common_save_changes()}</Button>
          </Group>
        </Stack>
      </form>
    </Drawer>
  )
}

function RoomsPage() {
  useLocale()
  const canManage = usePermission('rooms.manage')
  const [createModalOpen, setCreateModalOpen] = useState(false)
  const [editingRoom, setEditingRoom] = useState<Room | null>(null)
  const [startDate, setStartDate] = useState('')
  const [endDate, setEndDate] = useState('')

  const { data, isLoading } = usePikkuQuery('listRooms', { limit: 50, offset: 0 })

  const { data: availabilityData } = usePikkuQuery(
    'checkRoomAvailability',
    { startDate, endDate },
    { enabled: !!startDate && !!endDate },
  )

  const availabilityMap = new Map((availabilityData?.rooms ?? []).map((r) => [r.roomId, r]))

  const rooms = data?.items ?? []

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

  return (
    <Stack gap="lg">
      <PageHeader
        title={m.rooms_title()}
        description={m.rooms_description()}
        action={<RoomActions onCreateRoom={() => setCreateModalOpen(true)} />}
      />

      <Card padding="md" radius="md" style={cardStyle}>
        <Group gap="md" align="flex-end">
          <TextInput type="date" label={m.rooms_availability_start()} value={startDate} onChange={(e) => setStartDate(e.currentTarget.value)} size="sm" />
          <TextInput type="date" label={m.rooms_availability_end()} value={endDate} onChange={(e) => setEndDate(e.currentTarget.value)} size="sm" min={startDate || undefined} />
          {startDate && endDate && (
            <Badge color="teal" variant="light" size="lg">
              <Search size={12} style={{ marginRight: 4 }} />
              {m.rooms_showing_availability()}
            </Badge>
          )}
        </Group>
      </Card>

      {rooms.length === 0 ? (
        <Card padding="xl" radius="md" style={cardStyle}>
          <Text size="sm" c="dimmed" ta="center">
            {m.rooms_no_rooms()}
          </Text>
        </Card>
      ) : (
        <SimpleGrid cols={{ base: 1, xs: 2, md: 3 }} spacing="md">
          {rooms.map((room) => {
            const availability = availabilityMap.get(room.roomId)
            return (
              <Card key={room.roomId} padding="lg" radius="md" className="card-hover" style={{ ...cardStyle, transition: 'transform 0.15s ease, box-shadow 0.15s ease' }}>
                <Group justify="space-between" align="flex-start" mb="sm">
                  <Link to="/rooms/allocations" search={{ roomId: room.roomId }} style={{ textDecoration: 'none', flex: 1 }}>
                    <Text size="lg" fw={600} style={{ fontFamily: '"Cormorant", serif', color: '#3D2B1F' }}>
                      {asI18n(room.name)}
                    </Text>
                    <Text size="xs" c="dimmed" mt={2}>
                      {asI18n(room.code)}
                    </Text>
                  </Link>
                  <Group gap="xs">
                    <Badge color={room.isActive ? 'green' : 'gray'} variant="light" size="sm">
                      {room.isActive ? m.rooms_active() : m.rooms_inactive()}
                    </Badge>
                    {canManage && (
                      <Tooltip label={m.rooms_edit_room()}>
                        <ActionIcon variant="light" color="teal" size="sm" onClick={() => setEditingRoom(room)}>
                          <Pencil size={14} />
                        </ActionIcon>
                      </Tooltip>
                    )}
                  </Group>
                </Group>

                <Group gap="lg" mt="md">
                  <div>
                    <Text size="xs" c="dimmed" tt="uppercase" fw={600}>{m.rooms_type()}</Text>
                    <Text size="sm">{asI18n(formatType(room.roomType))}</Text>
                  </div>
                  <div>
                    <Text size="xs" c="dimmed" tt="uppercase" fw={600}>{m.rooms_capacity()}</Text>
                    <Text size="sm">{room.capacity}</Text>
                  </div>
                  <div>
                    <Text size="xs" c="dimmed" tt="uppercase" fw={600}>{m.rooms_price_night()}</Text>
                    <Text size="sm" fw={500}>{asI18n(room.pricePerNight != null ? `€${Number(room.pricePerNight).toFixed(2)}` : '—')}</Text>
                  </div>
                  {availability && (
                    <div>
                      <Text size="xs" c="dimmed" tt="uppercase" fw={600}>{m.rooms_availability()}</Text>
                      <Badge color={availability.available ? 'green' : 'red'} variant="filled" size="sm">
                        {availability.available ? m.rooms_available() : m.rooms_full()}
                      </Badge>
                    </div>
                  )}
                </Group>

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

      <CreateRoomDrawer opened={createModalOpen} onClose={() => setCreateModalOpen(false)} />
      <EditRoomDrawer room={editingRoom} onClose={() => setEditingRoom(null)} />
    </Stack>
  )
}
