import RefreshIcon from '@mui/icons-material/Refresh'
import {
  Timeline,
  TimelineConnector,
  TimelineContent,
  TimelineItem,
  TimelineSeparator,
} from '@mui/lab'
import {
  Box,
  CircularProgress,
  IconButton,
  SxProps,
  Typography,
} from '@mui/material'
import moment from 'moment'
import { useEffect, useRef } from 'react'
import { useInfiniteQuery } from 'react-query'
import { NoDataIllustration } from '..'
import axios from '../../config/axios'
import { useErrorModal } from '../ErrorModalWrapper/ErrorModalWrapper'
import Spinner from '../Spinner'
import Table from '../Tables/BasicTable/Table'
import { StyledAvatar, StyledCircleIcon, StyledTimeLineDot } from './Styles'

interface ActivityLogItem {
  timestamp: string
  message: string
  userName: string
  action: string
  typeId: number
  type: string
  tenantId: string
  institutionId: number
  userId: string
  cursor: string
}

interface Props {
  endPoint: string
  tableView: boolean
  enableTitle?: boolean
  params: any
  sx?: SxProps
  reloadKey?: string | number
}

export default function ActivityLog({
  endPoint,
  tableView,
  enableTitle,
  params,
  sx,
  reloadKey,
}: Props) {
  const errorModal = useErrorModal()
  const timestamp = useRef(Date.now())
  const queryKey = [
    'activities',
    endPoint,
    JSON.stringify(params),
    reloadKey ?? timestamp.current,
  ]

  const fetchActivities = async ({ pageParam = null }) => {
    try {
      const queryParams = { ...params }
      if (pageParam) {
        queryParams.cursor = pageParam
      }
      const response = await axios.get(endPoint, { params: queryParams })
      return response?.data || []
    } catch (error) {
      // eslint-disable-next-line no-console
      console.error('Error fetching activities:', error)
      errorModal({ error: error })
      return []
    }
  }

  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isLoading,
    refetch,
  } = useInfiniteQuery(queryKey, fetchActivities, {
    getNextPageParam: (lastPage: ActivityLogItem[]) => {
      return lastPage?.length ? lastPage[lastPage.length - 1].cursor : null
    },
    refetchOnWindowFocus: false,
    cacheTime: 0,
  })

  const activitiesData = data?.pages?.flatMap((page) => page) || []

  if (isLoading) {
    return (
      <Box
        display="flex"
        justifyContent="center"
        alignItems="center"
        minHeight="200px"
      >
        <Spinner />
      </Box>
    )
  }

  if (!activitiesData?.length) {
    return (
      <NoDataIllustration
        imageSrc=""
        message={
          <Typography
            variant="h6"
            style={{ textAlign: 'center', marginTop: '20px' }}
          >
            No activity logs found
          </Typography>
        }
      />
    )
  }

  return (
    <Box>
      {enableTitle && (
        <Box
          sx={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            margin: '20px',
          }}
        >
          <Typography variant="h1" sx={{ fontSize: '18px', fontWeight: 700 }}>
            Activity Logs
          </Typography>
          <IconButton
            size="small"
            onClick={() => refetch()}
            sx={{ '&:hover': { backgroundColor: 'rgba(0, 0, 0, 0.04)' } }}
          >
            <RefreshIcon fontSize="small" />
          </IconButton>
        </Box>
      )}

      {!tableView ? (
        <TimeLineComponent
          activitiesData={activitiesData}
          fetchNextPage={fetchNextPage}
          hasNextPage={hasNextPage}
          isFetchingNextPage={isFetchingNextPage}
          sx={sx}
        />
      ) : (
        <Box sx={{ margin: '0 25px' }}>
          <Table
            columns={tableColumns}
            dataSource={activitiesData}
            loading={isLoading}
          />
        </Box>
      )}
    </Box>
  )
}

// Table columns for table view
const tableColumns = [
  {
    title: 'Date',
    dataIndex: 'timestamp',
    key: 'timestamp',
    render: (timestamp: string) =>
      moment.utc(timestamp)?.local().format('DD MMM YYYY - hh:mm A'),
  },
  {
    title: 'Action',
    dataIndex: 'action',
    key: 'action',
  },
  {
    title: 'User Name',
    dataIndex: 'userName',
    key: 'userName',
  },
  {
    title: 'Message',
    dataIndex: 'message',
    key: 'message',
    render: (message: string) => (
      <Typography sx={{ fontSize: '16px' }} variant="subtitle1">
        {renderMessageWithBold(message)}
      </Typography>
    ),
  },
]

// Helper: Render message with bold text (text within single quotes)
const renderMessageWithBold = (message: string) => {
  return message?.split("'")?.map((text: string, index: number) =>
    index % 2 === 0 ? (
      <span key={index}>{text}</span>
    ) : (
      <Typography key={index} component="span" sx={{ fontWeight: 900 }}>
        {text}
      </Typography>
    ),
  )
}

// Timeline Component with Infinite Scroll
interface TimeLineComponentProps {
  activitiesData: ActivityLogItem[]
  fetchNextPage: () => void
  hasNextPage: boolean | undefined
  isFetchingNextPage: boolean
  sx?: SxProps
}

const TimeLineComponent = ({
  activitiesData,
  fetchNextPage,
  hasNextPage,
  isFetchingNextPage,
  sx,
}: TimeLineComponentProps) => {
  const scrollContainerRef = useRef<HTMLDivElement>(null)
  const loadMoreTriggerRef = useRef<HTMLDivElement>(null)

  // Intersection observer for infinite scroll
  useEffect(() => {
    const trigger = loadMoreTriggerRef.current
    const container = scrollContainerRef.current

    if (!trigger || !container) return

    const observer = new IntersectionObserver(
      (entries) => {
        const [entry] = entries
        if (entry.isIntersecting && hasNextPage && !isFetchingNextPage) {
          fetchNextPage()
        }
      },
      {
        root: container,
        rootMargin: '100px',
        threshold: 0.1,
      },
    )

    observer.observe(trigger)

    return () => {
      observer.disconnect()
    }
  }, [fetchNextPage, hasNextPage, isFetchingNextPage])

  return (
    <Box
      ref={scrollContainerRef}
      sx={{
        overflowY: 'auto',
        maxHeight: '600px',
        '&::-webkit-scrollbar': {
          display: 'none',
        },
      }}
    >
      <Timeline sx={{ padding: 0, margin: 0 }}>
        {activitiesData.map((item, index) => (
          <Box
            key={`${item.cursor}-${index}`}
            ref={
              activitiesData.length - 1 === index ? loadMoreTriggerRef : null
            }
            sx={{ maxWidth: '550px', ...sx }}
          >
            <TimelineItem
              sx={{
                margin: 2,
                padding: 0,
                '&:before': { display: 'none' },
              }}
            >
              <TimelineSeparator>
                <StyledTimeLineDot>
                  <StyledCircleIcon />
                </StyledTimeLineDot>
                {index < activitiesData.length - 1 && (
                  <Box
                    sx={{
                      width: '1px',
                      height: '115%',
                      bgcolor: '#12121233',
                      position: 'absolute',
                      top: '25px',
                    }}
                  />
                )}
              </TimelineSeparator>
              <TimelineContent sx={{ padding: '6px 8px' }}>
                <Box>
                  <Typography variant="subtitle2" sx={{ fontSize: '14px' }}>
                    {moment
                      .utc(item.timestamp)
                      .local()
                      .format('DD MMM YYYY - hh:mm A')}
                  </Typography>
                  <Typography sx={{ fontSize: '16px' }} variant="subtitle1">
                    {item.message?.split('\n')?.map((line: string, lineIdx: number) => (
                      <Box key={lineIdx} component="div">
                        {renderMessageWithBold(line)}
                      </Box>
                    ))}
                  </Typography>
                  <Typography
                    style={{
                      display: 'flex',
                      alignItems: 'center',
                      marginTop: '8px',
                    }}
                  >
                    <StyledAvatar>
                      {item.userName?.charAt(0)?.toUpperCase()}
                    </StyledAvatar>
                    <Typography sx={{ fontSize: '13px', fontWeight: 900 }}>
                      {item.userName}
                    </Typography>
                  </Typography>
                </Box>
              </TimelineContent>
            </TimelineItem>
          </Box>
        ))}
      </Timeline>

      {/* Loading indicator */}
      {isFetchingNextPage && (
        <Box
          sx={{
            display: 'flex',
            justifyContent: 'center',
            padding: 2,
          }}
        >
          <CircularProgress size={20} />
        </Box>
      )}
    </Box>
  )
}
