import React from 'react'

import {
  Badge,
  DefaultMantineColor,
  Flex,
  Group,
  Loader,
  Space,
  Text
} from '@mantine/core'
import { Tooltip, Typography } from 'antd'
import ReactJson from 'react-json-view'
import { useParams } from 'react-router-dom'

import { ActivitiesActivityGroup } from '@clinic/client'
import { ReportType } from '~/pages/reports/shared/types'
import { recentEventTelemetry } from '~/telemetry/event-center'
import { formatDateTimeWithTz } from '~/utils/date-time'

import { useGetGroup } from '../shared/api'
import { CollapseCard } from '../shared/components/CollapseCard'
import { EventCharts } from '../shared/components/EventCharts'
import { EventTimeline } from '../shared/components/EventTimeline'
import { hasOOMInsight } from '../shared/utils'

interface EventGroupCardProps {
  eventGroup: ActivitiesActivityGroup
  defaultExpanded?: boolean
}

export enum Status {
  Processing = 'PROCESSING',
  Finished = 'FINISHED'
}

const STATUS_MAP: {
  [status: string]: { label: string; color: DefaultMantineColor }
} = {
  [Status.Processing]: {
    label: 'Processing',
    color: 'blue'
  },
  [Status.Finished]: {
    label: 'Finished',
    color: 'gray'
  }
}

export const EventGroupCard: React.FC<EventGroupCardProps> = ({
  eventGroup,
  defaultExpanded
}) => {
  const { orgId, cid } = useParams()
  // TODO: temp solution for the groups definition of backend
  // show the event with severity >= 0 as the group summary
  const severityGT0Events = eventGroup.activities?.filter(
    (ac) => ac.severity! >= 0
  )
  const awarenessEvents = !!severityGT0Events?.length
    ? severityGT0Events
    : eventGroup.activities
  const eventsInRules = !!eventGroup.rule?.length
    ? awarenessEvents?.filter((ac) => eventGroup.rule?.includes(ac.name!))
    : awarenessEvents
  const lastEvent = eventsInRules?.[eventsInRules?.length - 1]
  const desc = (lastEvent?.payload as any)?.summary || lastEvent?.name
  const statusVal =
    // ignore the status for the single event
    !eventGroup.rule || eventGroup.rule.length === 1
      ? null
      : STATUS_MAP[eventGroup.status!]
  const tsTime = formatDateTimeWithTz(lastEvent?.calibration_time!)
  const showOOMInsight = hasOOMInsight(eventGroup)

  return (
    <CollapseCard
      defaultExpanded={!showOOMInsight && defaultExpanded}
      expandElement={
        !showOOMInsight && <EventGroupDetail gid={eventGroup.context_id!} />
      }
      onClickCollapse={(v) =>
        recentEventTelemetry.clickCollapse(v, eventGroup?.context_id!)
      }
      link={
        showOOMInsight
          ? {
              label: 'Open OOM Insight',
              path: `/orgs/${orgId}/clusters/${cid}/report/${ReportType.OOM}/${eventGroup.context_id}`,
              onClick: () =>
                recentEventTelemetry.clickOOMInsight(eventGroup.context_id!)
            }
          : undefined
      }
    >
      <Flex align='center'>
        <Tooltip title={eventGroup.name}>
          <Text className='truncate w-[100px] shrink-0'>{eventGroup.name}</Text>
        </Tooltip>

        <Space w='xl' />

        {!!statusVal && (
          <>
            <div className='w-[120px] shrink-0'>
              <Badge variant='outline' color={statusVal.color}>
                {eventGroup?.status === Status.Processing && (
                  <span className='inline-block align-sub mt-1 mr-1'>
                    <Loader size={12} />
                  </span>
                )}
                {statusVal.label}
              </Badge>
            </div>
            <Space w='xl' />
          </>
        )}

        <Typography.Paragraph
          className='grow-0'
          style={{ margin: 0 }}
          strong
          ellipsis
        >
          [{tsTime}] {desc}
        </Typography.Paragraph>
      </Flex>
    </CollapseCard>
  )
}

interface EventGroupDetailProps {
  gid: string
}

const EventGroupDetail: React.FC<EventGroupDetailProps> = ({ gid }) => {
  const { data, error } = useGetGroup({ groupId: gid })
  const loading = !data && !error
  const rules = data?.data.rule
  const singleRuleEvent = data?.data.activities?.find(
    (a) => a.name === rules?.[0]
  )
  const isSingleRule = rules?.length === 1 && singleRuleEvent
  const isSingleEvent = !rules?.length && data?.data.activities?.length === 1
  const isSingle = isSingleRule || isSingleEvent
  const singleEvent =
    isSingle && (isSingleRule ? singleRuleEvent : data?.data.activities?.[0])

  return (
    <>
      {loading ? (
        <Group position='center' className='my-4'>
          <Loader variant='bars' size='xs' />
        </Group>
      ) : (
        <>
          <Space h='xl' />
          <Space h='xl' />

          {singleEvent && (
            <>
              <Text>
                <span className='font-bold'>Source: </span>
                {singleEvent.source}
              </Text>
              <Text>
                <span className='font-bold'>Payload: </span>
              </Text>
              <ReactJson
                src={singleEvent.payload!}
                collapsed={1}
                displayDataTypes={false}
              />
              <Space h='xl' />
            </>
          )}
          {!!data?.data.activities?.length && (
            <>
              <EventTimeline eventGroup={data?.data!} />
              <EventCharts eventGroup={data?.data!} />
            </>
          )}
        </>
      )}
    </>
  )
}
