import type { ScatterPlotDataRenderer } from '@/analyst/Plots/types'
import SVGContext from '@/analyst/SVGContext'
import useActionLogs from '@/analyst/dataHooks/useActionLogs'
import useToolsWithEmailsSent from '@/analyst/dataHooks/useToolsWithEmailsSent'
import useToolsWithEmailsSentColor from '@/analyst/dataHooks/useToolsWithEmailsSentColor'
import { textFromRenderedContent } from '@/utils'
import type { ActionLog } from '@inject/graphql/fragments/ActionLog.generated'
import type { EmailDetails } from '@inject/graphql/fragments/EmailDetails.generated'
import type { ToolDetails } from '@inject/graphql/fragments/ToolDetails.generated'
import { useCallback, useContext } from 'react'
import ResponsivePlot from '../../Plots/ResponsivePlot'
import {
  NOTHING_SELECTED_OPACITY,
  NOT_SELECTED_OPACITY,
  SELECTED_OPACITY,
  getInjectEmailArgument,
  getInjectEmailResponse,
  injectEmailTool,
} from '../../utilities'
import SelectedContext from '../SelectedContext'
import CommandActionLog from './CommandActionLog'

const Plot = () => {
  const { dependencies } = useContext(SVGContext)
  const tools = useToolsWithEmailsSent()
  const toolsWithEmailsSentColor = useToolsWithEmailsSentColor()
  const actionLogs = useActionLogs()
  const { selectedReducer } = useContext(SelectedContext)
  const [selectedState, selectedDispatch] = selectedReducer

  const getOpacity = useCallback(
    (toolName: string) => {
      if (!selectedState.tool) return NOTHING_SELECTED_OPACITY
      if (selectedState.tool.name === toolName) return SELECTED_OPACITY
      return NOT_SELECTED_OPACITY
    },
    [selectedState.tool]
  )

  const actionLogsFilter = useCallback(
    (actionLog: ActionLog) => {
      if (actionLog.type !== 'TOOL' && actionLog.type !== 'EMAIL') {
        return false
      }
      if (selectedState.team && actionLog.team.id !== selectedState.team.id) {
        return false
      }
      if (
        actionLog.type === 'EMAIL' &&
        actionLog.team.id !==
          (actionLog.details as EmailDetails).sender.team?.id
      ) {
        return false
      }

      return true
    },
    [selectedState.team]
  )

  const dataRenderer: ScatterPlotDataRenderer = useCallback(
    ({ xScale, yScale, dotSize }) =>
      actionLogs.filter(actionLogsFilter).map(actionLog => {
        const tool =
          actionLog.type === 'TOOL'
            ? (actionLog.details as ToolDetails).tool
            : injectEmailTool
        const argument =
          actionLog.type === 'TOOL'
            ? (actionLog.details as ToolDetails).argument
            : getInjectEmailArgument(actionLog.details as EmailDetails)
        const response =
          actionLog.type === 'TOOL'
            ? textFromRenderedContent(
                (actionLog.details as ToolDetails).content.rendered
              )
            : getInjectEmailResponse()

        return (
          <CommandActionLog
            key={actionLog.id}
            teamName={selectedState.team ? undefined : actionLog.team.name}
            timestamp={actionLog.timestamp}
            toolName={tool.name}
            color={toolsWithEmailsSentColor(tool.name)}
            argument={argument}
            response={response}
            opacity={getOpacity(tool.name)}
            onClick={() => {
              if (selectedState.tool && selectedState.tool.id === tool.id) {
                selectedDispatch({ type: 'selectTool', tool: undefined })
                return
              }
              selectedDispatch({
                type: 'selectTool',
                tool,
              })
            }}
            xScale={xScale}
            yScale={yScale}
            dotSize={dotSize}
          />
        )
      }),
    [
      actionLogs,
      actionLogsFilter,
      getOpacity,
      selectedDispatch,
      selectedState.team,
      selectedState.tool,
      toolsWithEmailsSentColor,
    ]
  )

  return (
    <ResponsivePlot
      type='scatter'
      id='ToolUsagePlot'
      details={{
        dataRenderer,
      }}
      groupNames={tools.map(tool => tool.name)}
      selectedGroupName={selectedState.tool?.name}
      dependencies={[tools.length, dependencies]}
    />
  )
}

export default Plot
