import { createFileRoute, Link } from '@tanstack/react-router'
import {
  Title,
  Text,
  Card,
  Group,
  Stack,
  Badge,
  Button,
  SimpleGrid,
  Accordion,
  Anchor,
  Box,
  Drawer,
  Select,
  TextInput,
  Textarea,
} from '@pikku/mantine/core'
import { MapPin, Clock, Plus, Repeat, ShieldCheck } from 'lucide-react'
import { useQueryClient } from '@tanstack/react-query'
import { useDisclosure } from '@mantine/hooks'
import { notifications } from '@mantine/notifications'
import { useState } from 'react'
import { asI18n } from '@pikku/react'
import { usePikkuQuery, usePikkuMutation } from '@perauset/functions-sdk/pikku/api.gen'
import { useLocale } from '@/i18n/config'
import { m } from '@/i18n/messages'
import { TaskActions } from '@/components/task-actions'

export const Route = createFileRoute('/_authenticated/tasks/')({
  component: TasksPage,
})

const STATUS_CONFIG: Record<string, { color: string; order: number }> = {
  open: { color: 'teal', order: 0 },
  assigned: { color: 'blue', order: 1 },
  in_progress: { color: 'orange', order: 2 },
  blocked: { color: 'red', order: 3 },
  planned: { color: 'gray', order: 4 },
  completed: { color: 'green', order: 5 },
  cancelled: { color: 'gray', order: 6 },
}

const CATEGORY_COLORS: Record<string, string> = {
  housekeeping: 'pink',
  kitchen: 'yellow',
  maintenance: 'orange',
  operations: 'blue',
  retreat: 'violet',
  transport: 'cyan',
}

const KANBAN_STATUSES = ['open', 'assigned', 'in_progress', 'blocked']

const CATEGORIES = [
  { value: 'housekeeping', label: m.tasks_category_housekeeping() },
  { value: 'kitchen', label: m.tasks_category_kitchen() },
  { value: 'maintenance', label: m.tasks_category_maintenance() },
  { value: 'operations', label: m.tasks_category_operations() },
  { value: 'retreat', label: m.tasks_category_retreat() },
  { value: 'transport', label: m.tasks_category_transport() },
]

const ROLE_OPTIONS = [
  { value: 'admin', label: m.tasks_role_admin() },
  { value: 'coordinator', label: m.tasks_role_coordinator() },
  { value: 'facilitator', label: m.tasks_role_facilitator() },
  { value: 'boat_coordinator', label: m.tasks_role_boat_coordinator() },
  { value: 'kitchen_lead', label: m.tasks_role_kitchen_lead() },
  { value: 'staff', label: m.tasks_role_staff() },
  { value: 'volunteer', label: m.tasks_role_volunteer() },
  { value: 'community_member', label: m.tasks_role_community_member() },
]

const STATUS_LABEL: Record<string, () => string> = {
  open: () => m.tasks_status_open(),
  assigned: () => m.tasks_status_assigned(),
  in_progress: () => m.tasks_status_in_progress(),
  blocked: () => m.tasks_status_blocked(),
  planned: () => m.tasks_status_planned(),
  completed: () => m.tasks_status_completed(),
  cancelled: () => m.tasks_status_cancelled(),
}

interface TaskItem {
  taskId: string
  templateId: string | null
  title: string
  description: string | null
  category: string
  status: string
  location: string | null
  scheduledStartAt: string | Date | null
  scheduledEndAt: string | Date | null
  assignedRole: string | null
  createdByUserId: string
}

function formatTime(val: string | Date | null): string | null {
  if (!val) return null
  const d = typeof val === 'string' ? new Date(val) : val
  return d.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    hour: 'numeric',
    minute: '2-digit',
  })
}

function statusLabel(status: string): string {
  return STATUS_LABEL[status]?.() ?? status
}

function TaskCard({ task, onAssignRole }: { task: TaskItem; onAssignRole: (taskId: string) => void }) {
  const cfg = STATUS_CONFIG[task.status] ?? { color: 'gray', order: 99 }

  return (
    <Card
      padding="md"
      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)',
        transition: 'transform 0.15s ease, box-shadow 0.15s ease',
      }}
    >
      <Stack gap="xs">
        <Group justify="space-between" align="flex-start" wrap="nowrap">
          <Text
            fw={600}
            size="sm"
            lineClamp={2}
            style={{ fontFamily: '"Cormorant", serif', fontSize: 16 }}
          >
            {asI18n(task.title)}
          </Text>
          <Badge size="xs" color={cfg.color} variant="light" style={{ flexShrink: 0 }}>
            {asI18n(statusLabel(task.status))}
          </Badge>
        </Group>

        <Group gap="xs">
          <Badge size="xs" variant="dot" color={CATEGORY_COLORS[task.category] ?? 'gray'}>
            {asI18n(task.category)}
          </Badge>
          {task.assignedRole && (
            <Badge
              size="xs"
              variant="light"
              color="grape"
              leftSection={<ShieldCheck size={10} />}
            >
              {asI18n(task.assignedRole.replace(/_/g, ' '))}
            </Badge>
          )}
        </Group>

        {task.location && (
          <Group gap={4}>
            <MapPin size={14} color="#888" />
            <Text size="xs" c="dimmed">
              {asI18n(task.location)}
            </Text>
          </Group>
        )}

        {task.scheduledStartAt && (
          <Group gap={4}>
            <Clock size={14} color="#888" />
            <Text size="xs" c="dimmed">
              {asI18n(
                `${formatTime(task.scheduledStartAt)}${task.scheduledEndAt ? ` - ${formatTime(task.scheduledEndAt)}` : ''}`
              )}
            </Text>
          </Group>
        )}

        <Group gap="xs">
          <TaskActions taskId={task.taskId} status={task.status} />
          {(task.status === 'open' || task.status === 'planned') && (
            <Button size="xs" variant="light" color="grape" onClick={() => onAssignRole(task.taskId)}>
              {m.tasks_assign_role()}
            </Button>
          )}
        </Group>
      </Stack>
    </Card>
  )
}

function CreateTaskDrawer({ opened, onClose }: { opened: boolean; onClose: () => void }) {
  const queryClient = useQueryClient()
  const [title, setTitle] = useState('')
  const [description, setDescription] = useState('')
  const [category, setCategory] = useState<string | null>(null)
  const [location, setLocation] = useState('')
  const [scheduledStartAt, setScheduledStartAt] = useState('')
  const [scheduledEndAt, setScheduledEndAt] = useState('')
  const [assignedRole, setAssignedRole] = useState<string | null>(null)

  const assignToRole = usePikkuMutation('assignTaskToRole')
  const mutation = usePikkuMutation('createTaskInstance', {
    onSuccess: async (result) => {
      if (assignedRole && result.taskId) {
        await assignToRole.mutateAsync({ taskId: result.taskId, role: assignedRole })
      }
      queryClient.invalidateQueries({ queryKey: ['listTasks'] })
      notifications.show({
        title: m.tasks_created_title(),
        message: m.tasks_created_message({ title }),
        color: 'teal',
      })
      resetForm()
      onClose()
    },
    onError: (err) => {
      notifications.show({
        title: m.tasks_error_title(),
        message: err.message ?? m.tasks_error_generic(),
        color: 'red',
      })
    },
  })

  const resetForm = () => {
    setTitle('')
    setDescription('')
    setCategory(null)
    setLocation('')
    setScheduledStartAt('')
    setScheduledEndAt('')
    setAssignedRole(null)
  }

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()

    if (!title.trim() || !category) {
      notifications.show({
        title: m.tasks_validation_title(),
        message: m.tasks_validation_message(),
        color: 'orange',
      })
      return
    }

    mutation.mutate({
      title: title.trim(),
      category: category as 'housekeeping' | 'kitchen' | 'maintenance' | 'operations' | 'retreat' | 'transport',
      ...(description.trim() ? { description: description.trim() } : {}),
      ...(location.trim() ? { location: location.trim() } : {}),
      ...(scheduledStartAt
        ? { scheduledStartAt: new Date(scheduledStartAt).toISOString() }
        : {}),
      ...(scheduledEndAt
        ? { scheduledEndAt: new Date(scheduledEndAt).toISOString() }
        : {}),
    })
  }

  return (
    <Drawer position="right" size="md" opened={opened} onClose={onClose} title={m.tasks_create_new_task()}>
      <form onSubmit={handleSubmit}>
        <Stack gap="md">
          <TextInput
            label={m.tasks_field_title()}
            placeholder={m.tasks_title_placeholder()}
            value={title}
            onChange={(e) => setTitle(e.currentTarget.value)}
            required
          />

          <Textarea
            label={m.tasks_field_description()}
            placeholder={m.tasks_description_placeholder()}
            value={description}
            onChange={(e) => setDescription(e.currentTarget.value)}
            minRows={3}
          />

          <Select
            label={m.tasks_category()}
            placeholder={m.tasks_select_category()}
            data={CATEGORIES}
            value={category}
            onChange={setCategory}
            required
          />

          <TextInput
            label={m.tasks_location()}
            placeholder={m.tasks_location_placeholder()}
            value={location}
            onChange={(e) => setLocation(e.currentTarget.value)}
          />

          <Group grow>
            <TextInput
              label={m.tasks_scheduled_start()}
              type="datetime-local"
              value={scheduledStartAt}
              onChange={(e) => setScheduledStartAt(e.currentTarget.value)}
            />
            <TextInput
              label={m.tasks_scheduled_end()}
              type="datetime-local"
              value={scheduledEndAt}
              onChange={(e) => setScheduledEndAt(e.currentTarget.value)}
              min={scheduledStartAt || undefined}
            />
          </Group>

          <Select
            label={m.tasks_assign_to_role_optional()}
            placeholder={m.tasks_select_role()}
            data={ROLE_OPTIONS}
            value={assignedRole}
            onChange={setAssignedRole}
            clearable
          />

          <Group justify="flex-end" mt="sm">
            <Button variant="subtle" color="gray" onClick={onClose}>
              {m.tasks_cancel()}
            </Button>
            <Button type="submit" color="teal" loading={mutation.isPending || assignToRole.isPending}>
              {m.tasks_create_task()}
            </Button>
          </Group>
        </Stack>
      </form>
    </Drawer>
  )
}

function TasksPage() {
  useLocale()
  const queryClient = useQueryClient()
  const [roleDrawerOpened, { open: openRoleDrawer, close: closeRoleDrawer }] = useDisclosure(false)
  const [createDrawerOpened, { open: openCreateDrawer, close: closeCreateDrawer }] = useDisclosure(false)
  const [roleTaskId, setRoleTaskId] = useState<string | null>(null)
  const [selectedRole, setSelectedRole] = useState<string | null>(null)

  function handleOpenRoleDrawer(taskId: string) {
    setRoleTaskId(taskId)
    setSelectedRole(null)
    openRoleDrawer()
  }

  const assignRoleMutation = usePikkuMutation('assignTaskToRole', {
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['listTasks'] })
      notifications.show({
        title: m.tasks_role_assigned_title(),
        message: m.tasks_role_assigned_message(),
        color: 'green',
      })
      closeRoleDrawer()
      setRoleTaskId(null)
      setSelectedRole(null)
    },
    onError: (err) => {
      notifications.show({
        title: m.tasks_error_title(),
        message: err.message || m.tasks_error_assign_role(),
        color: 'red',
      })
    },
  })

  const generateMutation = usePikkuMutation('generateRecurringTasks', {
    onSuccess: (result) => {
      queryClient.invalidateQueries({ queryKey: ['listTasks'] })
      notifications.show({
        title: m.tasks_generated_title(),
        message: m.tasks_generated_message({ count: result.generated }),
        color: 'green',
      })
    },
    onError: (err) => {
      notifications.show({
        title: m.tasks_error_title(),
        message: err.message || m.tasks_error_generate(),
        color: 'red',
      })
    },
  })

  const { data, error: queryError } = usePikkuQuery('listTasks', { limit: 50, offset: 0 })
  const tasks = (data?.items ?? []) as TaskItem[]
  const error = queryError?.message ?? null

  const grouped: Record<string, TaskItem[]> = {}
  for (const status of KANBAN_STATUSES) {
    grouped[status] = []
  }
  for (const task of tasks) {
    const key = KANBAN_STATUSES.includes(task.status) ? task.status : 'open'
    grouped[key]!.push(task)
  }

  return (
    <>
      <Stack gap="lg">
        <Group justify="space-between" align="flex-end">
          <div>
            <Title order={2} style={{ fontFamily: '"Cormorant", serif', color: '#3D2B1F' }}>
              {m.tasks_title()}
            </Title>
            <Text size="sm" c="dimmed" mt={4}>
              {m.tasks_description()}
            </Text>
          </div>
          <Group gap="xs">
            <Button
              variant="light"
              color="teal"
              size="xs"
              leftSection={<Repeat size={14} />}
              onClick={() => generateMutation.mutate({ date: new Date().toISOString().split('T')[0] })}
              loading={generateMutation.isPending}
            >
              {m.tasks_generate_recurring()}
            </Button>
            <Anchor component={Link} to="/tasks/templates" size="sm" c="dimmed" style={{ textDecoration: 'none' }}>
              {m.tasks_templates()}
            </Anchor>
            <Button variant="subtle" size="xs" onClick={openCreateDrawer} leftSection={<Plus size={14} />}>
              {m.tasks_new_task()}
            </Button>
          </Group>
        </Group>

        {error && (
          <Card padding="md" radius="md" style={{ backgroundColor: '#fff3f3' }}>
            <Text size="sm" c="red">
              {asI18n(error)}
            </Text>
          </Card>
        )}

        {/* Mobile: Accordion */}
        <Box hiddenFrom="sm">
          <Accordion
            variant="separated"
            radius="md"
            multiple
            defaultValue={KANBAN_STATUSES}
            styles={{
              item: {
                backgroundColor: '#ffffff',
                boxShadow: '0 2px 12px rgba(61, 43, 31, 0.08), 0 1px 4px rgba(61, 43, 31, 0.04)',
              },
            }}
          >
            {KANBAN_STATUSES.map((status) => {
              const cfg = STATUS_CONFIG[status]!
              const items = grouped[status]!
              return (
                <Accordion.Item key={status} value={status}>
                  <Accordion.Control>
                    <Group gap="xs">
                      <Badge size="sm" color={cfg.color} variant="light">
                        {items.length}
                      </Badge>
                      <Text fw={600} size="sm">
                        {asI18n(statusLabel(status))}
                      </Text>
                    </Group>
                  </Accordion.Control>
                  <Accordion.Panel>
                    {items.length === 0 ? (
                      <Text size="sm" c="dimmed" ta="center" py="md">
                        {m.tasks_no_status_tasks({ status: statusLabel(status).toLowerCase() })}
                      </Text>
                    ) : (
                      <Stack gap="sm">
                        {items.map((task) => (
                          <TaskCard key={task.taskId} task={task} onAssignRole={handleOpenRoleDrawer} />
                        ))}
                      </Stack>
                    )}
                  </Accordion.Panel>
                </Accordion.Item>
              )
            })}
          </Accordion>
        </Box>

        {/* Desktop: Kanban columns */}
        <Box visibleFrom="sm">
          <SimpleGrid cols={4} spacing="md">
            {KANBAN_STATUSES.map((status) => {
              const cfg = STATUS_CONFIG[status]!
              const items = grouped[status]!
              return (
                <Stack key={status} gap="sm">
                  <Group gap="xs" mb={4}>
                    <Badge size="sm" color={cfg.color} variant="filled">
                      {items.length}
                    </Badge>
                    <Text
                      fw={600}
                      size="sm"
                      style={{ fontFamily: '"Cormorant", serif', fontSize: 16, color: '#3D2B1F' }}
                    >
                      {asI18n(statusLabel(status))}
                    </Text>
                  </Group>

                  {items.length === 0 ? (
                    <Card
                      padding="xl"
                      radius="md"
                      style={{
                        backgroundColor: 'rgba(245, 240, 232, 0.5)',
                        border: '2px dashed rgba(61, 43, 31, 0.1)',
                      }}
                    >
                      <Text size="sm" c="dimmed" ta="center">
                        {m.tasks_no_tasks()}
                      </Text>
                    </Card>
                  ) : (
                    items.map((task) => (
                      <TaskCard key={task.taskId} task={task} onAssignRole={handleOpenRoleDrawer} />
                    ))
                  )}
                </Stack>
              )
            })}
          </SimpleGrid>
        </Box>
      </Stack>

      <Drawer
        opened={roleDrawerOpened}
        onClose={closeRoleDrawer}
        title={m.tasks_assign_to_role()}
        position="right"
        size="md"
      >
        <Stack gap="md">
          <Select
            label={m.tasks_role()}
            placeholder={m.tasks_select_role()}
            data={ROLE_OPTIONS}
            value={selectedRole}
            onChange={setSelectedRole}
            required
          />

          <Group justify="flex-end" mt="md">
            <Button variant="default" onClick={closeRoleDrawer}>
              {m.tasks_cancel()}
            </Button>
            <Button
              color="grape"
              onClick={() => {
                if (roleTaskId && selectedRole) {
                  assignRoleMutation.mutate({ taskId: roleTaskId, role: selectedRole })
                }
              }}
              loading={assignRoleMutation.isPending}
              disabled={!selectedRole}
            >
              {m.tasks_assign_role()}
            </Button>
          </Group>
        </Stack>
      </Drawer>

      <CreateTaskDrawer opened={createDrawerOpened} onClose={closeCreateDrawer} />
    </>
  )
}
