import { zodResolver } from '@hookform/resolvers/zod'
import { notifier } from '@tidbcloud/uikit'
import { observer } from 'mobx-react'
import { useCallback, useId } from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import { useHistory, useLocation } from 'react-router-dom'

import { markOneConsoleFeedbackEventCompleted } from 'dbaas/layouts/v5/NewNavGuide/feedbackState'
import { useCreateResourceRoleState } from 'dbaas/screens/NextGen/shared/access/create-resource-role'
import { useStarterInventoryLimit } from 'dbaas/screens/shared/starter-capacity/use-starter-inventory-limit'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

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

import { createStarterFormSchema } from './schema'
import { StarterForm } from './StarterForm'
import { StarterSummary } from './StarterSummary'
import { StarterFormValue } from './types'
import { useCreateStarter } from './use-create-starter'

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

export const StarterCreation = observer(({ header, planSelector, active }: StarterCreationProps) => {
  const history = useHistory()
  const location = useLocation()
  const {
    store: {
      userProfile: { id: userId }
    },
    actions: { refreshOrgData }
  } = useStores()

  const virtualProjectId = useVirtualProjectId()
  const { requiresProjectSelection, isOrgOwner } = useCreateResourceRoleState()
  const starterInventoryLimit = useStarterInventoryLimit({ enabled: active })

  const formMethods = useForm<StarterFormValue>({
    mode: 'onChange',
    defaultValues: {
      projectId: '',
      provider: '',
      region: '',
      // TODO: Replace with client-generated semantic random default name (do not depend on projectId).
      name: '',
      spendingLimitMode: 'spendingLimit',
      spendingLimit: 10,
      encrypted: false,
      highAvailabilityType: undefined
    },
    resolver: (values, ctx, options) =>
      zodResolver(createStarterFormSchema({ requireProjectSelection: requiresProjectSelection }))(values, ctx, options)
  })

  const { createTidb, isCreating } = useCreateStarter({
    onSuccess: (tidbId) => {
      refreshOrgData()
      eventTracking('Created A Cluster', {
        'Cluster Type': 'Serverless Tier',
        source: 'Clusters - Creation v2'
      })
      markOneConsoleFeedbackEventCompleted(userId, 'creation')

      notifier.success('Creating TiDB Cloud Starter Instance...')
      if (tidbId) {
        history.push(`/tidbs/${tidbId}/overview${location.search}`)
      } else {
        history.push(`/tidbs${location.search}`)
      }
    },
    onError: (errorMsg) => {
      notifier.error(<div dangerouslySetInnerHTML={{ __html: errorMsg }} />)
    }
  })

  const handleValidSubmit = useCallback(
    async (data: StarterFormValue) => {
      if (starterInventoryLimit.isLoading) {
        return
      }

      if (starterInventoryLimit.isLimitReached) {
        notifier.error("You've reached the resource limit(100 instance + branch).")
        return
      }

      const resolvedProjectId = isOrgOwner ? data.projectId || virtualProjectId : data.projectId

      await createTidb({
        ...data,
        projectId: resolvedProjectId
      })
    },
    [createTidb, isOrgOwner, starterInventoryLimit.isLimitReached, starterInventoryLimit.isLoading, virtualProjectId]
  )
  const formId = useId()

  return (
    <FormProvider {...formMethods}>
      <TwoPaneLayout
        visible={active}
        header={header}
        rightSection={
          <StarterSummary
            formId={formId}
            disabled={starterInventoryLimit.isLoading || starterInventoryLimit.isLimitReached}
            isPending={isCreating || starterInventoryLimit.isLoading}
          />
        }
      >
        <StarterForm
          formId={formId}
          planSelector={planSelector}
          onSubmit={formMethods.handleSubmit(handleValidSubmit)}
          capacityStatus={starterInventoryLimit.status}
          capacityCurrentCount={starterInventoryLimit.currentCount}
          capacityLimit={starterInventoryLimit.limit}
          disabled={starterInventoryLimit.isLimitReached}
        />
      </TwoPaneLayout>
    </FormProvider>
  )
})
