import { useState, useEffect, useCallback, useRef } from 'react';
import {
  Container,
  Title,
  Text,
  Table,
  Badge,
  Group,
  Alert,
  Loader,
  Center,
  Stack,
  TextInput,
  Modal,
  Code,
  Tooltip
} from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { IconAlertCircle, IconFileText, IconSearch } from '@tabler/icons-react';
import { apiClient } from '../lib/api';
import type { EventLog } from '../types';

const ITEMS_PER_PAGE = 20;

export default function EventLogsPage() {
  const [logs, setLogs] = useState<EventLog[]>([]);
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const [hasMore, setHasMore] = useState(false);
  const [offset, setOffset] = useState(0);
  const [error, setError] = useState<string | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const [totalCount, setTotalCount] = useState<number | null>(null);
  const [modalTitle, setModalTitle] = useState('Event Details');
  const [modalContent, setModalContent] = useState('');
  const [dataModalOpened, { open: openDataModal, close: closeDataModal }] = useDisclosure(false);
  const sentinelRef = useRef<HTMLDivElement | null>(null);

  // Debounce search input by 400ms
  useEffect(() => {
    const timer = setTimeout(() => setDebouncedSearch(searchQuery), 400);
    return () => clearTimeout(timer);
  }, [searchQuery]);

  const loadLogsPage = useCallback(async (targetOffset: number, reset: boolean) => {
    try {
      if (reset) {
        setLoading(true);
      } else {
        setLoadingMore(true);
      }

      const result = await apiClient.getEventLogs({
        sort: '-created_at',
        limit: ITEMS_PER_PAGE,
        offset: targetOffset,
        search: debouncedSearch || undefined,
      });

      const pageData = result.data || [];
      const hasKnownTotal = typeof result.meta?.total === 'number';
      const total = hasKnownTotal ? (result.meta?.total as number) : null;
      const nextOffset = targetOffset + pageData.length;

      if (reset) {
        setLogs(pageData);
      } else {
        setLogs((previousLogs) => [...previousLogs, ...pageData]);
      }

      setOffset(nextOffset);
      if (total !== null) {
        setTotalCount(total);
        setHasMore(nextOffset < total);
      } else {
        setTotalCount(nextOffset);
        setHasMore(pageData.length === ITEMS_PER_PAGE);
      }
      setError(null);
    } catch (err) {
      setError('Failed to load event logs');
      console.error(err);
    } finally {
      if (reset) {
        setLoading(false);
      } else {
        setLoadingMore(false);
      }
    }
  }, [debouncedSearch]);

  useEffect(() => {
    setLogs([]);
    setOffset(0);
    setHasMore(false);
    setTotalCount(null);
    loadLogsPage(0, true);
  }, [debouncedSearch, loadLogsPage]);

  useEffect(() => {
    if (!sentinelRef.current || loading || loadingMore || !hasMore || error) {
      return;
    }

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0]?.isIntersecting) {
          loadLogsPage(offset, false);
        }
      },
      { rootMargin: '250px' },
    );

    observer.observe(sentinelRef.current);
    return () => observer.disconnect();
  }, [loading, loadingMore, hasMore, error, offset, loadLogsPage]);

  const openDetailsModal = (title: string, content?: string) => {
    setModalTitle(title);
    setModalContent(getFormattedData(content));
    openDataModal();
  };

  const getFormattedData = (data?: string) => {
    if (!data) {
      return '';
    }
    try {
      return JSON.stringify(JSON.parse(data), null, 2);
    } catch {
      return data;
    }
  };

  if (loading) {
    return (
      <Container size="xl" py="xl">
        <Center h={400}>
          <Loader size="lg" />
        </Center>
      </Container>
    );
  }

  if (error) {
    return (
      <Container size="xl" py="xl">
        <Alert icon={<IconAlertCircle size={16} />} title="Error" color="red" mb="md">
          {error}
        </Alert>
        <Text size="sm" c="dimmed">Try adjusting filters or refreshing the page.</Text>
      </Container>
    );
  }

  return (
    <Container size="xl" py="xl">
      <Group justify="space-between" mb="xl">
        <div>
          <Title order={2}>Event Logs</Title>
          <Text c="dimmed" size="sm">System activity and audit trail</Text>
        </div>
      </Group>

      <Group mb="md">
        <TextInput
          placeholder="Search by event type..."
          leftSection={<IconSearch size={16} />}
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          style={{ flex: 1 }}
        />
      </Group>

      <Table highlightOnHover withTableBorder withColumnBorders>
        <Table.Thead>
          <Table.Tr>
            <Table.Th>Timestamp</Table.Th>
            <Table.Th>Event Type</Table.Th>
            <Table.Th>Action</Table.Th>
            <Table.Th>Entity</Table.Th>
            <Table.Th>User</Table.Th>
            <Table.Th>Status</Table.Th>
            <Table.Th>Details</Table.Th>
          </Table.Tr>
        </Table.Thead>
        <Table.Tbody>
          {logs.length === 0 ? (
            <Table.Tr>
              <Table.Td colSpan={7}>
                <Center h={200}>
                  <Stack align="center">
                    <IconFileText size={48} stroke={1.5} color="gray" />
                    <Text c="dimmed">
                      {debouncedSearch ? 'No matching logs found' : 'No event logs available'}
                    </Text>
                  </Stack>
                </Center>
              </Table.Td>
            </Table.Tr>
          ) : (
            logs.map((log) => {
              let entityDisplay = log.entity_type || '-';
              if (log.entity_id) {
                entityDisplay += ` (${log.entity_id.substring(0, 8)}...)`;
              }

              return (
                <Table.Tr key={log.id}>
                  <Table.Td>
                    <Text size="sm">{new Date(log.created_at).toLocaleString()}</Text>
                  </Table.Td>
                  <Table.Td>
                    <Badge variant="light">{log.event_type}</Badge>
                  </Table.Td>
                  <Table.Td>
                    <Text size="sm">{log.action || '-'}</Text>
                  </Table.Td>
                  <Table.Td>
                    <Text size="sm">{entityDisplay}</Text>
                  </Table.Td>
                  <Table.Td>
                    <Text size="sm">{log.user_id ? `User ${log.user_id.substring(0, 8)}...` : '-'}</Text>
                  </Table.Td>
                  <Table.Td>
                    <Badge color={log.success ? 'green' : 'red'} variant="light">
                      {log.success ? 'Success' : 'Failed'}
                    </Badge>
                  </Table.Td>
                  <Table.Td>
                    {log.error ? (
                      <Tooltip label="Click to view error details" position="left">
                        <Code
                          component="button"
                          color="red"
                          onClick={() => openDetailsModal(`Event Error: ${log.event_type}`, log.error)}
                          style={{ cursor: 'pointer', border: 'none' }}
                        >
                          Error
                        </Code>
                      </Tooltip>
                    ) : log.data ? (
                      <Code
                        component="button"
                        onClick={() => openDetailsModal(`Event Data: ${log.event_type}`, log.data)}
                        style={{ cursor: 'pointer', border: 'none' }}
                      >
                        View Data
                      </Code>
                    ) : (
                      <Text size="sm" c="dimmed">-</Text>
                    )}
                  </Table.Td>
                </Table.Tr>
              );
            })
          )}
        </Table.Tbody>
      </Table>

      <div ref={sentinelRef} />

      {loadingMore && (
        <Center mt="lg">
          <Loader size="sm" />
        </Center>
      )}

      <Group justify="space-between" mt="md">
        <Text size="sm" c="dimmed">
          {totalCount !== null
            ? `Showing ${logs.length} of ${totalCount} logs`
            : `Showing ${logs.length} logs`}
        </Text>
        {debouncedSearch && (
          <Text size="sm" c="dimmed">Filtered by: "{debouncedSearch}"</Text>
        )}
      </Group>

      <Modal
        opened={dataModalOpened}
        onClose={closeDataModal}
        title={modalTitle}
        fullScreen
      >
        <Code
          component="pre"
          block
          style={{
            whiteSpace: 'pre-wrap',
            wordBreak: 'break-word',
            minHeight: '90vh',
            overflow: 'auto',
          }}
        >
          {modalContent}
        </Code>
      </Modal>
    </Container>
  );
}
