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

import {
  cloudConfigControllerGetDefaultConfigurationChangeRelease,
  cloudConfigControllerCancelDefaultConfigurationChangeRelease
} from 'apiClient/services/devops'
import {
  CloudconfigDefaultComponentChange,
  CloudconfigDefaultConfigurationChangeItemType,
  CloudconfigGetDefaultConfigurationChangeRelease,
  CloudconfigTemplateDefaultCaseBindingChange,
  CloudconfigDefaultConfigurationChangeReleasePhase,
  CloudconfigDefaultConfigurationChangeItem
} from 'apiClient/services/devops/interface'
import ApprovalTable from 'components/ApprovalTable'
import ModalForm from 'components/ModalForm'
import { toLocal } from 'pages/Devops/Maintenance/Detail'

import { UniqueAndSortComponents } from './Table/TemplateModifyTable'

function ShowReleasedTemplates({
  items
}: {
  items: CloudconfigDefaultConfigurationChangeItem[]
}) {
  const datas = items
    .filter(
      (v) =>
        v.type ===
        CloudconfigDefaultConfigurationChangeItemType.template_default_case_binding
    )
    .map((v) => {
      return v.data?.template_default_case_binding!
    })

  const configTypes = UniqueAndSortComponents(
    datas.map((v) => {
      return v.origin?.default_case?.config_type!
    })
  )

  const [configType, setConfigType] = useState('')

  const columnsTemplate: ColumnsType<CloudconfigTemplateDefaultCaseBindingChange> =
    [
      {
        title: 'Version',
        render: (_: any, record) => {
          return record.origin?.default_case?.version
        }
      },
      {
        title: 'Cloud Provider',
        render: (_: any, record) => {
          return record.origin?.default_case?.cloud_provider || 'Any'
        }
      },
      {
        title: 'Instance Type',
        render: (_: any, record) => {
          return record.origin?.default_case?.instance_type || 'Any'
        }
      },
      {
        title: 'Config Type',
        render: (_: any, record) => {
          return record.origin?.default_case?.config_type
        }
      },
      {
        title: 'Released Template',
        render: (_: any, record) => {
          return (
            <div>
              <Button type="link">
                <Link
                  target="_blank"
                  to={`/template/${record.modified?.template_id}`}
                >
                  {record.modified?.template_id}
                </Link>
              </Button>
            </div>
          )
        }
      }
    ]

  if (datas.length === 0) {
    return <></>
  }
  if (configType === '' && configTypes.length > 0) {
    setConfigType(configTypes[0]) // reset default config type after datas loaded.
  }

  return (
    <>
      <Divider></Divider>
      <Title level={5}>Released Templates</Title>

      <Select
        options={configTypes.map((v) => {
          return { label: v, value: v }
        })}
        value={configType}
        onChange={(e) => {
          setConfigType(e)
        }}
        dropdownMatchSelectWidth={false}
      ></Select>

      <Table<CloudconfigTemplateDefaultCaseBindingChange>
        columns={columnsTemplate}
        dataSource={datas.filter((v) => {
          return v.origin?.default_case?.config_type === configType
        })}
        size="small"
      ></Table>
    </>
  )
}

function ShowReleasedComponents({
  items
}: {
  items: CloudconfigDefaultConfigurationChangeItem[]
}) {
  const datas = items
    .filter(
      (v) =>
        v.type ===
        CloudconfigDefaultConfigurationChangeItemType.default_component_config
    )
    .map((v) => {
      return v.data?.default_component_config!
    })

  const columnsImage: ColumnsType<CloudconfigDefaultComponentChange> = [
    {
      title: 'Component',
      render: (_: any, record) => {
        return record.origin?.default_case?.component
      }
    },
    {
      title: 'Released Tag',
      render: (_: any, record) => {
        return record.modified?.image_tag
      }
    }
  ]

  if (datas.length === 0) {
    return <></>
  }

  return (
    <>
      <Divider></Divider>
      <Title level={5}>Released Components</Title>

      <Table<CloudconfigDefaultComponentChange>
        columns={columnsImage}
        dataSource={datas}
        size="small"
        pagination={false}
      ></Table>
    </>
  )
}

function EnvironmentReleaseDetail() {
  const { change_id, release_id } = useParams<{
    change_id: string
    release_id: string
  }>()

  const [reload, setReload] = useState(false)
  const [changeRelease, setChangeRelease] =
    useState<CloudconfigGetDefaultConfigurationChangeRelease>()
  const [cancelWindowOpen, setCancelWindowOpen] = useState(false)

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

  const CancelModalFormFields = () => {
    return (
      <>
        Are you sure to <b>Cancel</b> this release?
        <br></br>
        NOTE: It won't revert the staged data and only cancel this release.
      </>
    )
  }

  const handleCancel = async () => {
    try {
      await cloudConfigControllerCancelDefaultConfigurationChangeRelease(
        change_id,
        release_id
      )
      Modal.success({
        title: 'info',
        content: (
          <div>
            <p>Successfully Cancel</p>
          </div>
        ),
        onOk() {}
      })
      setCancelWindowOpen(false)
      setReload((pre) => !pre)
    } catch (error) {
      Modal.error({
        title: error.response.data.errcode,
        content: error.response.data.errmsg
      })
      setCancelWindowOpen(false)
      setReload((pre) => !pre)
    }
  }

  async function fetch() {
    try {
      const change_release_resp = (
        await cloudConfigControllerGetDefaultConfigurationChangeRelease(
          change_id,
          release_id,
          {
            with_released_items: true
          }
        )
      ).data
      setChangeRelease(change_release_resp)
    } catch (error) {
      Modal.error({
        title: error.response.data.errcode,
        content: error.response.data.errmsg
      })
    }
  }

  const columnsImage: ColumnsType<CloudconfigDefaultComponentChange> = [
    {
      title: 'Component',
      render: (_: any, record) => {
        return record.origin?.default_case?.component
      }
    },
    {
      title: 'Released Tag',
      render: (_: any, record) => {
        return record.modified?.image_tag
      }
    }
  ]

  return (
    <div>
      <Card
        title={<Title level={4}>{`Default Config Change Release`}</Title>}
        extra={
          <Space>
            <Button
              type="default"
              onClick={() => {
                setCancelWindowOpen(true)
              }}
              disabled={
                changeRelease?.release?.phase !==
                CloudconfigDefaultConfigurationChangeReleasePhase.approving
              }
            >
              Cancel
            </Button>
            &nbsp;
            <Button
              onClick={() => {
                setReload((pre) => !pre)
              }}
              icon={<ReloadOutlined />}
            ></Button>
          </Space>
        }
      >
        <Title level={5}>Basic Information</Title>
        <Descriptions>
          <Descriptions.Item label="ID" span={1}>
            {changeRelease?.release?.id}
          </Descriptions.Item>
          <Descriptions.Item label="Desciption" span={1}>
            {changeRelease?.release?.description}
          </Descriptions.Item>
          <Descriptions.Item label="Environment" span={1}>
            {changeRelease?.release?.environment}
          </Descriptions.Item>
          <Descriptions.Item label="Phase" span={1}>
            {changeRelease?.release?.phase}
          </Descriptions.Item>
          <Descriptions.Item label="Release At" span={1}>
            {toLocal(changeRelease?.release?.released_at)}
          </Descriptions.Item>
          <Descriptions.Item label="Release Number" span={1}>
            {changeRelease?.release?.release_number}
          </Descriptions.Item>
        </Descriptions>

        <ShowReleasedTemplates
          items={changeRelease?.released_items || []}
        ></ShowReleasedTemplates>

        <ShowReleasedComponents
          items={changeRelease?.released_items || []}
        ></ShowReleasedComponents>

        <Divider></Divider>
        {changeRelease?.release?.approval_id !== undefined ? (
          <ApprovalTable
            id={changeRelease?.release?.approval_id}
          ></ApprovalTable>
        ) : (
          <></>
        )}
      </Card>

      <ModalForm
        visible={!!cancelWindowOpen}
        name="Cancel Release"
        title={'Cancel Release'}
        getFields={() => {
          return <CancelModalFormFields />
        }}
        okText={'Confirm'}
        onSubmit={handleCancel}
        onCancel={() => {
          setCancelWindowOpen(false)
        }}
      />
    </div>
  )
}

export default EnvironmentReleaseDetail
