import {
  Badge,
  Container,
  Group,
  Stack,
  Text,
  Paper,
  TextInput,
  Select,
  Avatar,
  Box,
  Divider,
  Pagination,
  Center,
  Tooltip,
} from '@mantine/core'
import { useState, useMemo, useEffect } from 'react'
import { createFileRoute } from '@tanstack/react-router'
import { TbSearch, TbClock, TbCheck, TbX } 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).then((res) => res.json())

const typeConfig: Record<string, { color: string; icon?: any }> = {
  CREATE: { color: 'blue', icon: TbCheck },
  UPDATE: { color: 'teal', icon: TbCheck },
  DELETE: { color: 'red', icon: TbX },
  LOGIN: { color: 'green', icon: TbClock },
  LOGOUT: { color: 'orange', icon: TbClock },
}

const getRoleColor = (role: string) => {
  const r = (role || '').toLowerCase()
  if (r.includes('super')) return 'red'
  if (r.includes('admin')) return 'brand-blue'
  if (r.includes('developer')) return 'violet'
  return 'gray'
}

function groupLogsByDate(logs: any[]) {
  const groups: Record<string, any[]> = {}
  
  const today = new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' }).toUpperCase()
  const yesterday = new Date(Date.now() - 86400000).toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' }).toUpperCase()

  logs.forEach(log => {
    const dateObj = new Date(log.createdAt)
    let dateStr = dateObj.toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' }).toUpperCase()
    
    if (dateStr === today) dateStr = 'TODAY'
    else if (dateStr === yesterday) dateStr = 'YESTERDAY'

    if (!groups[dateStr]) groups[dateStr] = []
    
    const timeStr = dateObj.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' })
    
    groups[dateStr].push({
      id: log.id,
      time: timeStr,
      user: log.user,
      type: log.type,
      content: log.message,
      color: log.user ? getRoleColor(log.user.role) : 'gray',
      icon: typeConfig[log.type as string]?.icon
    })
  })

  // We want to keep the order as they came from the API (sorted by createdAt desc)
  // but grouped by date. Object.entries might mess up the order if dates are not sequential.
  // However, since the source logs are sorted, the first encounter of a date defines the group order.
  const result: { date: string; logs: any[] }[] = []
  const seenDates = new Set<string>()
  
  logs.forEach(log => {
    const dateObj = new Date(log.createdAt)
    let dateStr = dateObj.toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric' }).toUpperCase()
    if (dateStr === today) dateStr = 'TODAY'
    else if (dateStr === yesterday) dateStr = 'YESTERDAY'
    
    if (!seenDates.has(dateStr)) {
      result.push({ date: dateStr, logs: groups[dateStr] })
      seenDates.add(dateStr)
    }
  })

  return result
}

function GlobalLogsPage() {
  const [search, setSearch] = useState('')
  const [debouncedSearch, setDebouncedSearch] = useState('')
  const [logType, setLogType] = useState<string | null>('all')
  const [operatorId, setOperatorId] = useState<string | null>('all')
  const [page, setPage] = useState(1)

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedSearch(search), 300)
    return () => clearTimeout(timer)
  }, [search])

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

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

  const { data: response, isLoading } = useSWR(
    API_URLS.getGlobalLogs(page, debouncedSearch, logType || 'all', operatorId || 'all'),
    fetcher
  )

  const filteredTimeline = useMemo(() => {
    if (!response?.data) return []
    return groupLogsByDate(response.data)
  }, [response?.data])

  return (
    <DashboardLayout>
      <Container size="xl" py="lg">
        
        {/* Header Controls */}
        <Group mb="xl" gap="md">
          <TextInput
            placeholder="Search operator or message..."
            leftSection={<TbSearch size={16} />}
            radius="md"
            w={250}
            value={search}
            onChange={(e) => {
              setSearch(e.currentTarget.value)
              setPage(1)
            }}
          />
          <Select
            placeholder="Log Type"
            data={[
              { value: 'all', label: 'All Types' },
              { value: 'CREATE', label: 'Create' },
              { value: 'UPDATE', label: 'Update' },
              { value: 'DELETE', label: 'Delete' },
              { value: 'LOGIN', label: 'Login' },
              { value: 'LOGOUT', label: 'Logout' },
            ]}
            radius="md"
            w={160}
            value={logType}
            onChange={(val) => {
              setLogType(val)
              setPage(1)
            }}
          />
          <Select
            placeholder="Operator"
            data={operatorOptions}
            searchable
            radius="md"
            w={200}
            value={operatorId}
            onChange={(val) => {
              setOperatorId(val)
              setPage(1)
            }}
          />
        </Group>

        {/* Timeline Content */}
        <Paper withBorder p="md" radius="2xl" className="glass" style={{ background: 'var(--mantine-color-body)', minHeight: 400 }}>
          {isLoading ? (
             <Center py="xl">
               <Text c="dimmed">Loading logs...</Text>
             </Center>
          ) : filteredTimeline.length === 0 ? (
             <Text c="dimmed" ta="center" py="xl">No logs found matching your filters.</Text>
          ) : (
            <>
              {filteredTimeline.map((group, groupIndex) => (
                <Box key={group.date}>
                  <Text 
                    size="xs" 
                    fw={700} 
                    c="dimmed" 
                    mt={groupIndex > 0 ? "xl" : 0} 
                    mb="md" 
                    style={{ textTransform: 'uppercase' }}
                  >
                    {group.date}
                  </Text>
                  
                  <Stack gap={0} pl={4}>
                    {group.logs.map((log, logIndex) => {
                      const isLastLog = logIndex === group.logs.length - 1;
                      
                      return (
                        <Group 
                          key={log.id} 
                          wrap="nowrap" 
                          align="flex-start" 
                          gap="lg" 
                          style={{ position: 'relative', paddingBottom: isLastLog ? 0 : 32 }}
                        >
                          {/* Left: Time */}
                          <Text 
                            size="xs" 
                            c="dimmed" 
                            w={70} 
                            style={{ flexShrink: 0, marginTop: 4, textAlign: 'left' }}
                          >
                            {log.time}
                          </Text>
    
                          {/* Middle: Line & Avatar */}
                          <Box style={{ position: 'relative', width: 20, flexShrink: 0, alignSelf: 'stretch' }}>
                            {/* Vertical Line */}
                            {!isLastLog && (
                              <Box 
                                style={{ 
                                  position: 'absolute', 
                                  top: 24, 
                                  bottom: -8, 
                                  left: '50%', 
                                  transform: 'translateX(-50%)',
                                  width: 1, 
                                  backgroundColor: 'rgba(128,128,128,0.2)' 
                                }} 
                              />
                            )}
                            {/* Avatar */}
                            <Box style={{ position: 'relative', zIndex: 2 }}>
                               <Tooltip label={`${log.user?.name || 'Unknown'} (${log.user?.role || 'User'})`} withArrow radius="md">
                                 <Avatar 
                                   size={24} 
                                   radius="xl" 
                                   color={log.color} 
                                   variant="light"
                                   src={log.user?.image}
                                   style={{ cursor: 'help' }}
                                 >
                                   {log.icon ? <log.icon size={14} /> : (log.user?.name?.charAt(0) || '?')}
                                 </Avatar>
                               </Tooltip>
                            </Box>
                          </Box>
    
                          {/* Right: Content */}
                          <Box style={{ flexGrow: 1, marginTop: 2 }}>
                            <Text size="sm">
                              <Text component="span" fw={600} mr={4}>{log.user?.name || 'Unknown'}</Text>
                              {log.content}
                            </Text>
                          </Box>
                        </Group>
                      )
                    })}
                  </Stack>
                  
                  {groupIndex < filteredTimeline.length - 1 && (
                    <Divider my="xl" color="rgba(128,128,128,0.1)" />
                  )}
                </Box>
              ))}

              {response?.totalPages > 1 && (
                <Center mt="xl">
                  <Pagination 
                    total={response.totalPages} 
                    value={page} 
                    onChange={setPage} 
                    radius="md" 
                  />
                </Center>
              )}
            </>
          )}
        </Paper>
      </Container>
    </DashboardLayout>
  )
}
