import { Alert, Button, Flex, Group, LoadingOverlay, Modal, Stack, Typography } from '@tidbcloud/uikit'
import { Form, FormSwitch } from '@tidbcloud/uikit/biz'
import { first } from 'lodash-es'
import { useEffect, useState } from 'react'
import { useFieldArray, useForm } from 'react-hook-form'

import { useCreateSystemEndpoint, useGetSystemEnpoint } from 'dbaas/services/dataservice'
import { DataservicesInternalDtoDataapiEndpointConfig } from 'dbaas/services/dataservice/interface'

import { useDataApiContext } from '../context'
import { useCreateEndpCallbackHandler } from '../helpers'
import { DataApp } from '../types'

type TMgmtEndpLibModal = { data_endpoints: DataservicesInternalDtoDataapiEndpointConfig[] }

export const MgmtEndpLibModal = ({ appId, onClose }: { appId: string; onClose: () => void }) => {
  const [confirmShow, setConfirmShow] = useState(false)

  const {
    orgId,
    projectId,
    getAppList,
    setEditApp,
    setEditEndpoint,
    editEndpointRef,
    setScrollEle,
    openedEndpList,
    setOpenedEndpList
  } = useDataApiContext()

  const { clearMessageRes } = useCreateEndpCallbackHandler()

  const form = useForm<TMgmtEndpLibModal>()

  const { control, reset, watch } = form

  const { fields } = useFieldArray({
    control: control,
    name: 'data_endpoints'
  })

  const dataEndpoints = watch('data_endpoints')

  const { data, isFetching } = useGetSystemEnpoint(orgId, projectId, appId, {
    query: {
      enabled: !!orgId && !!projectId && !!appId,
      refetchOnWindowFocus: false
    }
  })

  const originalDataEndpoints = data?.data?.data_endpoints

  useEffect(() => {
    reset({
      data_endpoints: originalDataEndpoints
    })
  }, [originalDataEndpoints])

  const isDirty = !originalDataEndpoints?.every((v, i) => v.is_enabled === dataEndpoints?.[i]?.is_enabled)

  const { mutateAsync, isLoading: createLoading } = useCreateSystemEndpoint()

  const handleSubmit = async (formValues: TMgmtEndpLibModal) => {
    const data_endpoints = originalDataEndpoints?.map((v, i) => {
      v.is_enabled = formValues.data_endpoints[i].is_enabled
      return v
    })
    const resp = await mutateAsync({
      orgId,
      projectId,
      appId,
      data: {
        data_endpoints
      }
    })
    if (resp.code === 200) {
      const appList = (await getAppList()) as DataApp[]
      const app = appList.find((v) => v.id === appId)

      if (data_endpoints?.some((v) => v.is_enabled)) {
        const ep = first(app?.endpoints)
        if (ep) {
          setEditEndpoint(ep)
          editEndpointRef.current = ep

          setEditApp(null)

          if (!openedEndpList.some((item) => item.id === ep.id)) {
            setOpenedEndpList(openedEndpList.concat(ep))
          }

          setScrollEle(ep)
        }
      } else {
        // removed system data
        const list = openedEndpList.filter((v) => !(`${v.dataappp_id}` === `${appId}` && v.type === 'system-data'))
        setOpenedEndpList(list)

        if (
          `${editEndpointRef.current?.dataappp_id}` === `${appId}` &&
          editEndpointRef.current?.type === 'system-data'
        ) {
          if (list.length) {
            setEditEndpoint(list[list.length - 1])
            editEndpointRef.current = list[list.length - 1]
            setEditApp(null)
          } else {
            setEditEndpoint(null)
            editEndpointRef.current = null
            setEditApp(app as DataApp)
          }
        }
      }

      onClose()
      clearMessageRes()
    } else {
      throw new Error(resp.message)
    }
  }

  const handleCloseModal = () => (isDirty ? setConfirmShow(true) : onClose())

  return (
    <>
      <Modal size={550} centered title="Manage Endpoint Library" opened={true} onClose={handleCloseModal}>
        <Form<TMgmtEndpLibModal>
          form={form}
          onSubmit={handleSubmit}
          onCancel={handleCloseModal}
          formMode="onChange"
          actionsProps={{
            confirmText: 'Save',
            disabled: !isDirty,
            confirmProps: {
              loading: createLoading
            }
          }}
        >
          <LoadingOverlay visible={isFetching} />
          <Typography variant="body-lg" mb={8}>
            Add or remove predefined system-provided endpoints.
          </Typography>
          <Stack mb={8}>
            {fields.map((field, index) => (
              <Flex justify="space-between" key={field.id}>
                Execute Query
                <FormSwitch
                  key={field.id}
                  name={`data_endpoints.${index}.is_enabled`}
                  onLabel="Added"
                  offLabel="Removed"
                  size="lg"
                  {...field}
                ></FormSwitch>
              </Flex>
            ))}
          </Stack>
          <Alert mb={16}>
            <Typography mb={24} variant="body-lg">
              By enabling this endpoint '/system/query', it offers the capabilities to execute any SQL statements.
              Unlike other custom endpoints, only properties of 'timeout' and 'max rows' can be customized for system
              endpoints.
            </Typography>
            <Typography variant="body-lg">
              Caution: This endpoint is powerful and versatile but can be potentially destructive. Use with discretion
              and ensure the queries are secure and well-considered to prevent unintended consequences.
            </Typography>
          </Alert>
          <Typography variant="body-lg">
            Any added/removed endpoints will be deployed to production immediately, which means the changed endpoints
            become accessible/inaccessible right after the 'Save' button is clicked.
          </Typography>
        </Form>
      </Modal>
      <Modal
        size={500}
        centered
        opened={confirmShow}
        onClose={onClose}
        withCloseButton={false}
        title="Managing Endpoint Library"
      >
        <Typography mb={24}>Any modifications made will be lost. Are you sure you want to cancel?</Typography>
        <Group justify="flex-end">
          <Button variant="default" onClick={() => setConfirmShow(false)}>
            No, Back to Manage Endpoint Library
          </Button>
          <Button onClick={onClose}>Yes, Cancel</Button>
        </Group>
      </Modal>
    </>
  )
}
