import { Stack } from '@tidbcloud/uikit'
import React, { useEffect, useMemo } from 'react'
import { useHistory } from 'react-router-dom'

import config from 'config'
import { HeroComponent, isHeroQueryReady } from 'dbaas/components/Measurement'
import { SharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { ClusterPageShell } from 'dbaas/screens/ClusterV2/components'
import {
  StatementProvider,
  useStatementContext
} from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/utils/context'
import { getStatementContext } from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/utils/context-impl'
import { StatementModel } from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/utils/type'
import { useGetStatementsPlanDetailForCluster, useGetStatementsPlansForCluster } from 'dbaas/services/useDiagnosisQuery'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

import { PlanDetail } from '../../Statement/Detail/PlanDetail'
import { PlansList } from '../../Statement/Detail/plans-list/PlansList'
import { StmtSummary } from '../../Statement/Detail/StmtSummary'
import { useStatementDetailUrlState } from '../../Statement/Detail/url-state'

interface StatementV2DetailContentProps {
  cluster: SharedCluster
  orgId: string
  projectId: string
}

const StatementV2DetailContent = ({ cluster, orgId, projectId }: StatementV2DetailContentProps) => {
  const ctx = useStatementContext()
  const { digest, schema_name, begin_time, end_time, plans, setPlans } = useStatementDetailUrlState()
  const selectedPlans = useMemo(() => plans.slice(0, 1), [plans])
  const selectedPlanDigest = selectedPlans[0]
  const beginTime = Number(begin_time)
  const endTime = Number(end_time)
  const queryEnabled = !!digest && Number.isFinite(beginTime) && Number.isFinite(endTime)
  const statementParams = useMemo(
    () => ({
      digest: digest ?? '',
      schema_name: schema_name || undefined,
      begin_time: beginTime,
      end_time: endTime
    }),
    [beginTime, digest, endTime, schema_name]
  )

  const {
    data: stmtPlans,
    isLoading: fetchingPlans,
    isFetched,
    isError
  } = useGetStatementsPlansForCluster(orgId, projectId, cluster, statementParams, {
    query: {
      enabled: queryEnabled,
      refetchOnWindowFocus: false
    }
  })

  useEffect(() => {
    if (!stmtPlans?.length) {
      return
    }

    const availablePlans = stmtPlans.map((plan) => plan.plan_digest).filter((digest): digest is string => !!digest)
    const currentPlan = selectedPlans[0]
    const selectedPlan = currentPlan && availablePlans.includes(currentPlan) ? currentPlan : availablePlans[0]
    if (selectedPlan && (plans.length !== 1 || plans[0] !== selectedPlan)) {
      setPlans([selectedPlan])
    }
  }, [plans, selectedPlans, setPlans, stmtPlans])

  const { data: planDetailResult, isLoading: fetchingPlanDetail } = useGetStatementsPlanDetailForCluster<
    StatementModel & { selectedPlanDigest: string }
  >(
    orgId,
    projectId,
    cluster,
    { ...statementParams, plans: selectedPlans },
    {
      query: {
        enabled: queryEnabled && selectedPlans.length > 0,
        refetchOnWindowFocus: false,
        select: (detail) => ({ ...detail, selectedPlanDigest: selectedPlanDigest! })
      }
    }
  )
  const stmtPlanDetail =
    planDetailResult && planDetailResult.selectedPlanDigest === selectedPlanDigest ? planDetailResult : undefined
  const planDetailLoading = fetchingPlanDetail || (!!planDetailResult && !stmtPlanDetail)

  useEffect(() => {
    document.title = `${config.PAGE_TITLE_PREFIX}Diagnosis - Statement Insight Detail`
  }, [])

  const stmtSummary = stmtPlans?.[0]

  return (
    <ClusterPageShell
      title="Statement Insight Detail"
      headerProps={{
        withBack: true,
        onBackClick() {
          ctx.event.backFromDetail()
          eventTracking('SQL Statement V2 Detail Back Button Clicked')
        }
      }}
    >
      <Stack data-testid="statement-v2-detail-page">
        <HeroComponent ready={isHeroQueryReady({ isFetched, isError })} />
        <StmtSummary stmt={stmtSummary} plansCount={stmtPlans?.length ?? 0} loading={fetchingPlans} />

        {!!stmtPlans?.length && <PlansList data={stmtPlans} />}

        {selectedPlans.length > 0 && (
          <PlanDetail key={selectedPlanDigest} planDetail={stmtPlanDetail} loading={planDetailLoading} />
        )}
      </Stack>
    </ClusterPageShell>
  )
}

const StatementV2DetailPage = ({ cluster }: { cluster: SharedCluster }) => {
  const {
    store: {
      tenantData: { id: orgId },
      activeProjectId
    }
  } = useStores()
  const history = useHistory()

  return (
    <StatementProvider
      value={getStatementContext(
        {
          orgId,
          projectId: activeProjectId,
          clusterId: cluster.id,
          clusterProvider: cluster.provider,
          clusterRegion: cluster.region,
          computed: cluster.computed
        },
        history
      )}
    >
      <StatementV2DetailContent cluster={cluster} orgId={orgId} projectId={activeProjectId} />
    </StatementProvider>
  )
}

export default React.memo(
  StatementV2DetailPage,
  (prevProps, nextProps) => prevProps.cluster.id === nextProps.cluster.id
)
