import { Divider, Paper } from '@tidbcloud/uikit'
import { observer } from 'mobx-react'
import { cloneElement, isValidElement, useEffect, useMemo } from 'react'
import { useFormContext } from 'react-hook-form'

import { useServerlessPlanRegions } from 'dbaas/screens/NextGen/my-tidb-creation/shared/use-serverless-plan-regions'
import { useVirtualProjectId } from 'dbaas/screens/NextGen/my-tidb-creation/shared/use-virtual-project-id'
import { useCreateResourceRoleState } from 'dbaas/screens/NextGen/shared/access/create-resource-role'
import type { StarterInventoryLimitStatus } from 'dbaas/screens/shared/starter-capacity/use-starter-inventory-limit'
import useStores from 'dbaas/stores/useStores'

import { AdvancedSettingsSection } from './sections/AdvancedSettingsSection'
import { BasicSettingsSection } from './sections/BasicSettingsSection'
import { SpendingLimitSection } from './sections/SpendingLimitSection'
import { StarterCapacityPlanAlert } from './sections/StarterCapacityPlanAlert'
import type { StarterFormValue } from './types'

interface StarterFormProps {
  formId: string
  planSelector: React.ReactNode
  onSubmit: () => void
  capacityStatus?: StarterInventoryLimitStatus
  capacityCurrentCount?: number
  capacityLimit?: number
  disabled?: boolean
}

export const StarterForm = observer(
  ({
    formId,
    planSelector,
    onSubmit,
    capacityStatus,
    capacityCurrentCount,
    capacityLimit,
    disabled
  }: StarterFormProps) => {
    const {
      store: {
        lastVisitLocation: { orgId, projectId: currentProjectId }
      },
      actions: { fetchUserProfileV2 }
    } = useStores()

    const { watch, getValues, setValue } = useFormContext<StarterFormValue>()
    const provider = watch('provider')
    const projectId = watch('projectId')
    const virtualProjectId = useVirtualProjectId()

    const { cloudProviders: providers, regions, isLoading } = useServerlessPlanRegions('Starter', provider)

    const { ownerProjects, isOrgOwner, isAnyProjectOwner } = useCreateResourceRoleState()
    const effectiveProjectId = isOrgOwner ? projectId || virtualProjectId : projectId
    const eligibleProjects = useMemo(
      () => ownerProjects.filter((project) => !project.aws_cmek_enabled && project.type === 'tidbx'),
      [ownerProjects]
    )
    const projectOptions = useMemo(
      () => eligibleProjects.map((p) => ({ value: p.id, label: p.name })),
      [eligibleProjects]
    )
    const capacityAlert =
      capacityStatus && isValidElement(planSelector) ? (
        <StarterCapacityPlanAlert status={capacityStatus} currentCount={capacityCurrentCount} limit={capacityLimit} />
      ) : undefined
    const planSelectorWithCapacityAlert =
      capacityAlert && isValidElement(planSelector)
        ? cloneElement(planSelector, { footer: capacityAlert } as Partial<{ footer: React.ReactNode }>)
        : planSelector

    useEffect(() => {
      const nextProvider = providers[0]
      if (!nextProvider) {
        return
      }

      if (!provider || !providers.includes(provider)) {
        setValue('provider', nextProvider)
      }
    }, [provider, providers, setValue])

    useEffect(() => {
      const currentRegion = getValues('region')
      const nextRegion = regions?.[0]?.name ?? ''
      if (!currentRegion || !regions?.some((r) => r.name === currentRegion)) {
        setValue('region', nextRegion)
      }
    }, [regions, setValue, getValues])

    useEffect(() => {
      if (isOrgOwner || !isAnyProjectOwner) {
        return
      }

      const selectedProjectId = getValues('projectId')
      const hasValidProjectSelection =
        !!selectedProjectId && eligibleProjects.some((project) => project.id === selectedProjectId)
      if (hasValidProjectSelection) {
        return
      }

      const nextProjectId =
        eligibleProjects.find((project) => project.id === currentProjectId)?.id || eligibleProjects[0]?.id || ''

      setValue('projectId', nextProjectId, { shouldValidate: true })
    }, [currentProjectId, eligibleProjects, getValues, isAnyProjectOwner, isOrgOwner, setValue])

    return (
      <Paper component="form" id={formId} onSubmit={onSubmit} withBorder shadow="none">
        {planSelectorWithCapacityAlert}
        <Divider />
        <BasicSettingsSection
          cloudProviders={providers}
          regions={regions}
          disabled={disabled || isLoading}
          projectOptions={projectOptions}
          onProjectCreated={() => fetchUserProfileV2()}
          projectOptional={isOrgOwner}
        />
        <Divider />
        <SpendingLimitSection projectId={effectiveProjectId} disabled={disabled} />
        <Divider />
        <AdvancedSettingsSection orgId={orgId} disabled={disabled} />
      </Paper>
    )
  }
)
