import { Button, Card, Divider, Group, Modal, ScrollArea, SimpleGrid, Stack, Text, Typography } from '@tidbcloud/uikit'
import { PropertyCard } from '@tidbcloud/uikit/biz'
import { useMount } from 'ahooks'
import { capitalize } from 'lodash-es'
import { observer } from 'mobx-react'
import { useMemo, useState } from 'react'
import { useFormContext } from 'react-hook-form'
import { useHistory } from 'react-router-dom'

import { FormErrorMessage } from 'dbaas/components/Form'
import { EssentialDMTypeOptions } from 'dbaas/features/DataMigration'
import type { EssentialDMFormData } from 'dbaas/screens/DataMigration/CreateDataMigrationEssential.types'
import SelectedObjects from 'dbaas/screens/DataMigration/DMJobDetail/SelectedObject'
import type { EssentialStep1FormData } from 'dbaas/screens/DataMigration/steps/Step1/EssentialDMStep1'
import type { EssentialStep2FormData } from 'dbaas/screens/DataMigration/steps/Step2/EssentialDMStep2'
import { useMigrationServiceCreateTask } from 'dbaas/services/api-clients/legacy/serverless'
import type { MigrationServiceCreateTaskBody } from 'dbaas/services/api-clients/legacy/serverless/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

export type EssentialStep4FormData = Pick<
  EssentialStep1FormData,
  | 'name'
  | 'data_source'
  | 'connect_method'
  | 'connect_method_display_name'
  | 'host'
  | 'service_endpoint'
  | 'port'
  | 'username'
  | 'ssl'
  | 'cluster_username'
  | 'cluster_password'
> &
  Pick<
    EssentialStep2FormData,
    | 'migration_mode'
    | 'selectObjectMethod'
    | 'sources'
    | 'import_mode'
    | 'precheckId'
    | 'full_instance_migrate'
    | 'migration_mode'
  >

const Step4 = ({ onCancel, onGoPrev }: { onCancel: () => void; onGoPrev: () => void }) => {
  const {
    store: { tenantData, activeProjectId, currentCluster }
  } = useStores()
  const { handleSubmit, watch, getValues } = useFormContext<EssentialDMFormData>()
  const history = useHistory()
  const [modalOpen, setModalOpen] = useState(false)
  const [errorMessage, setErrorMessage] = useState('')
  const createTask = useMigrationServiceCreateTask()

  const formData = getValues() as EssentialStep4FormData
  const migration_mode = watch('migration_mode')

  const jobType = useMemo(() => {
    return EssentialDMTypeOptions.find((option) => option.value === migration_mode)?.label || ''
  }, [migration_mode])

  const onSubmit = async (formData: EssentialStep4FormData) => {
    try {
      const payload: MigrationServiceCreateTaskBody = {
        name: formData.name,
        sources: formData.sources,
        target: {
          user: formData.cluster_username,
          password: formData.cluster_password
        },
        mode: formData.migration_mode,
        full_instance_migration: formData.full_instance_migrate
      }

      await createTask.mutateAsync({
        orgId: tenantData.id,
        projectId: activeProjectId,
        clusterId: currentCluster?.id!,
        data: payload
      })

      eventTracking('Choose a spec and start DataMigration job succeed')

      history.push(`/clusters/${currentCluster?.id}/data-migration`)
    } catch (e) {
      setErrorMessage(getErrorMessage(e))
    }
  }

  useMount(() => {
    eventTracking('Enter the step to choose the spec of DataMigration job')
  })

  return (
    <Card withBorder shadow="none" p={0}>
      <form onSubmit={handleSubmit((values) => onSubmit(values as EssentialStep4FormData))}>
        <Stack m={24}>
          <Typography variant="headline-sm">Job Configuration</Typography>

          <Stack>
            <PropertyCard.Item label="Name">
              <Typography c="carbon.9">{formData.name}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="Type">
              <Typography c="carbon.9">{jobType}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="Precheck">
              <Typography c="carbon.9">{formData.precheckId ? 'Completed' : 'Not Run'}</Typography>
            </PropertyCard.Item>
          </Stack>
        </Stack>

        <Divider />

        <Stack m={24}>
          <Typography variant="headline-sm">Source Connection Profile</Typography>

          <SimpleGrid cols={2}>
            <PropertyCard.Item label="Data Source">
              <Typography c="carbon.9">{formData.data_source}</Typography>
            </PropertyCard.Item>

            {formData.connect_method?.includes('private') ? (
              <PropertyCard.Item label="Endpoint Service Name" labelProps={{ miw: 140 }}>
                <Typography c="carbon.9">{formData.service_endpoint}</Typography>
              </PropertyCard.Item>
            ) : (
              <PropertyCard.Item label="Host" labelProps={{ miw: 140 }}>
                <Typography c="carbon.9">{formData.host}</Typography>
              </PropertyCard.Item>
            )}

            <PropertyCard.Item label="Port">
              <Typography c="carbon.9">{formData.port}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="Connectivity Method" labelProps={{ miw: 140 }}>
              <Typography c="carbon.9">{formData.connect_method_display_name}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="Username">
              <Typography c="carbon.9">{formData.username}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="SSL/TLS" labelProps={{ miw: 140 }}>
              <Typography c="carbon.9">{formData.ssl ? 'Enabled' : 'Disabled'}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="Selected Objects">
              {formData.selectObjectMethod === 'customize' ? (
                <a onClick={() => setModalOpen(true)}>Show Detail</a>
              ) : (
                <Typography c="carbon.9">All</Typography>
              )}
            </PropertyCard.Item>

            <PropertyCard.Item label="Import Mode" labelProps={{ miw: 140 }}>
              <Typography c="carbon.9">{formData.import_mode ? capitalize(formData.import_mode) : '-'}</Typography>
            </PropertyCard.Item>
          </SimpleGrid>
        </Stack>

        <Divider />

        <Stack m={24}>
          <Typography variant="headline-sm">Target Connection Profile</Typography>

          <SimpleGrid cols={2}>
            <PropertyCard.Item label="Region">
              <Typography c="carbon.9">{currentCluster?.regionDisplayName}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="Cluster ID">
              <Typography c="carbon.9">{currentCluster?.id}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="Cluster Name">
              <Typography c="carbon.9">{currentCluster?.displayName}</Typography>
            </PropertyCard.Item>

            <PropertyCard.Item label="Username">
              <Typography c="carbon.9">{formData.cluster_username}</Typography>
            </PropertyCard.Item>
          </SimpleGrid>
        </Stack>

        <Divider />

        <FormErrorMessage message={errorMessage} />

        <Group m={24} justify="flex-end" gap={12}>
          <Button variant="default" type="button" onClick={onCancel} data-mp-event="mp-cancel-1691461016888">
            Cancel
          </Button>

          <Button variant="outline" type="button" onClick={onGoPrev} data-mp-event="mp-previous-1691461016891">
            Previous
          </Button>

          <Button type="submit" loading={createTask.isLoading} data-mp-event="mp-createjobandstart-1691461016892">
            Create Job and Start
          </Button>
        </Group>
      </form>

      <Modal
        opened={modalOpen}
        centered
        size="xl"
        title={
          <Text fw={700} fz={20}>
            Selected Migration Objects
          </Text>
        }
        onClose={() => setModalOpen(false)}
      >
        <ScrollArea.Autosize mah={300}>
          <SelectedObjects rules={formData.sources?.[0]?.ba_rules} />
        </ScrollArea.Autosize>
      </Modal>
    </Card>
  )
}

export const EssentialDMStep4 = observer(Step4)
