import React, { useEffect, useMemo, useState } from 'react'

import { Divider, Modal, Typography } from 'antd'
import useSWR from 'swr'

import { ClusterFileMeta, CommonTaskStatus } from '@clinic/client'
import { getClusterDataStatus, getFileSize, rebuildClusterData } from '~/api'
import LoadingSpin from '~/components/LoadingSpin'
import { useMutation } from '~/hooks/use-mutation'
import { clusterDetailTelemetry } from '~/telemetry'
import { formatDateTime } from '~/utils/date-time'

import { DetailItemCard } from '../components/DetailItemCard'
import { ItemModalProps, ItemType } from './types'

const DownloadModalBody: React.FC<ItemModalProps> = ({
  oid,
  cid,
  timeRange
}) => {
  const { start, end } = timeRange
  const itemType = ItemType.Download

  // invalidate the cache
  const now = useMemo(() => new Date().valueOf(), [])
  const {
    data: dataStatusRes,
    error,
    mutate
  } = useSWR(
    [`/orgs/${oid}/clusters/${cid}/data_status`, start, end, itemType, now],
    () => getClusterDataStatus(oid, cid, start, end, ItemType.Download)
  )
  const loading = !dataStatusRes && !error

  const { run: runRebuildClusterData } = useMutation(rebuildClusterData)

  const [itemsFileSize, setItemsFilesSize] = useState<
    Record<string, ClusterFileMeta>
  >({})

  useEffect(() => {
    function updateFileSizes(itemId: string, fileMeta: ClusterFileMeta) {
      setItemsFilesSize((pre) => {
        const sizes = { ...pre }
        sizes[itemId] = fileMeta
        return sizes
      })
    }

    dataStatusRes?.data.items?.forEach((item) => {
      const sizeInfo = itemsFileSize[item.itemID!]
      if (!sizeInfo || (!sizeInfo.briefSize && item.status === 100)) {
        getFileSize(oid, cid, item.itemID!)
          .then((res) => {
            updateFileSizes(item.itemID!, res.data)
          })
          .catch((err) => console.log(err))
      }
    })
  }, [dataStatusRes, oid, cid, itemsFileSize])

  function handleDataItem(i: CommonTaskStatus) {
    if (i.status === -1) {
      Modal.confirm({
        title: 'Do you want to rebuild the data?',
        content: 'The data is cold, need to rebuild before ready',
        onOk: () => {
          runRebuildClusterData(
            {
              oid,
              cid,
              rebuild: { dataType: ItemType.Download, itemID: i.itemID }
            },
            function () {
              mutate()
            }
          )
        }
      })
    } else if (i.status === 0) {
      Modal.info({
        title: 'Data rebuild is queued',
        content: 'It may need several minutes to start rebuilding'
      })
      mutate()
    } else if (i.status === -2) {
      Modal.info({
        title: 'Rebuild failed or data expired',
        content: `Rebuild failed or data expired`
      })
      mutate()
    } else if (i.status! < 100) {
      Modal.info({
        title: 'The data is still rebuilding',
        content: `Please wait untill the data is ready (process: ${i.status}%)`
      })
      mutate()
    } else {
      // i.status === 100
      // download
      window.location.href = `/clinic/api/v1/orgs/${oid}/clusters/${cid}/downloadConf/${i.itemID}`
    }
  }

  if (loading) {
    return (
      <div className='text-center'>
        <LoadingSpin />
      </div>
    )
  }

  // download
  return (
    <div className='flex flex-col items-center'>
      {dataStatusRes?.data.items?.map((i) => (
        <div key={i.itemID} className='flex flex-col items-center pb-2'>
          <div>
            {formatDateTime(i.startTime!)} - {formatDateTime(i.endTime!)}
          </div>
          <div>
            <a
              href={`/clinic/api/v1/orgs/${oid}/clusters/${cid}/download/${i.itemID}`}
              onClick={() =>
                clusterDetailTelemetry.clickDownloadItem(i.itemID!, 'full')
              }
            >
              <Typography.Text
                style={{ width: 150 }}
                ellipsis={{ tooltip: itemsFileSize[i.itemID!]?.filename }}
              >
                {itemsFileSize[i.itemID!]?.filename}
              </Typography.Text>

              {itemsFileSize[i.itemID!]?.totalSize &&
                ` (${itemsFileSize[i.itemID!].totalSize}) `}
            </a>
            <Divider type='vertical' />
            <a
              onClick={() => {
                clusterDetailTelemetry.clickDownloadItem(
                  i.itemID!,
                  'without_logs_metrics'
                )
                handleDataItem(i)
              }}
            >
              Without Logs {'&'} Metrics
              {itemsFileSize[i.itemID!]?.briefSize &&
                ` (${itemsFileSize[i.itemID!].briefSize}) `}
            </a>
          </div>
        </div>
      ))}
    </div>
  )
}

export const DownloadModal: React.FC<ItemModalProps> = ({
  oid,
  cid,
  timeRange
}) => {
  const name = 'Download Data'
  const [modalVisible, setModalVisible] = useState(false)
  return (
    <>
      <DetailItemCard
        name={name}
        onClick={() => {
          clusterDetailTelemetry.clickDetailItem(name)
          setModalVisible(true)
        }}
      />

      <Modal
        visible={modalVisible}
        footer={null}
        onCancel={() => setModalVisible(false)}
        title={name}
        destroyOnClose={true}
      >
        <DownloadModalBody
          oid={oid}
          cid={cid}
          timeRange={timeRange}
          onClose={() => setModalVisible(false)}
        />
      </Modal>
    </>
  )
}
