import {
  ActionIcon,
  Badge,
  Container,
  Group,
  Loader,
  Pagination,
  Paper,
  SegmentedControl,
  Select,
  Stack,
  Table,
  Text,
  Title,
  Tooltip,
} from '@mantine/core'
import { DatePickerInput, type DatesRangeValue } from '@mantine/dates'
import dayjs from 'dayjs'
import 'dayjs/locale/id'
import { useMemo, useState } from 'react'
import { createFileRoute } from '@tanstack/react-router'
import { TbHistory, TbRefresh } from 'react-icons/tb'
import { DashboardLayout } from '@/frontend/components/DashboardLayout'
import useSWR from 'swr'
import { API_URLS } from '../config/api'

export const Route = createFileRoute('/logs')({
  component: GlobalLogsPage,
})

const fetcher = (url: string) => fetch(url, { credentials: 'include' }).then((r) => r.json())

const LOG_TYPES = ['all', 'LOGIN', 'LOGOUT', 'CREATE', 'UPDATE', 'DELETE'] as const
const LOG_TYPE_LABEL: Record<string, string> = {
  all: 'All',
  LOGIN: 'Login',
  LOGOUT: 'Logout',
  CREATE: 'Create',
  UPDATE: 'Update',
  DELETE: 'Delete',
}
const LOG_TYPE_COLOR: Record<string, string> = {
  LOGIN: 'teal',
  LOGOUT: 'gray',
  CREATE: 'blue',
  UPDATE: 'yellow',
  DELETE: 'red',
}

function GlobalLogsPage() {
  const [type, setType] = useState('all')
  const [operatorId, setOperatorId] = useState('all')
  const [dateRange, setDateRange] = useState<DatesRangeValue>([null, null])
  const [page, setPage] = useState(1)

  const { data: operatorsData } = useSWR(API_URLS.getLogOperators(), fetcher)

  const operatorOptions = useMemo(() => {
    if (!operatorsData || !Array.isArray(operatorsData)) return [{ value: 'all', label: 'All users' }]
    return [
      { value: 'all', label: 'All users' },
      ...operatorsData.map((op: any) => ({ value: op.id, label: op.name })),
    ]
  }, [operatorsData])

  const dateFrom = dateRange[0] ? dayjs(dateRange[0]).format('YYYY-MM-DD') : undefined
  const dateTo = dateRange[1] ? dayjs(dateRange[1]).format('YYYY-MM-DD') : undefined

  const { data, isLoading, mutate } = useSWR(
    API_URLS.getGlobalLogs(page, '', type, operatorId, dateFrom, dateTo),
    fetcher,
    { refreshInterval: 10_000 },
  )

  const logs: any[] = data?.data ?? []
  const totalPages: number = data?.totalPages ?? 1

  return (
    <DashboardLayout>
      <Container size="xl" py="lg">
        <Stack gap="xl">
          <Group justify="space-between" align="flex-start">
            <Stack gap={4}>
              <Title order={2} className="gradient-text">Activity Logs</Title>
              <Text size="sm" c="dimmed">
                Track all user actions and system events across the platform.
              </Text>
            </Stack>
            <Tooltip label="Refresh logs" withArrow>
              <ActionIcon
                variant="light"
                color="brand-blue"
                size="lg"
                onClick={() => mutate()}
                loading={isLoading}
              >
                <TbRefresh size={16} />
              </ActionIcon>
            </Tooltip>
          </Group>

          <Paper withBorder radius="xl" p="md" className="glass">
            <Group gap="sm" wrap="wrap" align="flex-end">
              <Select
                label="User"
                placeholder="All users"
                value={operatorId}
                onChange={(v) => { setOperatorId(v ?? 'all'); setPage(1) }}
                data={operatorOptions}
                w={200}
                clearable
                size="sm"
              />
              <DatePickerInput
                type="range"
                label="Date range"
                placeholder="Pick a date range"
                value={dateRange}
                onChange={(v) => { setDateRange(v); setPage(1) }}
                locale="id"
                valueFormat="DD MMM YYYY"
                clearable
                w={280}
                size="sm"
              />
              <Stack gap={4}>
                <Text size="xs" fw={500} c="dimmed">Action type</Text>
                <SegmentedControl
                  value={type}
                  onChange={(v) => { setType(v); setPage(1) }}
                  size="sm"
                  data={LOG_TYPES.map((t) => ({ label: LOG_TYPE_LABEL[t] ?? t, value: t }))}
                />
              </Stack>
            </Group>
          </Paper>

          {isLoading && !data ? (
            <Group justify="center" py="xl">
              <Loader type="dots" />
            </Group>
          ) : (
            <Paper withBorder radius="2xl" className="glass" p="md">
              <Table.ScrollContainer minWidth={600}>
                <Table
                  className="data-table"
                  highlightOnHover
                  verticalSpacing="sm"
                  fz="sm"
                  style={{ tableLayout: 'fixed', width: '100%' }}
                >
                  <colgroup>
                    <col style={{ width: 155 }} />
                    <col style={{ width: 210 }} />
                    <col style={{ width: 105 }} />
                    <col />
                  </colgroup>
                  <Table.Thead>
                    <Table.Tr>
                      <Table.Th>Timestamp</Table.Th>
                      <Table.Th>User</Table.Th>
                      <Table.Th>Action</Table.Th>
                      <Table.Th>Description</Table.Th>
                    </Table.Tr>
                  </Table.Thead>
                  <Table.Tbody>
                    {logs.map((log: any) => (
                      <Table.Tr key={log.id}>
                        <Table.Td style={{ whiteSpace: 'nowrap' }}>
                          <Stack gap={0}>
                            <Text size="xs" fw={500}>
                              {dayjs(log.createdAt).locale('id').format('D MMM YYYY')}
                            </Text>
                            <Text size="xs" c="dimmed">
                              {dayjs(log.createdAt).format('HH:mm:ss')}
                            </Text>
                          </Stack>
                        </Table.Td>
                        <Table.Td>
                          {log.user ? (
                            <Stack gap={0}>
                              <Text size="sm" fw={600} truncate>{log.user.name}</Text>
                              <Text size="xs" c="dimmed" truncate>{log.user.email}</Text>
                            </Stack>
                          ) : (
                            <Text c="dimmed" size="sm">—</Text>
                          )}
                        </Table.Td>
                        <Table.Td>
                          <Badge
                            color={LOG_TYPE_COLOR[log.type] ?? 'gray'}
                            variant="light"
                            size="sm"
                            tt="capitalize"
                          >
                            {LOG_TYPE_LABEL[log.type] ?? log.type}
                          </Badge>
                        </Table.Td>
                        <Table.Td>
                          <Tooltip
                            label={log.message}
                            multiline
                            maw={340}
                            withArrow
                            position="top-start"
                            disabled={(log.message?.length ?? 0) < 60}
                          >
                            <Text size="sm" lineClamp={2} style={{ cursor: 'default' }}>
                              {log.message}
                            </Text>
                          </Tooltip>
                        </Table.Td>
                      </Table.Tr>
                    ))}
                    {logs.length === 0 && (
                      <Table.Tr>
                        <Table.Td colSpan={4}>
                          <Stack align="center" gap="xs" py="xl">
                            <TbHistory size={32} style={{ opacity: 0.25 }} />
                            <Text c="dimmed" size="sm">
                              No activity logs found for the selected filters.
                            </Text>
                          </Stack>
                        </Table.Td>
                      </Table.Tr>
                    )}
                  </Table.Tbody>
                </Table>
              </Table.ScrollContainer>
              {totalPages > 1 && (
                <Group justify="center" mt="md">
                  <Pagination total={totalPages} value={page} onChange={setPage} size="sm" />
                </Group>
              )}
            </Paper>
          )}
        </Stack>
      </Container>
    </DashboardLayout>
  )
}
