import { LoadingOutlined } from '@ant-design/icons'
import { Alert } from 'antd'
import { useEffect, useState } from 'react'

import { clusterServiceIsInClusterOpsMaintenanceWindow } from 'apiClient/services/devops'

const MAINTENANCE_WINDOW_CHECK_INFO_URL =
  'https://pingcap.feishu.cn/wiki/KLIhwUR2Bi1MTxks5ZkcP2ZmnFh?larkTabName=space#F32pdhpoDotBBvxcTl1cQnqSnyc'

const maintenanceWindowCheckMessage = (
  <span>
    Maintenance Window Check
    <a
      href={MAINTENANCE_WINDOW_CHECK_INFO_URL}
      target="_blank"
      rel="noreferrer"
      style={{ marginLeft: 8, fontSize: 12, fontWeight: 400 }}
    >
      Info
    </a>
  </span>
)

const normalizeExecuteTimes = (executeTimes?: number[]) => {
  const normalizedExecuteTimes = executeTimes?.filter((executeTime) =>
    Number.isFinite(executeTime)
  )

  return normalizedExecuteTimes?.length ? normalizedExecuteTimes : undefined
}

export const useClusterOpsMaintenanceWindowCheck = (
  clusterId?: string,
  executeTimes?: number[]
) => {
  const [isCheckingMaintenanceWindow, setIsCheckingMaintenanceWindow] =
    useState(false)
  const [isInMaintenanceWindow, setIsInMaintenanceWindow] = useState<
    boolean | undefined
  >(undefined)
  const executeTimesKey = normalizeExecuteTimes(executeTimes)?.join(',')

  useEffect(() => {
    let canceled = false

    const checkMaintenanceWindow = async () => {
      if (!clusterId) {
        setIsCheckingMaintenanceWindow(false)
        setIsInMaintenanceWindow(undefined)
        return
      }

      setIsCheckingMaintenanceWindow(true)
      try {
        const normalizedExecuteTimes = executeTimesKey
          ? executeTimesKey.split(',').map(Number)
          : undefined
        const resp = await clusterServiceIsInClusterOpsMaintenanceWindow(
          clusterId,
          normalizedExecuteTimes
            ? { execute_times: normalizedExecuteTimes }
            : undefined
        )
        if (!canceled) {
          setIsInMaintenanceWindow(resp.data?.is)
        }
      } catch (error) {
        if (!canceled) {
          setIsInMaintenanceWindow(undefined)
        }
      } finally {
        if (!canceled) {
          setIsCheckingMaintenanceWindow(false)
        }
      }
    }

    checkMaintenanceWindow()

    return () => {
      canceled = true
    }
  }, [clusterId, executeTimesKey])

  return {
    isCheckingMaintenanceWindow,
    isInMaintenanceWindow
  }
}

export const ClusterOpsMaintenanceWindowCheckAlert = ({
  clusterId,
  executeTime,
  executeTimes
}: {
  clusterId?: string
  executeTime?: number
  executeTimes?: number[]
}) => {
  const normalizedExecuteTimes = normalizeExecuteTimes([
    ...(executeTimes || []),
    ...(executeTime !== undefined ? [executeTime] : [])
  ])
  const { isCheckingMaintenanceWindow, isInMaintenanceWindow } =
    useClusterOpsMaintenanceWindowCheck(clusterId, normalizedExecuteTimes)

  if (isCheckingMaintenanceWindow) {
    return (
      <Alert
        style={{ marginBottom: '12px' }}
        message={maintenanceWindowCheckMessage}
        description={<span>Checking maintenance window...</span>}
        type="info"
        showIcon
        icon={<LoadingOutlined />}
      />
    )
  }

  if (isInMaintenanceWindow === true) {
    return (
      <Alert
        style={{ marginBottom: '12px' }}
        message={maintenanceWindowCheckMessage}
        description={
          <span>
            This cluster is in maintenance window. Operation is allowed.
          </span>
        }
        type="success"
        showIcon
      />
    )
  }

  if (isInMaintenanceWindow === false) {
    return (
      <Alert
        style={{ marginBottom: '12px' }}
        message={maintenanceWindowCheckMessage}
        description={
          <span>
            Operation does not follow a maintenance window. Approval will append
            additional admin approvers.
          </span>
        }
        type="warning"
        showIcon
      />
    )
  }

  return null
}
