import { useEffect, useState } from 'react'
import useSWR from 'swr'
import {
  ActionIcon,
  Avatar,
  Badge,
  Code,
  Group,
  Loader,
  Pagination,
  Paper,
  ScrollArea,
  Select,
  Stack,
  Table,
  Text,
  TextInput,
  Title,
  Tooltip,
} from '@mantine/core'
import { useDebouncedValue, useMediaQuery } from '@mantine/hooks'
import { DatePickerInput } from '@mantine/dates'
import { createFileRoute, useParams } from '@tanstack/react-router'
import {
  TbAlertCircle,
  TbCalendar,
  TbHistory,
  TbHome2,
  TbSearch,
  TbX,
} from 'react-icons/tb'
import { API_URLS } from '../config/api'

export const Route = createFileRoute('/apps/$appId/logs')({
  component: AppLogsPage,
})

interface LogEntry {
  id: string
  createdAt: string
  action: string
  desc: string
  username: string
  village: string
}

const fetcher = (url: string) => fetch(url).then((res) => res.json())

const ACTION_COLOR: Record<string, string> = {
  LOGIN: 'teal',
  LOGOUT: 'gray',
  CREATE: 'blue',
  UPDATE: 'yellow',
  DELETE: 'red',
}

const ACTION_OPTIONS = [
  { value: 'LOGIN', label: 'Login' },
  { value: 'LOGOUT', label: 'Logout' },
  { value: 'CREATE', label: 'Create' },
  { value: 'UPDATE', label: 'Update' },
  { value: 'DELETE', label: 'Delete' },
]

function getActionColor(action: string) {
  return ACTION_COLOR[action.toUpperCase()] ?? 'brand-blue'
}

function LogTimestamp({ value }: { value: string }) {
  if (value.endsWith('lalu')) {
    return <Text size="xs" fw={600}>{value}</Text>
  }
  const [time, ...dateParts] = value.split(' ')
  return (
    <Stack gap={0}>
      <Text size="xs" fw={600}>{dateParts.join(' ')}</Text>
      <Text size="xs" c="dimmed">{time}</Text>
    </Stack>
  )
}

function AppLogsPage() {
  const { appId } = useParams({ from: '/apps/$appId/logs' })
  const [page, setPage] = useState(1)
  const [search, setSearch] = useState('')
  const [searchQuery, setSearchQuery] = useState('')
  const [debouncedSearch] = useDebouncedValue(search, 400)
  const [filterAction, setFilterAction] = useState<string | null>(null)
  const [filterVillageSearch, setFilterVillageSearch] = useState('')
  const [filterVillageId, setFilterVillageId] = useState<string | null>(null)
  const [dateRange, setDateRange] = useState<[string | null, string | null]>([null, null])

  const isDesaPlus = appId === 'desa-plus'
  const isMobile = useMediaQuery('(max-width: 768px)')

  const [dateFrom, dateTo] = dateRange
  const apiUrl = isDesaPlus
    ? API_URLS.getLogsAllVillages(
        page,
        searchQuery,
        filterAction ?? undefined,
        filterVillageId ?? undefined,
        dateFrom ?? undefined,
        dateTo ?? undefined,
      )
    : null
  const { data: response, error, isLoading } = useSWR(apiUrl, fetcher)
  const logs: LogEntry[] = response?.data?.log || []

  const { data: filterVillagesResp } = useSWR(
    isDesaPlus && filterVillageSearch.length >= 1 ? API_URLS.getVillages(1, filterVillageSearch) : null,
    fetcher
  )
  const filterVillagesOptions = (filterVillagesResp?.data || []).map((v: any) => ({ value: v.id, label: v.name }))

  useEffect(() => {
    if (debouncedSearch.length >= 3 || debouncedSearch.length === 0) {
      setSearchQuery(debouncedSearch)
      setPage(1)
    }
  }, [debouncedSearch])

  useEffect(() => {
    setPage(1)
  }, [filterAction, filterVillageId, dateFrom, dateTo])

  const handleClearSearch = () => {
    setSearch('')
    setSearchQuery('')
    setPage(1)
  }

  if (!isDesaPlus) {
    return (
      <Paper withBorder radius="2xl" className="glass" p="xl">
        <Stack align="center" gap="xs" py="xl">
          <TbHistory size={36} style={{ opacity: 0.25 }} />
          <Text fw={600} size="sm">Activity Logs — Coming Soon</Text>
          <Text size="sm" c="dimmed">This feature is currently available for Desa+. Other apps coming soon.</Text>
        </Stack>
      </Paper>
    )
  }

  return (
    <Stack gap="xl" py="md">
      <Group justify="space-between" align="flex-start">
        <Stack gap={4}>
          <Title order={3}>Activity Logs</Title>
          <Text size="sm" c="dimmed">
            {isLoading
              ? 'Loading logs...'
              : `${(response?.data?.total ?? 0).toLocaleString()} events across all villages`}
          </Text>
        </Stack>
      </Group>

      <Paper withBorder p="md" className="glass">
        <Stack gap="sm">
          <TextInput
            placeholder="Search by user name or village..."
            leftSection={<TbSearch size={16} />}
            size="sm"
            rightSection={
              search ? (
                <Tooltip label="Clear search" withArrow>
                  <ActionIcon variant="transparent" color="gray" onClick={handleClearSearch} size="sm">
                    <TbX size={16} />
                  </ActionIcon>
                </Tooltip>
              ) : null
            }
            value={search}
            onChange={(e) => setSearch(e.currentTarget.value)}
            radius="md"
          />
          <Group gap="sm" wrap="nowrap">
            <Select
              size="sm"
              placeholder="All actions"
              data={ACTION_OPTIONS}
              value={filterAction}
              onChange={setFilterAction}
              radius="md"
              clearable
              style={{ flex: 1 }}
            />
            <Select
              size="sm"
              placeholder="Search village..."
              searchable
              onSearchChange={setFilterVillageSearch}
              data={filterVillagesOptions}
              value={filterVillageId}
              onChange={setFilterVillageId}
              radius="md"
              clearable
              style={{ flex: 1 }}
            />
            <DatePickerInput
              type="range"
              size="sm"
              placeholder="Date range"
              leftSection={<TbCalendar size={16} />}
              value={dateRange}
              onChange={setDateRange}
              radius="md"
              clearable
              style={{ flex: 1 }}
              maxDate={new Date()}
            />
          </Group>
        </Stack>
      </Paper>

      {isLoading ? (
        <Group justify="center" py="xl">
          <Loader type="dots" />
        </Group>
      ) : error ? (
        <Paper withBorder radius="2xl" className="glass" p="md">
          <Stack align="center" gap="xs" py="xl">
            <TbAlertCircle size={32} style={{ opacity: 0.4, color: 'var(--mantine-color-red-6)' }} />
            <Text size="sm" c="dimmed">Failed to load logs from the API.</Text>
          </Stack>
        </Paper>
      ) : logs.length === 0 ? (
        <Paper withBorder radius="2xl" className="glass" p="md">
          <Stack align="center" gap="xs" py="xl">
            <TbHistory size={32} style={{ opacity: 0.25 }} />
            <Text size="sm" c="dimmed">
              {searchQuery || filterAction || filterVillageId || dateFrom ? 'No activity found for this filter.' : 'No activity logs yet.'}
            </Text>
          </Stack>
        </Paper>
      ) : (
        <Paper withBorder radius="2xl" className="glass" style={{ overflow: 'hidden' }}>
          <ScrollArea h={isMobile ? undefined : 'auto'} offsetScrollbars>
            <Table
              className="data-table"
              verticalSpacing="sm"
              horizontalSpacing="lg"
              highlightOnHover
              withColumnBorders={false}
              style={{
                tableLayout: isMobile ? 'auto' : 'fixed',
                width: '100%',
                minWidth: isMobile ? 900 : 'unset',
              }}
            >
              <Table.Thead>
                <Table.Tr>
                  <Table.Th style={{ width: isMobile ? undefined : '18%' }}>Timestamp</Table.Th>
                  <Table.Th style={{ width: isMobile ? undefined : '22%' }}>User & Village</Table.Th>
                  <Table.Th style={{ width: isMobile ? undefined : '14%' }}>Action</Table.Th>
                  <Table.Th>Description</Table.Th>
                </Table.Tr>
              </Table.Thead>
              <Table.Tbody>
                {logs.map((log) => (
                  <Table.Tr key={log.id}>
                    <Table.Td>
                      <LogTimestamp value={log.createdAt} />
                    </Table.Td>
                    <Table.Td>
                      <Stack gap={4} style={{ overflow: 'hidden' }}>
                        <Group gap={6} wrap="nowrap">
                          <Avatar size="xs" radius="xl" color="brand-blue" variant="light">
                            {log.username.charAt(0)}
                          </Avatar>
                          <Text size="xs" fw={600} truncate="end">{log.username}</Text>
                        </Group>
                        <Group gap={6} wrap="nowrap">
                          <TbHome2 size={12} color="gray" />
                          <Text size="xs" c="dimmed" truncate="end">{log.village}</Text>
                        </Group>
                      </Stack>
                    </Table.Td>
                    <Table.Td>
                      <Badge
                        variant="light"
                        color={getActionColor(log.action)}
                        size="sm"
                        tt="capitalize"
                      >
                        {log.action}
                      </Badge>
                    </Table.Td>
                    <Table.Td>
                      <Code
                        color="brand-blue"
                        bg="rgba(37, 99, 235, 0.05)"
                        fw={600}
                        style={{ fontSize: 11, display: 'block', whiteSpace: 'normal' }}
                      >
                        {log.desc}
                      </Code>
                    </Table.Td>
                  </Table.Tr>
                ))}
              </Table.Tbody>
            </Table>
          </ScrollArea>
        </Paper>
      )}

      {!isLoading && !error && response?.data?.totalPage > 1 && (
        <Group justify="center">
          <Pagination
            value={page}
            onChange={setPage}
            total={response.data.totalPage}
            size="sm"
            radius="md"
            withEdges={false}
            siblings={1}
            boundaries={1}
          />
        </Group>
      )}
    </Stack>
  )
}
