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

import config from 'config'
import { HeroComponent, isHeroQueryReady } from 'dbaas/components/Measurement'
import { PlanDetail } from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/Detail/PlanDetail'
import { PlansList } from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/Detail/plans-list/PlansList'
import { StmtSummary } from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/Detail/StmtSummary'
import { useStatementDetailUrlState } from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/Detail/url-state'
import {
  StatementProvider,
  useStatementContext
} from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/utils/context'
import { StatementModel } from 'dbaas/screens/ClusterV2/features/Diagnosis/Statement/utils/type'
import { useSharedTiDBContext } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/tidb-context'
import { TiDBPageShell } from 'dbaas/screens/NextGen/tidb-mgmt-container/shared/TiDBPageShell'
import { useGetStatementsPlanDetail, useGetStatementsPlans } from 'dbaas/services/useDiagnosisQuery'
import { getNextGenBizType, useGetO11YHost } from 'dbaas/services/useO11YQuery'
import useStores from 'dbaas/stores/useStores'
import { isCookieAuthEnabled } from 'dbaas/utils/o11y-auth'
import { eventTracking } from 'dbaas/utils/tracking'

import { getStatementContext } from '../../sql-statement/premium-context-impl'

const StatementV2DetailContent = ({ orgId }: { orgId: string }) => {
  const ctx = useStatementContext()
  const tidb = useSharedTiDBContext()
  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
  } = useGetStatementsPlans(orgId, tidb, 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 } = useGetStatementsPlanDetail<
    StatementModel & { selectedPlanDigest: string }
  >(
    orgId,
    tidb,
    { ...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}Statement Insight Detail`
  }, [])

  const stmtSummary = stmtPlans?.[0]

  return (
    <TiDBPageShell
      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>
    </TiDBPageShell>
  )
}

const StatementV2DetailPage = () => {
  const {
    store: {
      tenantData: { id: orgId }
    }
  } = useStores()
  const cookieEnabled = isCookieAuthEnabled()
  const history = useHistory()
  const tidb = useSharedTiDBContext()
  const { data, isLoading } = useGetO11YHost(orgId, tidb)
  const o11yHost = data?.data?.slowQuery?.openReadUri
  const contextOptions = cookieEnabled
    ? {
        cookieEnabled: true,
        headerInput: {
          regionId: tidb.regionId,
          bizType: getNextGenBizType(tidb),
          orgId,
          clusterId: tidb.tidbId!
        }
      }
    : undefined

  return (
    <StatementProvider value={getStatementContext(tidb, history, o11yHost!, contextOptions)}>
      {!isLoading && <StatementV2DetailContent orgId={orgId} />}
    </StatementProvider>
  )
}

export default StatementV2DetailPage
