import { notifier } from '@tidbcloud/uikit'
import { ActionIcon, Anchor, Badge, Box, Button, Flex, HoverCard, Modal, Typography } from '@tidbcloud/uikit'
import { Form, FormTextInput } from '@tidbcloud/uikit/biz'
import { ProTable, MRT_ColumnDef } from '@tidbcloud/uikit/biz'
import { IconInfoCircle, IconLinkExternal01 } from '@tidbcloud/uikit/icons'
import { useEffect, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'

import TimeComponent from 'dbaas/components/TimeComponent'
import { useDataappReDeploy } from 'dbaas/services/dataservice'
import { EntityDataAppDeploymentLog } from 'dbaas/services/dataservice/interface'
import { eventTracking } from 'dbaas/utils/tracking'

import { useDataApiContext } from '../../context'

import Detail from './Detail'
import Diff from './Diff'

interface RedepolyFormValues {
  deploy_name: string
}

const DeploymentList = ({
  data,
  loading,
  fetch
}: {
  data: EntityDataAppDeploymentLog[]
  loading: boolean
  fetch: () => void
}) => {
  const { orgId, projectId, editApp, dataappDeployConfig } = useDataApiContext()
  const reDeployMutation = useDataappReDeploy()
  const [opened, setOpened] = useState(false)
  const [editData, setEditData] = useState<EntityDataAppDeploymentLog>()
  const [redeployOpened, setRedeployOpened] = useState(false)
  const formProps = useForm<RedepolyFormValues>({})
  const { setValue } = formProps

  const columns = useMemo<MRT_ColumnDef<EntityDataAppDeploymentLog>[]>(
    () => [
      {
        header: 'Changes',
        Header: () => {
          return <Typography pl={8}>Changes</Typography>
        },
        accessorFn: (column) => (
          <Box
            pl={8}
            sx={{
              maxWidth: 300,
              wordBreak: 'break-all'
            }}
          >
            <Typography
              variant="action-sm"
              fw={400}
              sx={{ cursor: 'pointer', overflow: 'hidden' }}
              onClick={() => {
                eventTracking('Dataservice deployment list change name clicked')
                setEditData(column)
                setOpened(true)
              }}
            >
              {column.name}
            </Typography>
          </Box>
        )
      },
      {
        header: 'Status',
        accessorFn: (column) => (
          <Flex align="center">
            <Badge variant="dot" color={getStatusColor(column.status || '')} sx={{ paddingLeft: 0 }}>
              {column.status}
            </Badge>
            {column.status === 'failed' && (
              <HoverCard width={200} position="top" withArrow shadow="md">
                <HoverCard.Target>
                  <ActionIcon aria-label="Status error message" variant="transparent">
                    <IconInfoCircle size={12} />
                  </ActionIcon>
                </HoverCard.Target>
                <HoverCard.Dropdown>
                  <Typography variant="body-sm" sx={{ wordBreak: 'break-all' }}>
                    {column.status_error_msg}
                  </Typography>
                </HoverCard.Dropdown>
              </HoverCard>
            )}
          </Flex>
        )
      },
      {
        header: 'Time',
        accessorFn: (column) => (
          <Typography variant="body-sm">
            <TimeComponent time={column.created_at!} />
          </Typography>
        )
      },
      {
        header: 'Origin',
        accessorFn: (column) => (
          <Box>
            {column.origin === 'UI' ? (
              <Typography variant="body-sm">TiDB Cloud UI</Typography>
            ) : (
              <>
                {!column?.commit_id ? (
                  '-'
                ) : (
                  <Anchor href={column?.diff_url} target="_blank">
                    <Flex align="center">
                      GitHub: {column?.commit_id.slice(0, 7)}
                      <ActionIcon aria-hidden c="peacock.7">
                        <IconLinkExternal01 size={16} />
                      </ActionIcon>
                    </Flex>
                  </Anchor>
                )}
              </>
            )}
          </Box>
        )
      },
      {
        header: 'Action',
        accessorFn: (column) => (
          <Button
            variant="default"
            size="compact-xs"
            loading={editData?.id === column.id && reDeployMutation.isLoading}
            data-mp-event="Dataservice re-deploy button clicked"
            onClick={() => {
              setEditData(column)
              setRedeployOpened(true)
            }}
          >
            Re-deploy
          </Button>
        )
      }
    ],
    []
  )

  const redeploy = async (values: RedepolyFormValues) => {
    try {
      const res = await reDeployMutation.mutateAsync({
        orgId,
        projectId,
        appId: `${editApp?.id}`,
        logId: `${editData?.id}`,
        data: {
          deploy_name: values.deploy_name || 'Redeploy from Data App'
        }
      })

      if (res.code !== 200) {
        notifier.error(res.message)
      } else {
        fetch()
        setRedeployOpened(false)
      }
    } catch (_e) {}
  }

  const getStatusColor = (status: string) => {
    switch (status) {
      case 'failed':
        return 'red'
      case 'success':
        return 'green'
      default:
        return 'peacock'
    }
  }

  useEffect(() => {
    if (redeployOpened) {
      setTimeout(() => {
        setValue('deploy_name', `[Redeploy]${editData?.name}` || '')
      }, 0)
    }
  }, [redeployOpened])

  return (
    <>
      <ProTable
        columns={columns}
        loading={loading}
        emptyMessage="No change log"
        data={loading ? [] : data}
        mantinePaperProps={{ mx: 16 }}
      />

      <Detail
        opened={opened}
        data={editData}
        close={() => {
          setOpened(false)
          fetch()
        }}
        onRename={(name: string) => {
          setEditData({
            ...editData,
            name
          })
        }}
        onRedeploy={() => {
          setRedeployOpened(true)
        }}
      />

      <Modal
        title={
          <Flex align="center">
            <Typography>Re-deploy Change</Typography>
            {editData?.commit_id && (
              <Box
                sx={(theme) => ({
                  fontSize: 12,
                  fontWeight: 700,
                  backgroundColor: theme.colors.carbon[2],
                  color: theme.colors.carbon[8],
                  border: `1px solid ${theme.colors.carbon[5]}`,
                  padding: '2px 6px',
                  borderRadius: 4,
                  marginLeft: 8
                })}
              >
                {editData.commit_id}
              </Box>
            )}
          </Flex>
        }
        opened={redeployOpened}
        onClose={() => setRedeployOpened(false)}
        centered
        trapFocus={false}
        size="80vw"
      >
        <Form
          layout="none"
          actionsProps={{
            confirmText: `Re-deploy ${dataappDeployConfig?.enable_automatic_deployment ? 'and Push to GitHub' : ''}`
          }}
          form={formProps}
          onSubmit={redeploy}
          onCancel={() => setRedeployOpened(false)}
        >
          <FormTextInput
            name="deploy_name"
            label="Change Description"
            placeholder="Enter some change description for deploying record"
            mb={16}
          />

          <Diff type="redeploy" logId={`${editData?.id}`} />
        </Form>
      </Modal>
    </>
  )
}

export default DeploymentList
