import React, { useEffect, useMemo } from 'react'

import { Alert, Stack } from '@tidbcloud/uikit'
import { useQuery } from 'react-query'
import { useLocation, useNavigate } from 'react-router-dom'

import { ngmContextFromCluster } from '~/api/ngm'
import { useCurCluster, useCurOrg } from '~/hooks/state'
import { eventTracking } from '~/utils/telemetry'

import { StmtSummary } from '../../SQLRepository/Detail/StmtSummary'
import { useStatementDetailUrlState } from '../../SQLRepository/Detail/url-state'
import { ClusterPageShell } from '../../SQLRepository/migration_shared/components'
import {
  getStatementV2PlanDetail,
  getStatementV2Plans,
  statementV2ContextQueryKey
} from '../api'
import { isStatementV2RUMetricAvailable } from '../statementV2'
import { PlanDetail } from './PlanDetail'
import { PlansList } from './PlansList'

interface DetailLocationState {
  detailFromHref?: string
  historyBack?: boolean
}

const StatementV2DetailContent: React.FC = () => {
  const { curOrg } = useCurOrg()
  const { curCluster } = useCurCluster()
  const navigate = useNavigate()
  const location = useLocation()
  const { digest, schema_name, begin_time, end_time, plans, setPlans } =
    useStatementDetailUrlState()

  const selectedPlanDigest = plans[0]
  const beginTime = Number(begin_time)
  const endTime = Number(end_time)
  const queryEnabled =
    !!digest && Number.isFinite(beginTime) && Number.isFinite(endTime)

  const ngmContext = useMemo(
    () => ngmContextFromCluster(curCluster!, curOrg?.externalID || ''),
    [curCluster, curOrg?.externalID]
  )
  const statementParams = useMemo(
    () => ({
      digest: digest || '',
      schema_name: schema_name || undefined,
      begin_time: beginTime,
      end_time: endTime
    }),
    [beginTime, digest, endTime, schema_name]
  )

  const plansQuery = useQuery(
    [
      'statement-v2',
      'plans',
      ...statementV2ContextQueryKey(ngmContext),
      statementParams
    ],
    () => getStatementV2Plans(ngmContext, statementParams),
    {
      enabled: queryEnabled,
      refetchOnWindowFocus: false
    }
  )

  useEffect(() => {
    if (!plansQuery.data?.length) return

    const availablePlans = plansQuery.data
      .map((plan) => plan.plan_digest)
      .filter((planDigest): planDigest is string => !!planDigest)

    if (!availablePlans.length) {
      return
    }

    const nextPlan =
      selectedPlanDigest && availablePlans.includes(selectedPlanDigest)
        ? selectedPlanDigest
        : availablePlans[0]
    if (plans.length !== 1 || plans[0] !== nextPlan) {
      setPlans([nextPlan])
    }
  }, [plans, plansQuery.data, selectedPlanDigest, setPlans])

  const detailQuery = useQuery(
    [
      'statement-v2',
      'plan-detail',
      ...statementV2ContextQueryKey(ngmContext),
      statementParams,
      selectedPlanDigest
    ],
    () =>
      getStatementV2PlanDetail(ngmContext, {
        ...statementParams,
        plans: selectedPlanDigest ? [selectedPlanDigest] : []
      }),
    {
      enabled: queryEnabled && !!selectedPlanDigest,
      refetchOnWindowFocus: false,
      keepPreviousData: false
    }
  )

  useEffect(() => {
    document.title = 'TiDB Clinic - Statement Insight Detail (PREVIEW)'
  }, [])

  const handleBack = () => {
    const state = location.state as DetailLocationState | null
    if (state?.detailFromHref) {
      navigate(state.detailFromHref, { replace: true })
    } else if (state?.historyBack) {
      navigate(-1)
    } else {
      const search = new URLSearchParams()
      if (begin_time) search.set('from', begin_time)
      if (end_time) search.set('to', end_time)
      navigate(
        `/orgs/${curOrg?.id}/clusters/${
          curCluster?.id
        }/sql-statement-v2?${search.toString()}`,
        { replace: true }
      )
    }
    eventTracking('Statement V2 Detail Back Button Clicked')
  }

  const statementSummary = plansQuery.data?.[0]
  const showRU = isStatementV2RUMetricAvailable(curCluster?.deployTypeV2)

  return (
    <ClusterPageShell
      title='Statement Insight Detail (PREVIEW)'
      titleProps={{ order: 3, fw: 300 }}
      headerProps={{ withBack: true, onBackClick: handleBack }}
    >
      <Stack data-testid='statement-v2-detail-page'>
        {!queryEnabled && (
          <Alert color='red'>
            The statement digest and a valid time range are required.
          </Alert>
        )}
        {plansQuery.isError && (
          <Alert color='red'>Failed to load statement execution plans.</Alert>
        )}
        {plansQuery.isFetched &&
          !plansQuery.isError &&
          !plansQuery.data?.length && (
            <Alert>No execution plans were found in this time range.</Alert>
          )}

        <StmtSummary
          stmt={statementSummary}
          plansCount={plansQuery.data?.length || 0}
          loading={plansQuery.isLoading}
        />

        {!!plansQuery.data?.length && (
          <PlansList
            data={plansQuery.data}
            selectedPlanDigest={selectedPlanDigest}
            showRU={showRU}
            onSelect={(planDigest) => {
              setPlans([planDigest])
              eventTracking('Statement V2 Detail Plan Selected', {
                planDigest
              })
            }}
          />
        )}

        {detailQuery.isError && (
          <Alert color='red'>Failed to load the execution plan detail.</Alert>
        )}
        {!!selectedPlanDigest && !detailQuery.isError && (
          <>
            <PlanDetail
              key={selectedPlanDigest}
              planDetail={detailQuery.data}
              loading={detailQuery.isLoading}
              showRU={showRU}
            />
          </>
        )}
      </Stack>
    </ClusterPageShell>
  )
}

const StatementV2DetailPage: React.FC = () => <StatementV2DetailContent />

export default StatementV2DetailPage
