import { ReloadOutlined } from '@ant-design/icons'
import {
  Alert,
  Badge,
  Button,
  Card,
  Descriptions,
  Divider,
  Modal,
  Space,
  Table
} from 'antd'
import { ColumnsType } from 'antd/lib/table'
import Title from 'antd/lib/typography/Title'
import { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import useProfileContext from 'useProfileContext'

import {
  jumpControllerCancelAuthorization,
  jumpControllerGetAuthorization
} from 'apiClient/services/devops'
import {
  AuditAuditLogType,
  JumpJump,
  JumpAuthorization,
  JumpDestinationType
} from 'apiClient/services/devops/interface'
import ApprovalTable from 'components/ApprovalTable'
import AuditTable from 'components/Audit'
import { ClusterDetailLinkPopover } from 'components/DetailLinkPopover/ClusterDetailLinkPopover'
import ModalForm from 'components/ModalForm'
import { toLocal } from 'pages/Devops/Maintenance/Detail'

import JumpServerConnect from './JumpServerConnect'
import {
  GetCancelError,
  GetDestinationsFromUnion,
  GetJumpCommand
} from './util'

const statusActionText: { [key: string]: string } = {
  created: 'created',
  approving: 'approving',
  notapproved: 'notapproved',
  creating: 'creating',
  creationfailed: 'creationfailed',
  expired: 'expired',
  canceled: 'canceled',
  initialized: 'initialized'
}

const statusActionColor: { [key: string]: string } = {
  created: 'green',
  approving: 'orange',
  notapproved: 'red',
  creating: 'blue',
  creationfailed: 'red',
  expired: 'grey',
  canceled: 'black',
  initialized: 'lime'
}

export default function AuthorizationDetail() {
  const { authorization_id } = useParams<{ authorization_id: string }>()
  const [jumpAuthorization, setJumpAuthorization] =
    useState<JumpAuthorization>()

  const [reload, setReload] = useState(false)
  const [connectModalOpen, setConnectModalOpen] = useState<boolean>(false)
  const [cancelModalOpen, setCancelModalOpen] = useState<boolean>(false)
  const [forceCancelModalOpen, setForceCancelModalOpen] =
    useState<boolean>(false)
  const [cancelError, setCancelError] = useState({
    errcode: '',
    errmsg: ''
  })

  const columnsOfJump: ColumnsType<JumpJump> = [
    {
      title: 'Plane',
      render: (_: any, record) => {
        return record.destination_type
      }
    },
    {
      title: 'Destination',
      render: (_: any, record) => {
        const id = GetDestinationsFromUnion(record.destination)
        if (record.destination_type === JumpDestinationType.dedicated) {
          return <ClusterDetailLinkPopover clusterId={id} text={id} />
        }
        return id
      }
    },
    {
      title: 'Jump Method',
      render: (_: any, record) => {
        return record.method
      }
    },
    {
      title: 'Jump Command',
      render: (_: any, record) => {
        return GetJumpCommand(record)
      }
    }
  ]

  const CancelModalFormFields = () => {
    return (
      <span style={{ fontSize: 'larger' }}>
        Sure to cancel this jump authorization?
      </span>
    )
  }

  const ForceCancelModalFormFields = () => {
    return (
      <Space direction="vertical" size="middle">
        <span style={{ fontSize: 'larger' }}>
          Normal cancellation failed. Do you want to force cancel this jump
          authorization?
        </span>
        <Alert
          message={cancelError.errcode}
          description={cancelError.errmsg}
          type="error"
          showIcon
        />
        <Alert
          message="Force Cancel Warning"
          description="Force cancel skips cleanup for some resources and may cause resource leaks. It is typically used when the cluster cannot be accessed normally."
          type="warning"
          showIcon
        />
      </Space>
    )
  }

  const {
    profile: { userEmail }
  } = useProfileContext()

  async function fetch() {
    const data = (
      await jumpControllerGetAuthorization(parseInt(authorization_id))
    ).data.authorization
    setJumpAuthorization(data)
  }

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

  const handleConnect = () => {
    setConnectModalOpen(true)
  }

  const handleCancel = async () => {
    try {
      await jumpControllerCancelAuthorization(parseInt(authorization_id), {
        force: false
      })
      setCancelModalOpen(false)
      setReload((pre) => !pre)
    } catch (error) {
      setCancelError(GetCancelError(error))
      setCancelModalOpen(false)
      setForceCancelModalOpen(true)
    }
  }

  const handleForceCancel = async () => {
    await jumpControllerCancelAuthorization(parseInt(authorization_id), {
      force: true,
      timeout: 10
    })
    setForceCancelModalOpen(false)
    setReload((pre) => !pre)
  }

  const enableCancel = () => {
    return (
      jumpAuthorization?.phase === 'created' ||
      jumpAuthorization?.phase === 'approving' ||
      jumpAuthorization?.phase === 'creating' ||
      jumpAuthorization?.phase === 'initialized'
    )
  }

  const [activeTabKey, setActiveTabKey] = useState<string>('approval')
  const onTabChange = (key: string) => {
    setActiveTabKey(key)
  }

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

  const contentList: Record<string, React.ReactNode> = {
    audit: authorization_id ? (
      <AuditTable type={AuditAuditLogType.jump} id={authorization_id} />
    ) : (
      <div>Loading...</div>
    ),
    approval: jumpAuthorization?.approval_id ? (
      <ApprovalTable id={jumpAuthorization?.approval_id}></ApprovalTable>
    ) : (
      <div>Loading...</div>
    )
  }

  return (
    <>
      <div>
        <Card
          title={<Title level={4}>{`Jump Authorization Detail`}</Title>}
          extra={
            <Space>
              <Button
                type="primary"
                onClick={handleConnect}
                disabled={
                  !(
                    jumpAuthorization?.phase === 'created' &&
                    jumpAuthorization?.applicant === userEmail
                  )
                }
              >
                Connect
              </Button>
              &nbsp;
              <Button
                type="default"
                onClick={() => {
                  setCancelModalOpen(true)
                }}
                disabled={!enableCancel()}
              >
                Cancel
              </Button>
              &nbsp;
              <Button
                onClick={() => {
                  setReload((pre) => !pre)
                }}
                icon={<ReloadOutlined />}
              ></Button>
            </Space>
          }
        >
          <Title level={5}>Basic Information</Title>
          <Descriptions>
            <Descriptions.Item label="ID">
              {jumpAuthorization?.id}
            </Descriptions.Item>
            <Descriptions.Item label="Privilege">
              {jumpAuthorization?.privilege}
            </Descriptions.Item>
            <Descriptions.Item label="Applicant">
              {jumpAuthorization?.applicant}
            </Descriptions.Item>
            <Descriptions.Item label="Phase">
              {
                <Badge
                  color={
                    statusActionColor[jumpAuthorization?.phase || '']
                      ? statusActionColor[jumpAuthorization?.phase || '']
                      : 'grey'
                  }
                  text={
                    statusActionText[jumpAuthorization?.phase || '']
                      ? statusActionText[jumpAuthorization?.phase || '']
                      : 'Unknown'
                  }
                />
              }
            </Descriptions.Item>
            <Descriptions.Item label="Created At">
              {toLocal(jumpAuthorization?.created_at)}
            </Descriptions.Item>
            <Descriptions.Item label="Expire At">
              {toLocal(jumpAuthorization?.expire_at)}
            </Descriptions.Item>
            <Descriptions.Item label="Reason">
              {jumpAuthorization?.reason}
            </Descriptions.Item>
          </Descriptions>

          <Divider />

          <Title level={5}>Destinations</Title>
          <Table
            dataSource={jumpAuthorization?.jumps}
            columns={columnsOfJump}
            pagination={false}
          ></Table>
        </Card>
      </div>

      <Card
        tabList={tabList}
        tabProps={{ size: 'middle' }}
        bordered={false}
        activeTabKey={activeTabKey}
        onTabChange={(key) => {
          onTabChange(key)
        }}
      >
        {contentList[activeTabKey]}
      </Card>

      <Modal
        title={'Connect to Jumpserver'}
        visible={connectModalOpen}
        onCancel={() => setConnectModalOpen(false)}
        footer={null}
        width={1000}
      >
        <JumpServerConnect auth={jumpAuthorization!} open={connectModalOpen} />
      </Modal>

      <ModalForm
        visible={!!cancelModalOpen}
        name="Cancel Authorization"
        title={'Cancel Authorization'}
        width={380}
        getFields={() => {
          return <CancelModalFormFields />
        }}
        okText={'Confirm'}
        onSubmit={handleCancel}
        onCancel={() => {
          setCancelModalOpen(false)
        }}
      />

      <ModalForm
        visible={!!forceCancelModalOpen}
        name="Force Cancel Authorization"
        title={'Force Cancel Authorization'}
        width={520}
        getFields={() => {
          return <ForceCancelModalFormFields />
        }}
        okText={'Force Cancel'}
        okButtonProps={{ danger: true }}
        onSubmit={handleForceCancel}
        onCancel={() => {
          setForceCancelModalOpen(false)
        }}
      />
    </>
  )
}
