import { Accordion, Input, notifier, Tooltip } from '@tidbcloud/uikit'
import { Alert, Box, Divider, Flex, Modal, Typography } from '@tidbcloud/uikit'
import { Form, FormCheckbox, FormSelect, FormSwitch, FormTextInput, TimePicker } from '@tidbcloud/uikit/biz'
import { IconInfoCircle } from '@tidbcloud/uikit/icons'
import { isNil } from 'lodash-es'
import { observer } from 'mobx-react'
import { useState } from 'react'
import { useForm } from 'react-hook-form'

import { ProjectType } from 'dbaas/features/Project'
import { utcOffsetToTz } from 'dbaas/screens/OrgSettings/features/General/helpers'
import { dayList } from 'dbaas/screens/Project/MaintenanceWindow/const'
import { CentralProject } from 'dbaas/services'
import { updateProject, createProject } from 'dbaas/services'
import { maintenanceServiceUpdateMaintenanceWindow } from 'dbaas/services/api-clients/v2023/dedicated/v1beta1'
import { pickErrorResponse } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'
import { projectNameRules } from 'dbaas/utils/validationRules'

type FormValues = {
  name: string
  enable_xaccount_deploy?: boolean
  create_for_dedicated_clusters?: boolean
  enable_cmek: boolean
  maintenanceDay?: string
}

export type ProjectCreateMode = 'tidbx-or-dedicated' | 'dedicated-only' | 'tidbx-only'

interface ProjectEditModalProps {
  project: CentralProject | undefined
  opened: boolean
  onClose: () => void
  onFinish?: () => void
  createMode?: ProjectCreateMode
}

interface ProjectEditFormlProp {
  project: CentralProject | undefined
  onClose: () => void
  onFinish: (() => void) | undefined
  createMode: ProjectCreateMode
}

const ProjectEditForm: React.FC<React.PropsWithChildren<ProjectEditFormlProp>> = observer(
  ({ project, onClose, onFinish, createMode }) => {
    const {
      actions,
      store: {
        tenantData: { id: orgId, timezone }
      }
    } = useStores()

    const utcoffset = utcOffsetToTz(timezone || 0)
    const userSetTimezone = `UTC${utcoffset === '+00:00' ? '±00:00' : utcoffset}`
    const [hour, setHour] = useState('03')
    const [minute, setMinute] = useState('00')
    const wednesday = '3'

    const defaultValues = {
      name: project?.name || '',
      enable_xaccount_deploy: false,
      create_for_dedicated_clusters: !project && createMode === 'dedicated-only',
      enable_cmek: project?.aws_cmek_enabled ?? false,
      maintenanceDay: !project ? wednesday : ''
    }

    const formProps = useForm<FormValues>({
      defaultValues
    })

    const { watch } = formProps

    const enableCmek = watch('enable_cmek')
    const name = watch('name')
    const maintenanceDay = watch('maintenanceDay')
    const isTidbxOnlyCreate = !project && createMode === 'tidbx-only'
    const createForDedicatedClusters = project
      ? true
      : isTidbxOnlyCreate
        ? false
        : createMode === 'dedicated-only' || !!watch('create_for_dedicated_clusters')

    const isUpdate = !!project

    const handleSubmit = async (values: FormValues) => {
      const pName = values.name.trim()
      let notifyMsg
      if (isUpdate) {
        await updateProject(orgId, project.id, {
          name: pName,
          org_id: orgId,
          project_id: project.id
        })
        notifyMsg = <Typography>Project has been updated successfully</Typography>
      } else {
        const projectType = isTidbxOnlyCreate
          ? ProjectType.TIDBX
          : createForDedicatedClusters
            ? ProjectType.DEDICATED
            : ProjectType.TIDBX
        const res = await createProject(orgId, {
          name,
          org_id: orgId,
          enable_xaccount_deploy: !!values.enable_xaccount_deploy,
          aws_cmek_enabled: projectType === ProjectType.DEDICATED ? values.enable_cmek : false,
          type: projectType
        })
        notifyMsg = <Typography>Project has been created successfully</Typography>

        if (projectType === ProjectType.DEDICATED) {
          try {
            res.id &&
              (await maintenanceServiceUpdateMaintenanceWindow(
                `project-${res.id}`,
                {
                  dayHour: +hour,
                  hourMinute: +minute,
                  weekDay: values.maintenanceDay ? +values.maintenanceDay : 0
                },
                {
                  orgId: orgId,
                  projectId: res.id
                }
              ))
          } catch (err: any) {
            const { message } = pickErrorResponse(err)
            if (message.includes('permission')) {
              notifier.error(
                'Maintenance Window is temporarily unavailable due to legacy architecture. Please contact technical support for more information.'
              )
            } else {
              notifier.error(message)
            }
          }
        }
      }

      notifier.info(notifyMsg)

      // fetch user profile to update userProfile.projects in store
      actions.fetchUserProfileV2()

      onFinish?.()
      onClose()
    }

    return (
      <Form<FormValues>
        form={formProps}
        onSubmit={handleSubmit}
        onCancel={onClose}
        stopPropagation
        actionsProps={{
          mx: -24,
          pt: 16,
          pr: 24,
          sx: (theme) => ({
            borderTop: `1px solid ${theme.colors.carbon[4]}`
          }),
          confirmProps: {
            disabled: !(name || '').trim().length || (!project && createForDedicatedClusters && !maintenanceDay),
            'data-mp-event': `${project ? 'Edit' : 'Create'} Project Confirm Button Clicked`
          },
          cancelProps: {
            'data-mp-event': `${project ? 'Edit' : 'Create'} Project Cancel Button Clicked`
          }
        }}
      >
        <FormTextInput
          name="name"
          label="Project Name"
          placeholder="Project-1"
          rules={projectNameRules}
          data-autofocus
        />
        {!project && createMode === 'tidbx-or-dedicated' && !isTidbxOnlyCreate && (
          <FormCheckbox
            size="xs"
            name="create_for_dedicated_clusters"
            styles={{ body: { alignItems: 'center' } }}
            label={
              <Typography fw={500} c="carbon.8">
                Create for Dedicated Clusters
              </Typography>
            }
          />
        )}

        {!isUpdate && createForDedicatedClusters && !isTidbxOnlyCreate && (
          <>
            <Divider my={10} />
            <Flex justify="space-between">
              <Typography variant="title-md">Customer-Managed Encryption Keys (CMEK)</Typography>
              <Tooltip
                disabled={isNil(project)}
                label="It is not supported to enable or disable CMEK for an existing project."
              >
                <Box>
                  <FormSwitch disabled={!isNil(project)} name="enable_cmek" />
                </Box>
              </Tooltip>
            </Flex>
            <Typography variant="body-lg">
              CMEK allow you to protect data at rest in your TiDB Cloud Dedicated cluster.
            </Typography>
            {enableCmek && isNil(project) && (
              <Alert color="peacock" icon={<IconInfoCircle size={14} />}>
                After enabling CMEK, due to security restrictions, this project can only create dedicated tier clusters,
                and all clusters must use CMEK for encryption. Currently, there is no option to enable/disable CMEK
                later, and once created, CMEK cannot be turned on/off again.
              </Alert>
            )}
            <Box>
              <Divider pt={16} mt={16} />
              <Accordion
                styles={{
                  item: { border: 'none' },
                  control: {
                    padding: 0
                  },
                  chevron: { marginLeft: 32 },
                  content: {
                    padding: 0
                  }
                }}
              >
                <Accordion.Item value="maintenanceWindow">
                  <Accordion.Control>
                    <Box>
                      <Typography variant="title-md">Maintenance Window Setting</Typography>
                      <Typography>
                        Maintenance Window will be enabled by default to perform essential maintenance tasks when needed
                        to ensure the service level of TiDB Cloud Dedicated. Learn more about{' '}
                        <a
                          href="https://docs.pingcap.com/tidbcloud/configure-maintenance-window"
                          target="_blank"
                          rel="noreferrer"
                        >
                          Maintenance Window
                        </a>
                        .
                      </Typography>
                    </Box>
                  </Accordion.Control>
                  <Accordion.Panel>
                    <Flex
                      mt={8}
                      gap={24}
                      styles={{
                        root: {
                          '.mantine-Popover-dropdown': {
                            '.mantine-ScrollArea-root': {
                              '&:last-child': {
                                display: 'none'
                              }
                            }
                          }
                        }
                      }}
                    >
                      <FormSelect
                        name="maintenanceDay"
                        required
                        placeholder="Select day"
                        data={dayList.map((v, i) => ({ label: `Every ${v}`, value: i.toString() }))}
                      />

                      <TimePicker
                        sx={{ flex: 1 }}
                        withinPortal={false}
                        withArrow={false}
                        value={`${hour}:${minute}:00`}
                        onChange={(v) => {
                          const time = v.split(':')
                          if (time.length === 3) {
                            setHour(time[0])
                            setMinute(time[1])
                          }
                        }}
                        minTime="00:00:00"
                        maxTime="23:59:59"
                      />
                      <Input value={userSetTimezone} disabled />
                    </Flex>
                  </Accordion.Panel>
                </Accordion.Item>
              </Accordion>
            </Box>
          </>
        )}
      </Form>
    )
  }
)

export const ProjectEditModal: React.FC<React.PropsWithChildren<ProjectEditModalProps>> = observer(
  ({ opened = false, onClose, onFinish, project, createMode = 'dedicated-only' }) => {
    return (
      <Modal
        centered
        size="lg"
        title={project ? 'Edit Project' : 'Create Project'}
        opened={opened}
        onClose={onClose}
        styles={{ body: { paddingBottom: 16 } }}
      >
        <ProjectEditForm project={project} onClose={onClose} onFinish={onFinish} createMode={createMode} />
      </Modal>
    )
  }
)

export default ProjectEditModal
