import { ReloadOutlined } from '@ant-design/icons'
import { useSessionStorageState } from 'ahooks'
import {
  Badge,
  Button,
  Card,
  Descriptions,
  Divider,
  Modal,
  Space,
  Typography
} from 'antd'
import moment from 'moment'
import { Moment } from 'moment'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { Link, useParams } from 'react-router-dom'

import {
  closeK8sUpgradeTask,
  createK8sUpgradeTask,
  deleteK8sUpgradeTask,
  getK8sUpgradeTask,
  submitK8sUpgradeTask,
  updateK8sUpgradeTask
} from 'apiClient/services/devops'

import { getTenantByID } from '../../../../apiClient/api'
import {
  AuditControllerListAuditLogType,
  K8supgradeCloseTaskReq,
  K8supgradeCreateTaskReq,
  K8supgradeTask,
  K8supgradeTaskStatus,
  K8supgradeUpdateTaskReq
} from '../../../../apiClient/services/devops/interface'
import ApprovalTable from '../../../../components/ApprovalTable'
import AuditTable from '../../../../components/Audit'
import value from '../../../../components/currency/Value'
import ModalForm from '../../../../components/ModalForm'
import { toLocal } from '../../Maintenance/Detail'
import { TaskK8sClusterList } from '../TaskK8sClusters'
import K8sUpgradeTaskModalFormFields from '../TaskList/CreateTaskForm'
import { K8sUpgradeTaskForm } from '../TaskList/K8sUpgradeList'

import EditTaskModalFormFields from './EditTaskForm'
import { TaskExcludedClusterList } from './ExcludedClusters'
const { Title } = Typography

export const statusActionText = {
  pending: 'pending',
  approving: 'approving',
  running: 'running',
  completed: 'completed',
  cancelled: 'cancelled'
}

export const statusActionColor: Record<K8supgradeTaskStatus, string> = {
  pending: 'grey',
  approving: 'orange',
  running: 'blue',
  completed: 'green',
  cancelled: 'black'
}

export type EditTaskForm = {
  deadline: Moment
  max_restart_times: number
}

export default function K8sUpgradeTaskDetail() {
  const params = new URLSearchParams(window.location.search)
  const name = params.get('name') || ''
  const { task_id } = useParams<{ task_id: string }>()
  const [, setTaskName] = useSessionStorageState('task_name', {
    defaultValue: name
  })
  const [reload, setReload] = useState(false)
  const [task, setTask] = useState<K8supgradeTask>()
  const [activeTabKey, setActiveTabKey] = useState<string>('approval')
  const onTabChange = (key: string) => {
    setActiveTabKey(key)
  }
  const [activeClusterTabKey, setClusterActiveTabKey] =
    useState<string>('clusterList')
  const onClusterTabChange = (key: string) => {
    setClusterActiveTabKey(key)
  }
  const [modalOpen, setModalOpen] = useState<boolean>(false)

  async function fetch() {
    const data = (await getK8sUpgradeTask(task_id)).data
    setTask(data)
  }

  useEffect(() => {
    fetch()
  }, [reload])

  useEffect(() => {
    setTaskName(name)

    return () => {
      setTaskName('')
    }
  }, [name, setTaskName])

  const enableDelete = () => {
    return task?.status != 'running'
  }

  const handleClickDelete = async () => {
    Modal.info({
      title: 'Info',
      closable: true,
      content: (
        <div>
          <p>Sure to delete this upgrade task?</p>
        </div>
      ),
      okText: 'Confirm',
      async onOk() {
        try {
          await deleteK8sUpgradeTask(task_id)
          Modal.success({
            title: 'info',
            content: (
              <div>
                <p>Successfully Delete</p>
              </div>
            ),
            onOk() {}
          })
          window.history.back()
          // setReload((pre) => !pre)
        } catch (error) {
          Modal.error({
            title: error.response.data.errcode,
            content: error.response.data.errmsg
          })
          window.history.back()
          // setReload((pre) => !pre)
        }
      }
    })
  }

  const enableCancel = () => {
    return (
      task?.status === 'pending' ||
      task?.status === 'approving' ||
      task?.status === 'running'
    )
  }

  const handleClickCancel = async () => {
    Modal.info({
      title: 'Info',
      closable: true,
      content: (
        <div>
          <p>Sure to cancel this upgrade task?</p>
        </div>
      ),
      okText: 'Confirm',
      async onOk() {
        const req: K8supgradeCloseTaskReq = {
          reason: ''
        }

        try {
          await closeK8sUpgradeTask(task_id, req)
          Modal.success({
            title: 'info',
            content: (
              <div>
                <p>Successfully Cancel</p>
              </div>
            ),
            onOk() {}
          })
          setReload((pre) => !pre)
        } catch (error) {
          Modal.error({
            title: error.response.data.errcode,
            content: error.response.data.errmsg
          })
          setReload((pre) => !pre)
        }
      }
    })
  }

  const enableEdit = () => {
    return task?.status === 'pending'
  }
  const renderFormFields = () => {
    return <EditTaskModalFormFields />
  }
  const handleEdit = useCallback(
    async (payload: EditTaskForm) => {
      const req: K8supgradeUpdateTaskReq = {
        deadline: payload.deadline.unix(),
        name: task?.name!,
        max_restart_times: payload.max_restart_times!
      }
      return updateK8sUpgradeTask(task_id, req)
        .then(() => {
          setModalOpen(false)
          setReload((pre) => !pre)
        })
        .catch((e) => {
          // HACK: overide the default error of axios to enable showing error message in ModalForm
          if (e.response.data.errmsg && e.response.status)
            throw {
              response: {
                data: {
                  message: e.response.status + ': ' + e.response.data.errmsg
                }
              }
            }
          else throw e
        })
    },
    [reload]
  )

  const enableSubmit = () => {
    return task?.status === 'pending'
  }

  const handleClickSubmit = async () => {
    Modal.info({
      title: 'Info',
      closable: true,
      content: (
        <div>
          <p>Sure to submit this upgrade task?</p>
        </div>
      ),
      okText: 'Confirm',
      async onOk() {
        try {
          await submitK8sUpgradeTask(task_id)
          Modal.success({
            title: 'info',
            content: (
              <div>
                <p>Successfully Submit</p>
              </div>
            ),
            onOk() {}
          })
          setReload((pre) => !pre)
        } catch (error) {
          Modal.error({
            title: error.response.data.errcode,
            content: error.response.data.errmsg
          })
          setReload((pre) => !pre)
        }
      }
    })
  }

  const tabList = [
    {
      key: 'approval',
      tab: 'Approval Info'
    },
    {
      key: 'audit',
      tab: 'Audit Logs'
    }
  ]

  const contentList: Record<string, React.ReactNode> = {
    approval:
      task?.approval_id !== undefined ? (
        <ApprovalTable id={task?.approval_id}></ApprovalTable>
      ) : (
        <></>
      ),
    audit:
      task?.id !== undefined ? (
        <AuditTable
          type={AuditControllerListAuditLogType.k8s_upgrade_task}
          id={task.id}
        ></AuditTable>
      ) : (
        <></>
      )
  }

  const tabListCluster = [
    {
      key: 'clusterList',
      tab: 'Clusters to be Upgraded'
    },
    {
      key: 'excludedClusters',
      tab: 'Excluded Clusters'
    }
  ]
  const contentListCluster: Record<string, React.ReactNode> = {
    clusterList: <TaskK8sClusterList status={task?.status!} />,
    excludedClusters: <TaskExcludedClusterList />
  }
  if (!task) {
    return <></>
  }
  const selector = (() => {
    switch (task.selector_type) {
      case 'none':
        return 'None'
      case 'internal':
        return 'Internal Clusters'
      case 'non_prod':
        return 'Non-prod Clusters'
      case 'by_region':
        return 'By Region'
      case 'by_tenant_ids':
        return 'By Tenant IDs'
      case 'by_project_ids':
        return 'By Project IDs'
      case 'by_tidb_cluster_ids':
        return 'By Cluster IDs'
      case 'by_k8s_names':
        return 'By K8s Names'
      default:
        return task.selector_type || 'None'
    }
  })()
  return (
    <>
      <div>
        <Card
          bordered={false}
          title={<Title level={4}>{task.name}</Title>}
          extra={
            <Space>
              <Button
                type="primary"
                onClick={() => {
                  setModalOpen(!modalOpen)
                }}
                disabled={!enableEdit()}
              >
                Edit
              </Button>
              <Button
                type="primary"
                onClick={handleClickSubmit}
                // size={'small'}
                disabled={!enableSubmit()}
              >
                Submit
              </Button>
              <Button
                type="default"
                danger
                // size={'small'}
                onClick={handleClickCancel}
                disabled={!enableCancel()}
              >
                Cancel
              </Button>
              <Button
                type="primary"
                danger
                // size={'small'}
                onClick={handleClickDelete}
                disabled={!enableDelete()}
              >
                Delete
              </Button>
              <Button
                onClick={() => {
                  setReload((pre) => !pre)
                }}
                icon={<ReloadOutlined />}
              ></Button>
            </Space>
          }
        >
          <Descriptions>
            <Descriptions.Item label="ID">{task.id}</Descriptions.Item>
            <Descriptions.Item label="Status">
              {
                <Badge
                  color={statusActionColor[task?.status!]}
                  text={statusActionText[task?.status!]}
                />
              }
            </Descriptions.Item>
            <Descriptions.Item label="Deadline">
              {toLocal(task.deadline)}
            </Descriptions.Item>
            <Descriptions.Item label="Cloud Provider">
              {task.cloud_provider}
            </Descriptions.Item>
            <Descriptions.Item label="EOS Version">
              {task.version_to_be_upgraded}
            </Descriptions.Item>
            <Descriptions.Item label="Max Restart Times">
              {task.max_restart_times}
            </Descriptions.Item>
            <Descriptions.Item label="Selector">{selector}</Descriptions.Item>
            <Descriptions.Item label="Selector Value">
              {task.selector_value}
            </Descriptions.Item>
            <Descriptions.Item label="Applicant">
              {task.applicant}
            </Descriptions.Item>
            <Descriptions.Item label="Created At">
              {toLocal(task.created_at)}
            </Descriptions.Item>
            <Descriptions.Item label="Close At">
              {toLocal(task.closed_at)}
            </Descriptions.Item>
          </Descriptions>
        </Card>
        <Divider></Divider>
        <ModalForm<EditTaskForm>
          initValues={{
            max_restart_times: task.max_restart_times!,
            deadline: moment.unix(task.deadline!)
          }}
          visible={!!modalOpen}
          name="edit k8s upgrade task"
          title="Edit K8S Upgrade Task"
          getFields={renderFormFields}
          onSubmit={handleEdit}
          onCancel={() => {
            setModalOpen(false)
          }}
        />
        <Card
          title={<Title level={5}>K8S Clusters</Title>}
          tabList={tabListCluster}
          tabProps={{ size: 'middle' }}
          bordered={false}
          activeTabKey={activeClusterTabKey}
          onTabChange={(key) => {
            onClusterTabChange(key)
          }}
        >
          {contentListCluster[activeClusterTabKey]}
        </Card>
      </div>
      <Divider />
      <Card
        tabList={tabList}
        tabProps={{ size: 'middle' }}
        bordered={false}
        activeTabKey={activeTabKey}
        onTabChange={(key) => {
          onTabChange(key)
        }}
      >
        {contentList[activeTabKey]}
      </Card>
    </>
  )
}
