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

import { Button, Card, Drawer, Group, Stack, Title } from '@tidbcloud/uikit'
import { useQuery } from 'react-query'
import { useNavigate } from 'react-router-dom'

import UIKitProvider from '~/uikit-provider'
import { eventTracking } from '~/utils/telemetry'

import { ClusterPageShell } from '../migration_shared/components'
import { useClusterToClusterInfo } from '../migration_shared/types'
import { StatementProvider, useStatementContext } from '../utils/context'
import { getStatementContext } from '../utils/context-impl'
import { PlanDetail } from './PlanDetail'
import { PlansList } from './plans-list/PlansList'
// import { RelatedSlowQuery } from './slow-query/RelatedSlowQuery'
import { SQLBindingModal } from './SQLBindingModal'
import { StmtSummary } from './StmtSummary'
import { useStatementDetailUrlState } from './url-state'

const StatementDetail: React.FC<React.PropsWithChildren<unknown>> = () => {
  useEffect(() => {
    document.title = `TiDB Clinic - Statement Detail`
  }, [])
  const ctx = useStatementContext()
  const { digest, schema_name, begin_time, end_time, plans, setPlans } =
    useStatementDetailUrlState()
  const [planDetailOpened, setPlanDetailOpened] = useState(false)
  const [openedPlanDigest, setOpenedPlanDigest] = useState<string | undefined>(
    undefined
  )
  const [sqlBindingModalOpened, setSQLBindingModalOpened] = useState(false)

  const { data: stmtPlans, isLoading: fetchingPlans } = useQuery(
    [
      'statement_detail',
      'plans',
      ctx.cfg.clusterId,
      digest,
      schema_name,
      begin_time,
      end_time
    ],
    () => ctx.ds.getStmtPlans({ digest, schema_name, begin_time, end_time }),
    {
      refetchOnWindowFocus: false
    }
  )
  const stmtSummary = stmtPlans?.[0]
  useEffect(() => {
    if (plans.length === 0 && stmtPlans) {
      setPlans(stmtPlans.map((p) => p.plan_digest!))
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [stmtPlans])

  const showPlanList = (stmtPlans?.length || 0) > 1

  const { data: stmtPlanDetail, isLoading: fetchingPlanDetail } = useQuery(
    [
      'statement_detail',
      'detail',
      ctx.cfg.clusterId,
      digest,
      schema_name,
      begin_time,
      end_time,
      openedPlanDigest
    ],
    () =>
      ctx.ds.getStmtPlanDetail({
        digest,
        schema_name,
        begin_time,
        end_time,
        plans: openedPlanDigest ? [openedPlanDigest!] : []
      }),
    {
      enabled: planDetailOpened || !showPlanList,
      refetchOnWindowFocus: false
    }
  )

  return (
    <ClusterPageShell
      title='SQL Detail'
      headerProps={{
        withBack: true,
        onBackClick() {
          ctx.event.backFromDetail()
          eventTracking('SQL Repository Detail Back Button Clicked')
        }
      }}
    >
      <Stack>
        <StmtSummary
          stmt={stmtSummary}
          plansCount={stmtPlans?.length ?? 0}
          loading={fetchingPlans}
        />

        {!showPlanList && (
          <Card shadow='none' p='xl'>
            <Group justify='space-between'>
              <Title order={5}>Execution Detail</Title>
              {stmtPlanDetail?.plan_digest && (
                <Button
                  data-mp-event='Statement Detail Create SQL Binding Button Clicked'
                  data-mp-plan-digest={openedPlanDigest}
                  onClick={() => {
                    setSQLBindingModalOpened(true)
                  }}
                  size='sm'
                >
                  Create SQL Binding
                </Button>
              )}
            </Group>

            <PlanDetail
              planDetail={stmtPlanDetail}
              loading={fetchingPlanDetail}
              computed={ctx.cfg.computed}
            />
          </Card>
        )}
        {showPlanList && (
          <PlansList
            data={stmtPlans ?? []}
            onPlanClick={(planDigest) => {
              setOpenedPlanDigest(planDigest)
              setPlanDetailOpened(true)
              eventTracking('SQL Repository Plan Clicked', { planDigest })
            }}
          />
        )}

        {/* <RelatedSlowQuery /> */}

        <Drawer
          position='right'
          size='70%'
          title={
            <Title order={5}>
              Plan Detail{openedPlanDigest ? `: ${openedPlanDigest}` : ''}
            </Title>
          }
          styles={(theme) => ({
            header: {
              padding: '16px 24px 16px 24px',
              borderBottom: `1px solid ${theme.colors.carbon[4]}`
            },
            body: {
              height: 'calc(100% - 61px)',
              overflow: 'auto',
              paddingBottom: '77px'
            }
          })}
          opened={planDetailOpened}
          onClose={() => {
            setPlanDetailOpened(false)
            setSQLBindingModalOpened(false)
            setOpenedPlanDigest(undefined)
          }}
        >
          <PlanDetail
            planDetail={stmtPlanDetail}
            loading={fetchingPlanDetail}
            computed={ctx.cfg.computed}
          />

          {ctx.cfg.computed.isDedicated && openedPlanDigest && (
            <>
              <Group
                w='100%'
                px='xl'
                py='md'
                justify='flex-end'
                bg='white'
                sx={(theme) => ({
                  position: 'absolute',
                  bottom: 0,
                  right: 0,
                  borderTop: `1px solid ${theme.colors.carbon[4]}`
                })}
              >
                <Button
                  variant='outline'
                  onClick={() => setPlanDetailOpened(false)}
                >
                  Close
                </Button>
                <Button
                  data-mp-event='Statement Detail Create SQL Binding Button Clicked'
                  data-mp-plan-digest={openedPlanDigest}
                  onClick={() => {
                    setSQLBindingModalOpened(true)
                  }}
                >
                  Create SQL Binding
                </Button>
              </Group>
            </>
          )}
        </Drawer>
        <SQLBindingModal
          opened={
            (showPlanList ? planDetailOpened : !!stmtPlanDetail?.plan_digest) &&
            sqlBindingModalOpened
          }
          onClose={() => setSQLBindingModalOpened(false)}
          digest={
            showPlanList
              ? openedPlanDigest ?? ''
              : stmtPlanDetail?.plan_digest ?? ''
          }
        />
      </Stack>
    </ClusterPageShell>
  )
}

/////////////////////////////////////////

interface StatementDetailPageProps {}

const StatementDetailPage: React.FC<
  React.PropsWithChildren<StatementDetailPageProps>
> = () => {
  const navigate = useNavigate()

  const clusterInfo = useClusterToClusterInfo()
  return (
    <UIKitProvider>
      <StatementProvider value={getStatementContext(clusterInfo, navigate)}>
        <StatementDetail />
      </StatementProvider>
    </UIKitProvider>
  )
}

// use React.memo to prevent re-rendering when the cluster is updating periodically
export default StatementDetailPage
