import { Alert, Button, Form, FormInstance, Modal, Typography } from 'antd'
import Table, { ColumnsType } from 'antd/lib/table'
import {
  Dispatch,
  SetStateAction,
  useCallback,
  useEffect,
  useMemo,
  useState
} from 'react'

import {
  CloudconfigChangeComponentReq,
  CloudconfigClusterType,
  CloudconfigComponent,
  CloudconfigConfiguration,
  CloudconfigConfigurationComponents
} from 'apiClient/services/devops/interface'
import ModalForm from 'components/ModalForm'

import {
  CreateCloudConfigController,
  GetCloudConfigController,
  PreviewCloudConfigController,
  PreviewParam
} from '../../Configs/CurrentConfig/Current'

import ImageTagForm, { ImageTagType } from './ImageTagForm'

const ImageForm = ({
  getAPI,
  getParam,
  cacheAPI,
  cacheParam,
  type,
  clusterType,
  setComponentsReq
}: {
  getAPI: GetCloudConfigController
  getParam: unknown
  cacheAPI: GetCloudConfigController
  cacheParam: unknown
  type: string
  clusterType?: CloudconfigClusterType
  setComponentsReq: Dispatch<
    SetStateAction<CloudconfigChangeComponentReq[] | undefined>
  >
}) => {
  const [reload, setReload] = useState(false)
  const [configuration, setConfiguration] = useState<CloudconfigConfiguration>()
  const [components, setComponents] =
    useState<CloudconfigConfigurationComponents>()
  const [changeable, setChangeable] = useState<{
    changeable: boolean
    reason: string
  }>()
  const [modalEditInitial, setModalEditInitial] = useState<{
    name?: string
    image_tag?: string
  }>()
  const [modalEdit, setModalEdit] = useState(false)

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

  async function fetch() {
    try {
      const s = (await getAPI(getParam)).data
      const c = (await cacheAPI(cacheParam)).data
      setConfiguration(s.configuration)
      setComponents(c.configuration.components)
      // setComponentsReq(componentsToReq(c.configuration.components))
      setChangeable(s.changeable)
    } catch (error) {
      //todo: get vs preview
      Modal.error({
        title: error.response.data.errcode,
        content: error.response.data.errmsg
      })
    }
  }

  const columns: ColumnsType<UnifyColumn> = useMemo(
    () => [
      {
        title: 'Component',
        width: 380,
        render: (_: any, record) => {
          return (
            <div>
              <div>{record.component.name}</div>
              {clusterType === 'SHARED_POOL' &&
                record.key.toLowerCase() === 'tidb' && (
                  <Typography.Text
                    style={{
                      color: '#fa8c16',
                      display: 'block',
                      fontSize: 13,
                      lineHeight: '18px',
                      maxWidth: 360,
                      whiteSpace: 'normal'
                    }}
                  >
                    Modifies the default TiDB image for new logical clusters;
                    <br />
                    existing logical clusters are unaffected.
                  </Typography.Text>
                )}
            </div>
          )
        }
      },
      {
        title: 'Version',
        render: (_: any, record) => {
          return record.component.version || configuration?.version || '-'
        }
      },
      {
        title: 'Base Image',
        render: (_: any, record) => {
          return record.component.base_image
        }
      },
      {
        title: 'Image Tag',
        render: (_: any, record) => {
          let origin =
            configuration?.components![record.key].effective_image_tag

          return origin === record.component.effective_image_tag ? (
            origin
          ) : (
            <>
              <p style={{ color: 'red' }}>
                {record.component.effective_image_tag}
              </p>
            </>
          )
        }
      },
      {
        title: 'Action',
        key: 'action',
        render: (_: any, record) => (
          <div>
            <a
              onClick={() => {
                setModalEditInitial({
                  name: record.component.name,
                  image_tag: record.component.effective_image_tag
                })
                setModalEdit(true)
              }}
            >
              Edit
            </a>
          </div>
        )
      }
    ],
    [clusterType, configuration, components]
  )

  const renderEditParamFields = useCallback(
    (form: FormInstance) => {
      form.setFieldsValue({
        name: modalEditInitial?.name,
        image_tag: modalEditInitial?.image_tag
      })
      return <ImageTagForm {...modalEditInitial} />
    },
    [modalEdit, configuration, modalEditInitial]
  )

  const hasDowngradeWarning = useMemo(() => {
    if (!components || !configuration?.components) return false
    for (const key of Object.keys(components)) {
      const originalVersion = configuration.components[key]?.effective_image_tag
      const currentVersion = components[key]?.effective_image_tag
      if (
        originalVersion &&
        currentVersion &&
        originalVersion !== currentVersion
      ) {
        const v1Parts = currentVersion.split('.')
        const v2Parts = originalVersion.split('.')
        let isLess = false
        const len = Math.max(v1Parts.length, v2Parts.length)
        for (let i = 0; i < len; i++) {
          const num1 = parseInt(v1Parts[i]?.replace(/[^\d]/g, '') || '0', 10)
          const num2 = parseInt(v2Parts[i]?.replace(/[^\d]/g, '') || '0', 10)
          if (num1 < num2) {
            isLess = true
            break
          } else if (num1 > num2) {
            break
          }
        }
        if (isLess) {
          return true
        }
      }
    }
    return false
  }, [components, configuration])

  const handleEdit = useCallback(
    (payload: ImageTagType) => {
      let tmp = components || {}

      tmp[payload.name].effective_image_tag = payload.image_tag
      tmp[payload.name].overwrite_image_tag = payload.image_tag
      setComponents({ ...tmp })
      setComponentsReq(componentsToReq(tmp))
      setModalEdit(false)
    },
    [components]
  )

  const handleCancelEdit = useCallback(() => {
    setModalEdit(false)
  }, [])

  return (
    <>
      <Table
        dataSource={mapToList(components || {})}
        columns={columns}
        pagination={{ pageSize: 10, position: ['bottomLeft'] }}
      />
      {hasDowngradeWarning && (
        <Alert
          type="warning"
          showIcon
          message="The modified version is lower than the current version. Please make sure this is what you want."
          style={{ marginTop: 16 }}
        />
      )}
      <Button type="primary"></Button>
      <ModalForm<ImageTagType>
        visible={!!modalEdit}
        name="editImage"
        title={'Edit Image'}
        getFields={renderEditParamFields}
        onSubmit={handleEdit}
        onCancel={handleCancelEdit}
        width={600}
        destoryOnClose={true}
        okText="OK"
      ></ModalForm>
    </>
  )
}

const mapToList = (m: CloudconfigConfigurationComponents) => {
  var l: UnifyColumn[] = []
  Object.keys(m).forEach((key) => {
    const v = m[key]
    l.push({ key: key, component: v })
  })
  return l
}
type UnifyColumn = {
  key: string
  component: CloudconfigComponent & { version?: string }
}

const componentsToReq = (c: CloudconfigConfigurationComponents | undefined) => {
  let res: CloudconfigChangeComponentReq[] = []
  if (c !== undefined) {
    Object.keys(c).forEach((key) => {
      const v = c[key]
      res.push({
        component: key,
        overwrite_image_tag: { to_image_tag: v.overwrite_image_tag }
      })
    })
  }
  return res
}

export default ImageForm
