import { zodResolver } from '@hookform/resolvers/zod'
import { notifier } from '@tidbcloud/uikit'
import { observer } from 'mobx-react'
import { useCallback, useId, useMemo } from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import { useQueryClient } from 'react-query'

import {
  invalidateCapacityLimitsQueries,
  PREMIUM_MAX_RCU_FALLBACK,
  PREMIUM_MIN_RCU,
  useCapacityLimits
} from 'dbaas/screens/NextGen/my-tidb-creation/shared/premium-byoc/capacity/use-capacity-limits'
import { createPremiumByocFormSchema } from 'dbaas/screens/NextGen/my-tidb-creation/shared/premium-byoc/schema'
import { PremiumByocFormValue } from 'dbaas/screens/NextGen/my-tidb-creation/shared/premium-byoc/types'
import { useCreateTidb } from 'dbaas/screens/NextGen/my-tidb-creation/shared/premium-byoc/use-create-tidb'
import { useCreateResourceRoleState } from 'dbaas/screens/NextGen/shared/access/create-resource-role'
import {
  Commonv1beta1ServicePlan,
  V1beta1RegionCloudProvider
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import useStores from 'dbaas/stores/useStores'

import { TwoPaneLayout } from '../../layout/TwoPaneLayout'
import { useVirtualProjectId } from '../../shared/use-virtual-project-id'

import { PremiumForm } from './PremiumForm'
import { PremiumSummary } from './PremiumSummary'

interface PremiumCreationProps {
  header: React.ReactNode
  planSelector: React.ReactNode
  active: boolean
}

export const PremiumCreation = observer(({ header, planSelector, active }: PremiumCreationProps) => {
  const {
    store: {
      lastVisitLocation: { orgId }
    }
  } = useStores()
  const virtualProjectId = useVirtualProjectId()
  const { requiresProjectSelection, isOrgOwner, ownerProjects } = useCreateResourceRoleState()
  const eligibleProjects = useMemo(
    () => ownerProjects.filter((project) => !project.aws_cmek_enabled && project.type === 'tidbx'),
    [ownerProjects]
  )

  const servicePlan = Commonv1beta1ServicePlan.Premium
  const formMethods = useForm<PremiumByocFormValue>({
    mode: 'onChange',
    defaultValues: {
      projectId: '',
      cloudProvider: undefined,
      regionId: '',
      name: '',
      maxRcu: 20000,
      highAvailabilityType: 'REGIONAL',
      dualLayerDataEncryption: {
        encrypted: false,
        keyType: 'service-managed',
        awsCmek: {
          accountId: '',
          kmsKeyArn: ''
        },
        aliyunCmek: {
          accountId: '',
          kmsKeyArn: ''
        }
      }
    },
    resolver: (values, ctx, options) => {
      const resolvedProjectId = isOrgOwner ? values.projectId || virtualProjectId : values.projectId
      const schema = createPremiumByocFormSchema(servicePlan, orgId, resolvedProjectId, {
        requireProjectSelection: requiresProjectSelection || (!isOrgOwner && eligibleProjects.length === 0)
      })

      return zodResolver(schema)(values, ctx, options)
    }
  })
  const { handleSubmit, setError, watch } = formMethods
  const selectedProjectId = watch('projectId')
  const effectiveProjectId = isOrgOwner ? selectedProjectId || virtualProjectId : selectedProjectId

  const { instanceMaxRcu, availableTotalRcu } = useCapacityLimits({ servicePlan, projectId: effectiveProjectId })
  const effectiveLimit = Math.min(
    instanceMaxRcu ?? PREMIUM_MAX_RCU_FALLBACK,
    availableTotalRcu ?? PREMIUM_MAX_RCU_FALLBACK
  )
  const isQuotaInsufficient = effectiveLimit < PREMIUM_MIN_RCU

  const queryClient = useQueryClient()
  const createMutator = useCreateTidb()

  const handleValidSubmit = useCallback(
    async (data: PremiumByocFormValue) => {
      const resolvedProjectId = isOrgOwner ? data.projectId || virtualProjectId : data.projectId

      if (!resolvedProjectId) {
        notifier.error('Missing organization or project context.')
        return
      }

      if (
        data.dualLayerDataEncryption?.encrypted &&
        data.dualLayerDataEncryption.keyType === 'customer-managed' &&
        data.cloudProvider === V1beta1RegionCloudProvider.aws &&
        !data.dualLayerDataEncryption.awsCmek?.kmsKeyArn?.trim()
      ) {
        setError('dualLayerDataEncryption.awsCmek.kmsKeyArn', {
          type: 'validate',
          message: 'KMS Key ARN is required when using CMEK. Please add a KMS Key ARN to continue.'
        })
        return
      }

      if (
        data.dualLayerDataEncryption?.encrypted &&
        data.dualLayerDataEncryption.keyType === 'customer-managed' &&
        data.cloudProvider === V1beta1RegionCloudProvider.alicloud
      ) {
        if (!data.dualLayerDataEncryption.aliyunCmek?.kmsKeyArn?.trim()) {
          setError('dualLayerDataEncryption.aliyunCmek.kmsKeyArn', {
            type: 'validate',
            message: 'KMS Key ARN is required when using CMEK. Please add a KMS Key ARN to continue.'
          })
          return
        }
      }

      const dualLayerDataEncryption = data.dualLayerDataEncryption?.encrypted
        ? {
            defaultKey: data.dualLayerDataEncryption.keyType === 'service-managed' ? {} : undefined,
            cmek:
              data.dualLayerDataEncryption.keyType === 'customer-managed'
                ? {
                    servicePlan,
                    regionId: data.regionId,
                    ...(data.cloudProvider === V1beta1RegionCloudProvider.aws
                      ? {
                          awsKms: {
                            kmsKeyArn: data.dualLayerDataEncryption.awsCmek?.kmsKeyArn?.trim()!
                          },
                          awsPrincipal: {
                            accountId: data.dualLayerDataEncryption.awsCmek?.accountId!
                          }
                        }
                      : {
                          aliyunKms: {
                            kmsKeyArn: data.dualLayerDataEncryption.aliyunCmek?.kmsKeyArn?.trim()!
                          },
                          aliyunPrincipal: {
                            accountId: data.dualLayerDataEncryption.aliyunCmek?.accountId!
                          }
                        })
                  }
                : undefined
          }
        : undefined

      const result = await createMutator.mutateAsync({
        data: {
          servicePlan,
          displayName: data.name,
          cloudProvider: data.cloudProvider,
          regionId: data.regionId,
          maxRcu: String(data.maxRcu),
          highAvailabilityType: data.highAvailabilityType,
          labels: {
            'tidb.cloud/project': resolvedProjectId
          },
          dualLayerDataEncryption
        },
        params: {
          orgId,
          projectId: resolvedProjectId
        }
      })

      // Invalidate capacity limits queries to refresh quota data
      invalidateCapacityLimitsQueries(queryClient, servicePlan, orgId, resolvedProjectId)

      return result
    },
    [createMutator, isOrgOwner, orgId, queryClient, servicePlan, setError, virtualProjectId]
  )
  const formId = useId()

  return (
    <FormProvider {...formMethods}>
      <TwoPaneLayout
        visible={active}
        header={header}
        rightSection={
          <PremiumSummary
            formId={formId}
            servicePlan={servicePlan}
            disabled={isQuotaInsufficient}
            isPending={createMutator.isLoading}
          />
        }
      >
        <PremiumForm
          formId={formId}
          planSelector={planSelector}
          onSubmit={handleSubmit(handleValidSubmit)}
          active={active}
        />
      </TwoPaneLayout>
    </FormProvider>
  )
})
