import React, {
  createContext,
  useEffect,
  useState,
  useContext,
  useMemo
} from 'react'

import {
  Card,
  Group,
  Text,
  Tooltip,
  Flex,
  Button,
  Modal,
  Textarea,
  Select,
  ActionIcon,
  Loader,
  Grid,
  Pagination,
  Input
} from '@mantine/core'
import { useForm } from '@mantine/form'
import {
  IconAlertCircle,
  IconCircleCheck,
  IconSettings,
  IconTrash
} from '@tabler/icons-react'
import { Popconfirm } from 'antd'
import { useNavigate, useParams } from 'react-router-dom'

import {
  ApiActionSchema,
  ApiTargetModeEnum,
  ApiExperimentStatusEnum,
  ApiBackendStatusStatusEnum,
  ApiComponent,
  ApiBackendStatus,
  ApiExperiment
} from '@drill-test/client'
import {
  getExperimentActionsList,
  getComponentList,
  getChaosPermission
} from '~/api'
import LoadingSpin from '~/components/LoadingSpin'
import { useCurCluster, useCurOrg } from '~/hooks/state'
import { ClusterStatus } from '~/utils/cluster-status'
import { formatDateTimeWithTz } from '~/utils/date-time'

import {
  useGetDrillTestEnableStatus,
  useEnableDrillTest,
  useDisableDrillTest,
  useGetExperimentList,
  useCreateExperiment,
  useDeleteExperiment,
  useStartExperiment,
  useApproveExperiment
} from './helpers'

// TODO: remove undefined when the backend has group auth API,
// we get undefined when the API request is not authorized with status 403
const PermissionContext = createContext<boolean | undefined>(false)
const PAGE_SIZE = 10

interface EnableDrillTestProps {
  enableCreateExperiment: boolean
  onHandleEnableExperimentActions: (enable: boolean) => void
}

const EnableDrillTest = ({
  enableCreateExperiment,
  onHandleEnableExperimentActions
}: EnableDrillTestProps) => {
  const { orgId, cid } = useParams<'orgId' | 'cid'>()
  const hasEnablePermission = useContext(PermissionContext)
  const [enableDrillTestStatus, setEnableDrillTestStatus] = useState<
    ApiBackendStatusStatusEnum | undefined
  >(undefined)

  const [openCreateExperimentModal, setOpenCreateExperimentModal] =
    useState(false)
  const [openSettingModal, setOpenSettingModal] = useState(false)
  const [openEnableFailedModal, setOpenEnableFailedModal] = useState(true)

  const {
    data: drillTestEnableStatusResp,
    isLoading: loadingDrillTestEnableStatus,
    isError: errorDrillTestEnableStatus,
    mutate
  } = useGetDrillTestEnableStatus({
    oid: orgId!,
    cid: cid!
  })

  const drillTestEnableStatusData = drillTestEnableStatusResp?.data

  useEffect(() => {
    setEnableDrillTestStatus(drillTestEnableStatusData?.status)

    const _enbaleExperimentActions =
      drillTestEnableStatusData?.status === ApiBackendStatusStatusEnum.ready
    onHandleEnableExperimentActions(_enbaleExperimentActions)
  }, [
    drillTestEnableStatusResp,
    drillTestEnableStatusData?.status,
    onHandleEnableExperimentActions
  ])

  const { mutate: enableDrillTestMut } = useEnableDrillTest()
  const { mutate: disableDrillTestMut } = useDisableDrillTest()

  const handleEnableDrillTest = async () => {
    await enableDrillTestMut({ oid: orgId!, cid: cid! })
    // revalidate
    mutate()
  }

  const handleDisableDrillTest = async () => {
    await disableDrillTestMut(
      { oid: orgId!, cid: cid! },
      // onSuccess
      () => {
        setOpenSettingModal(false)
      }
    )
    // revalidate
    mutate()
  }

  const renderStatusComponent = () => {
    switch (enableDrillTestStatus) {
      case ApiBackendStatusStatusEnum.installing:
        return (
          <Flex gap='md' wrap='wrap'>
            <LoadingSpin />
            <Text>
              Drill Test components are being deployed. It may take several
              minutes.{' '}
            </Text>
          </Flex>
        )
      case ApiBackendStatusStatusEnum.ready:
        return (
          <Flex direction='column'>
            <Button
              onClick={() => setOpenCreateExperimentModal(true)}
              className='w-40 h-10 font-light'
              disabled={!enableCreateExperiment}
            >
              Create a Drill Test
            </Button>
            {!enableCreateExperiment && (
              <Text mt='md' c='dimmed' fz='sm'>
                Cannot create new experiment since there exist waiting_approval
                / ready_to_start / running experiments.
              </Text>
            )}
          </Flex>
        )
      case ApiBackendStatusStatusEnum.uninstalling:
        return (
          <Flex gap='md' wrap='wrap'>
            <LoadingSpin />
            <Text c='dimmed' fz='sm'>
              Drill Test components are uninstalling. It may take several
              minutes.{' '}
            </Text>
          </Flex>
        )
      case ApiBackendStatusStatusEnum.install_failed:
        return (
          <Group>
            <Flex direction='column'>
              <Button
                onClick={handleDisableDrillTest}
                disabled={!hasEnablePermission}
                className='w-24 font-light'
              >
                Disable
              </Button>
              <Text mt='md' c='dimmed' fz='sm'>
                {hasEnablePermission
                  ? 'Drill test feature failed to enable, you can directly disable the feature or refer to the Drill Test Runbook for help.'
                  : 'Drill Test feature is disabled since you do not have permission to enable it or the current cluster is not ready.'}
              </Text>
              <Text c='dimmed'>
                Please refer to{' '}
                <a
                  href='https://pingcap.feishu.cn/wiki/wikcnpBKxMKwtn2iyKyReNKog4g?wiki_all_space_view_source=space_sidebar'
                  target='_blank'
                >
                  Drill Test Runbook
                </a>{' '}
                for how to use this feature.
              </Text>
            </Flex>
            <Modal
              centered
              opened={openEnableFailedModal}
              onClose={() => setOpenEnableFailedModal(false)}
              title='Error'
              styles={{ title: { fontSize: 16, fontWeight: 600 } }}
              trapFocus={false}
            >
              {/* TODO: handle error msg */}
              <Text>
                <p>Failed to enable the feature.</p>
              </Text>
              <Flex justify='flex-end'>
                <Button onClick={handleDisableDrillTest}>Disable</Button>
              </Flex>
            </Modal>
          </Group>
        )
      case ApiBackendStatusStatusEnum.disabled:
      default:
        return (
          <Group>
            <Flex direction='column'>
              <Button
                onClick={handleEnableDrillTest}
                disabled={!hasEnablePermission}
                className='w-24 font-light'
              >
                Enable
              </Button>
              <Text mt='md' c='dimmed' fz='sm'>
                {hasEnablePermission
                  ? 'Drill Test components including Chaos Mesh will be deployed for this cluster after enabling the feature.'
                  : 'Drill Test feature is disabled since you do not have permission to enable it or the current cluster is not ready.'}
              </Text>
              <Text c='dimmed'>
                Please refer to{' '}
                <a
                  href='https://pingcap.feishu.cn/wiki/wikcnpBKxMKwtn2iyKyReNKog4g?wiki_all_space_view_source=space_sidebar'
                  target='_blank'
                >
                  Drill Test Runbook
                </a>{' '}
                for how to use this feature.
              </Text>
            </Flex>
          </Group>
        )
    }
  }

  useEffect(
    () => {
      // set interval to polling enableStatus when status is installing or uninstalling
      let timer: any = null
      if (
        (enableDrillTestStatus === ApiBackendStatusStatusEnum.installing ||
          enableDrillTestStatus === ApiBackendStatusStatusEnum.uninstalling) &&
        !errorDrillTestEnableStatus
      ) {
        timer = setInterval(async () => {
          mutate()
        }, 5000)
      }

      // re-render EnableDrillTest Component when enableDrillTestStatus changed
      renderStatusComponent()
      return () => clearInterval(timer)
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [enableDrillTestStatus, errorDrillTestEnableStatus, mutate]
  )

  return (
    <div className='mb-12'>
      <Group position='apart'>
        {loadingDrillTestEnableStatus ? (
          <Loader size='sm' />
        ) : (
          <>
            {renderStatusComponent()}
            {enableDrillTestStatus === ApiBackendStatusStatusEnum.ready && (
              <ActionIcon variant='filled' color='text-cc-primary'>
                <IconSettings
                  size={18}
                  onClick={() => setOpenSettingModal(true)}
                />
              </ActionIcon>
            )}
          </>
        )}
      </Group>
      <SettingFormModal
        visible={openSettingModal}
        onHandleOpenSettingModal={(open: boolean) => setOpenSettingModal(open)}
        hasEnablePermission={hasEnablePermission}
        handleDisableDrillTest={handleDisableDrillTest}
        drillTestEnableStatusData={drillTestEnableStatusData!}
      />
      <CreateExperimentFormModal
        visible={openCreateExperimentModal}
        onHandleCreatingTask={(open: boolean) =>
          setOpenCreateExperimentModal(open)
        }
      />
    </div>
  )
}

const SettingFormModal = ({
  visible,
  onHandleOpenSettingModal,
  hasEnablePermission,
  handleDisableDrillTest,
  drillTestEnableStatusData
}: {
  visible: boolean
  onHandleOpenSettingModal: (open: boolean) => void
  hasEnablePermission: boolean | undefined
  handleDisableDrillTest: () => Promise<void>
  drillTestEnableStatusData: ApiBackendStatus
}) => {
  return (
    <Modal
      onClose={() => onHandleOpenSettingModal(false)}
      title='Drill Test Setting'
      opened={visible}
      centered
      trapFocus={false}
    >
      {drillTestEnableStatusData && (
        <>
          <Text>
            Drill test feature is enabled by{' '}
            <span className='italic'>
              {drillTestEnableStatusData?.updated_by?.email}{' '}
            </span>{' '}
            on {formatDateTimeWithTz(drillTestEnableStatusData?.updated_at!)}
          </Text>
          {hasEnablePermission && (
            <>
              <Button
                onClick={handleDisableDrillTest}
                mt='md'
                className='font-light'
              >
                Disable Drill Test
              </Button>

              <Text c='red' fz='sm' mt='md'>
                Note: Disable the feature will delete the related components to
                save cost. It will not deleted the history data.
              </Text>
            </>
          )}
        </>
      )}
    </Modal>
  )
}

const CreateExperimentFormModal = ({
  visible,
  onHandleCreatingTask
}: {
  visible: boolean
  onHandleCreatingTask: (visible: boolean) => void
}) => {
  return (
    <Modal
      centered
      opened={visible}
      onClose={() => onHandleCreatingTask(false)}
      title='Create Task'
      styles={{ title: { fontSize: 16, fontWeight: 600 } }}
      trapFocus={false}
    >
      {visible && (
        <CreateExperimentFormModalContent
          onHandleCreatingTask={onHandleCreatingTask}
        />
      )}
    </Modal>
  )
}

const CreateExperimentFormModalContent = ({
  onHandleCreatingTask
}: {
  onHandleCreatingTask: (visible: boolean) => void
}) => {
  const form = useForm({
    initialValues: {
      action: {
        kind: '',
        pod_shutdown: {
          target: {
            component: '',
            mode: '',
            name: ''
          }
        }
      },
      summary: ''
    },
    validate: {
      action: {
        kind: (value) => (value === '' ? 'Action Type is required' : null),
        pod_shutdown: {
          target: {
            mode: (value) => (value === '' ? 'Node is required' : null)
          }
        }
      }
    }
  })

  const { curCluster } = useCurCluster()
  const { curOrg } = useCurOrg()
  const { orgId, cid } = useParams<'orgId' | 'cid'>()

  const [selectedAction, setSelectedAction] = useState(null)
  const [selectedNode, setSelectedNode] = useState<string | null>(null)
  const [actionTypeList, setActionTypeList] = useState<ApiActionSchema[]>([])
  const [nodesList, setNodesList] = useState<string[]>(['random'])

  const { mutate: getExperimentListMut } = useGetExperimentList({
    oid: orgId!,
    cid: cid!
  })
  const { mutate: createExperimentMut } = useCreateExperiment()

  const handleActionTypeChange = async (val: any) => {
    setSelectedAction(val)
    setSelectedNode(null)
    setNodesList([])
    form.setFieldValue('action.kind', val.kind)
    form.setFieldValue('action.pod_shutdown.target.component', val.comp)
    try {
      const res = await getComponentList({ oid: orgId!, cid: cid! })
      const nodeList: ApiComponent = res.data
      const nodes = nodeList[val.comp! as keyof ApiComponent]!.map((n) => {
        return Object.values(n)
      })

      setNodesList(nodes.flat().concat('random'))
    } catch (e) {
      console.log(e)
    }
  }

  const handleNodeChange = (val: any) => {
    setSelectedNode(val)
    form.setFieldValue(
      'action.pod_shutdown.target.mode',
      val === ApiTargetModeEnum.random
        ? ApiTargetModeEnum.random
        : ApiTargetModeEnum.specified
    )
    form.setFieldValue(
      'action.pod_shutdown.target.name',
      val === ApiTargetModeEnum.random ? '' : val
    )
  }

  const computedActionTypeList = useMemo(() => {
    if (!actionTypeList) return []
    return actionTypeList?.flatMap((action: ApiActionSchema) =>
      action.component!.map((comp) => ({
        value: { comp: comp, kind: action.kind },
        label: `${comp + '_' + action.kind}`
      }))
    )
  }, [actionTypeList])

  const handleOnSubmit = async (values: any) => {
    onHandleCreatingTask(false)
    await createExperimentMut(
      {
        oid: orgId!,
        cid: cid!,
        experiment: values
      },

      // onSuccess
      () => {
        onHandleCreatingTask(false)
      }
    )

    // revalidate
    getExperimentListMut()
  }

  useEffect(() => {
    const fetchActionTypeList = async () => {
      const res = await getExperimentActionsList()
      setActionTypeList(res.data)
    }
    fetchActionTypeList()
  }, [])

  return (
    <>
      <form onSubmit={form.onSubmit(handleOnSubmit)}>
        <Input.Wrapper label='Tenant Name' mb='md'>
          <Input value={curOrg?.name} disabled />
        </Input.Wrapper>

        <Input.Wrapper label='Cluster Name'>
          <Input value={curCluster?.name} disabled />
        </Input.Wrapper>

        {actionTypeList && (
          <Select
            mt='md'
            label='Action Type'
            placeholder='Select type'
            data={computedActionTypeList as any}
            onChange={(val: any) => handleActionTypeChange(val)}
            value={selectedAction}
            required
            error={form.getInputProps('action.kind').error}
          />
        )}
        <Select
          mt='md'
          label='Node'
          placeholder='Select Node'
          disabled={!selectedAction}
          data={nodesList}
          onChange={(val) => handleNodeChange(val)}
          value={selectedNode}
          required
          error={form.getInputProps('action.pod_shutdown.target.mode').error}
        />
        <Textarea
          mt='md'
          label='Summary'
          placeholder='Enter Summary'
          {...form.getInputProps('summary')}
        />
        <Button type='submit' mt='md'>
          Submit
        </Button>
      </form>
    </>
  )
}

interface ExperimentListProps {
  enableExperimentActions: boolean
  onHandleEnableCreateExperiment: (enable: boolean) => void
}

const ExperimentList = ({
  enableExperimentActions,
  onHandleEnableCreateExperiment
}: ExperimentListProps) => {
  // const navigate = useNavigate()
  const { orgId, cid } = useParams<'orgId' | 'cid'>()
  const [activePage, setActivePage] = useState(1)
  const [polling, setPolling] = useState(false)

  const { data: experimentListResp, mutate: getExperimentListMut } =
    useGetExperimentList({
      oid: orgId!,
      cid: cid!,
      page: 1,
      size: PAGE_SIZE
    })

  const experimentList = experimentListResp?.data?.experiments

  useEffect(() => {
    // check enable button disable when experiment list has running/waiting_approval/draft experiment
    const hasExpectedExperiment = experimentList?.find((experiment) => {
      return (
        experiment.status === ApiExperimentStatusEnum.Running ||
        experiment.status === ApiExperimentStatusEnum.Waiting_Approve ||
        experiment.status === ApiExperimentStatusEnum.Draft
      )
    })

    const _enbaleCreateExperiment = hasExpectedExperiment ? false : true

    setPolling(!_enbaleCreateExperiment)
    onHandleEnableCreateExperiment(_enbaleCreateExperiment)
  }, [experimentListResp, onHandleEnableCreateExperiment, experimentList])

  useEffect(() => {
    let timer: any = null
    if (polling) {
      timer = setInterval(() => {
        getExperimentListMut()
      }, 5000)
    }
    return () => clearInterval(timer)
  }, [polling, getExperimentListMut])

  const handlePageChange = (page: number) => {
    setActivePage(page)
  }

  const renderExperimentList = () => {
    return (
      <>
        <div className='flex flex-col gap-4'>
          {experimentList &&
            experimentList.map((exp) => (
              <Card shadow='sm' radius='md' key={exp.experiment_id}>
                <Card.Section withBorder inheritPadding py='md'>
                  <Group position='apart'>
                    <Text>{`Created on ${formatDateTimeWithTz(
                      exp.created_at!
                    )} by ${exp.created_by!.email}`}</Text>
                    <Text>Approver: {exp.approved_by!.email || '--'}</Text>
                  </Group>
                </Card.Section>
                <Card.Section inheritPadding py='xl'>
                  <Grid justify='space-between' align='center'>
                    <Grid.Col span={2}>
                      <ExperimentStatus
                        status={exp.status!}
                        message={exp.message!}
                      />
                    </Grid.Col>
                    <Grid.Col span={3}>
                      <Text>
                        {exp.action!.pod_shutdown!.target!.component}_
                        {exp.action!.kind}{' '}
                        {exp.action!.pod_shutdown!.target!.mode ===
                        ApiTargetModeEnum.specified
                          ? '- ' + exp.action!.pod_shutdown!.target!.name
                          : ' - random node'}
                      </Text>
                    </Grid.Col>
                    <Grid.Col span={2}>
                      <Text>Summary: {exp.summary}</Text>
                    </Grid.Col>

                    <Grid.Col span={3}>
                      <Flex direction='column' className='col-span-2'>
                        <p>
                          Starts:{' '}
                          {exp.started_at
                            ? formatDateTimeWithTz(exp.started_at!)
                            : '--'}
                        </p>
                        <p>
                          Ends:{' '}
                          {exp.completed_at
                            ? formatDateTimeWithTz(exp.completed_at!)
                            : '--'}
                        </p>
                      </Flex>
                    </Grid.Col>
                    <Grid.Col style={{ maxWidth: 120 }}>
                      <ExperimentActions
                        experimentDetail={exp}
                        enableExperimentActions={enableExperimentActions}
                        getExperimentListMut={getExperimentListMut}
                      />
                    </Grid.Col>
                  </Grid>
                </Card.Section>
              </Card>
            ))}
        </div>
        <Flex
          mt={50}
          gap='md'
          justify='flex-end'
          align='center'
          direction='row'
        >
          <Pagination
            page={activePage}
            onChange={(page) => {
              handlePageChange(page)
            }}
            total={
              experimentListResp?.data.total! % PAGE_SIZE === 0
                ? experimentListResp?.data.total! / PAGE_SIZE
                : Math.floor(experimentListResp?.data.total! / PAGE_SIZE) + 1
            }
          />
        </Flex>
      </>
    )
  }

  // TODO: add no experiment page
  return (
    <>{experimentListResp?.data.total! > 0 ? renderExperimentList() : ''}</>
  )
}

interface ExperimentStatusProps {
  status: string
  message: string
}

const ExperimentStatus = ({ status, message }: ExperimentStatusProps) => {
  switch (status) {
    case ApiExperimentStatusEnum.Waiting_Approve:
      return (
        <Text align='center'>{ApiExperimentStatusEnum.Waiting_Approve}</Text>
      )
    case ApiExperimentStatusEnum.Draft:
      return <Text align='center'>{ApiExperimentStatusEnum.Draft}</Text>
    case ApiExperimentStatusEnum.Running:
      return <Text align='center'>{ApiExperimentStatusEnum.Running}</Text>
    case ApiExperimentStatusEnum.Done:
      return (
        <Flex align='center' direction='column'>
          <IconCircleCheck color='var(--cc-success-color)' />
          <Text color='var(--cc-success-color)'>
            {ApiExperimentStatusEnum.Done}
          </Text>
        </Flex>
      )
    case ApiExperimentStatusEnum.Failed:
      return (
        <Flex align='center' direction='column'>
          <Tooltip label={message} position='top-start' withArrow>
            <IconAlertCircle color='var(--cc-error-color)' />
          </Tooltip>

          <Text color='var(--cc-error-color)'>
            {ApiExperimentStatusEnum.Failed}
          </Text>
        </Flex>
      )
    case ApiExperimentStatusEnum.Deleted:
      return (
        <Flex align='center' direction='column'>
          <Tooltip label={message} position='top-start' withArrow>
            <IconTrash color='var(--cc-error-color)' />
          </Tooltip>

          <Text color='var(--cc-error-color)'>
            {ApiExperimentStatusEnum.Deleted}
          </Text>
        </Flex>
      )
    default:
      return null
  }
}

interface ExperimentActionsProps {
  experimentDetail: ApiExperiment
  enableExperimentActions: boolean
  getExperimentListMut: () => void
}

const ExperimentActions = ({
  experimentDetail,
  enableExperimentActions,
  getExperimentListMut
}: ExperimentActionsProps) => {
  const navigate = useNavigate()
  const hasEnablePermission = useContext(PermissionContext)
  const { orgId, cid } = useParams<'orgId' | 'cid'>()

  const { mutate: deleteExperimentMut } = useDeleteExperiment()
  const { mutate: startExperimentMut } = useStartExperiment()
  const { mutate: approveExperimentMut } = useApproveExperiment()

  const handleApprove = async (id: string) => {
    await approveExperimentMut({
      oid: orgId!,
      cid: cid!,
      eid: id
    })
    // revalidate
    getExperimentListMut()
  }

  const handleDelete = async (id: string) => {
    await deleteExperimentMut({
      oid: orgId!,
      cid: cid!,
      eid: id
    })
    // revalidate
    getExperimentListMut()
  }

  const handleStart = async (id: string) => {
    await startExperimentMut({
      oid: orgId!,
      cid: cid!,
      eid: id
    })
    // revalidate
    getExperimentListMut()
  }

  const handleDetailClick = (id: number) => {
    navigate(`/orgs/${orgId}/clusters/${cid}/drill-test/${id}`)
  }

  const renderActionButtons = () => {
    switch (experimentDetail.status) {
      case ApiExperimentStatusEnum.Waiting_Approve:
        return (
          <>
            <ActionButton
              textOnBtn='Approve'
              confirmType='default'
              onHandleAction={() =>
                handleApprove(String(experimentDetail.experiment_id)!)
              }
              experimentDetail={experimentDetail}
              disable={!hasEnablePermission || !enableExperimentActions}
              variant='filled'
            />
            <ActionButton
              textOnBtn='Delete'
              confirmType='danger'
              onHandleAction={() =>
                handleDelete(String(experimentDetail.experiment_id!))
              }
              experimentDetail={experimentDetail}
              disable={!hasEnablePermission || !enableExperimentActions}
              needConfirm={true}
              variant='outline'
            />
          </>
        )
      case ApiExperimentStatusEnum.Draft:
        return (
          <>
            <ActionButton
              textOnBtn='Start'
              confirmType='default'
              onHandleAction={() =>
                handleStart(String(experimentDetail.experiment_id!))
              }
              experimentDetail={experimentDetail}
              disable={!hasEnablePermission || !enableExperimentActions}
              variant='light'
            />
            <ActionButton
              textOnBtn='Delete'
              confirmType='danger'
              onHandleAction={() =>
                handleDelete(String(experimentDetail.experiment_id!))
              }
              experimentDetail={experimentDetail}
              disable={!hasEnablePermission || !enableExperimentActions}
              needConfirm={true}
              variant='outline'
            />
          </>
        )
    }
  }

  return (
    <Flex direction='column' gap='sm'>
      {renderActionButtons()}
      {(experimentDetail.status === ApiExperimentStatusEnum.Running ||
        experimentDetail.status === ApiExperimentStatusEnum.Done) && (
        <Button
          onClick={() => handleDetailClick(experimentDetail.experiment_id!)}
          className='font-light'
          variant='outline'
        >
          Details
        </Button>
      )}
    </Flex>
  )
}

const ActionButton = ({
  textOnBtn,
  confirmType,
  onHandleAction,
  experimentDetail,
  disable,
  needConfirm = false,
  variant = 'light'
}: {
  textOnBtn: string
  confirmType?: 'danger' | 'default'
  onHandleAction: (eid: number) => void
  experimentDetail: ApiExperiment
  disable: boolean
  needConfirm?: boolean
  variant: 'outline' | 'light' | 'filled' | 'subtle'
}) => {
  return (
    <>
      {needConfirm ? (
        <Popconfirm
          onConfirm={() => onHandleAction(experimentDetail.experiment_id!)}
          title='Are you sure?'
          okType={confirmType}
        >
          <Button disabled={disable} className='font-light' variant={variant}>
            {textOnBtn}
          </Button>
        </Popconfirm>
      ) : (
        <>
          <Button
            onClick={() => onHandleAction(experimentDetail.experiment_id!)}
            disabled={disable}
            className='font-light'
            variant={variant}
          >
            {textOnBtn}
          </Button>
        </>
      )}
    </>
  )
}

const Page: React.FC = () => {
  const { curCluster } = useCurCluster()
  const [hasEnablePermission, setHasEnablePermission] = useState<
    boolean | undefined
  >(false)

  // Disable create experiment button when there is running / waiting_approval / draft experiment
  const [enableCreateExperiment, setEnableCreateExperiment] = useState(false)

  // Disable experiment action buttons when there has no permission to enable drill test or there is no normal cluster
  const [enableExperimentActions, setEnableExperimentActions] = useState(false)

  useEffect(() => {
    const getPermission = async () => {
      try {
        const res = await getChaosPermission()
        setHasEnablePermission(
          res.status === 200 &&
            (curCluster?.status === ClusterStatus.Normal ||
              curCluster?.status === ClusterStatus.Active)
        )
      } catch (e) {
        console.log(e)
      }
    }

    getPermission()
  }, [curCluster])
  return (
    <PermissionContext.Provider value={hasEnablePermission}>
      <EnableDrillTest
        enableCreateExperiment={enableCreateExperiment}
        onHandleEnableExperimentActions={(enable: boolean) =>
          setEnableExperimentActions(enable)
        }
      />
      <ExperimentList
        onHandleEnableCreateExperiment={(enable: boolean) =>
          setEnableCreateExperiment(enable)
        }
        enableExperimentActions={enableExperimentActions}
      />
    </PermissionContext.Provider>
  )
}

const DrillTestPage: React.FC = () => {
  return <Page />
}

export default DrillTestPage
