import { Box, Button, Divider, Group, HoverCard, Stack, Typography, notifier } from '@tidbcloud/uikit'
import { observer } from 'mobx-react'
import { useMemo } from 'react'
import { useFormContext } from 'react-hook-form'
import { useHistory, useLocation } from 'react-router-dom'

import { PropertyKV } from 'dbaas/components'
import { AccessGuard } from 'dbaas/contexts/access-control'
import { getCloudProviderLabel } from 'dbaas/features/Project'
import { CreateActionGuard } from 'dbaas/screens/NextGen/my-tidb-creation/shared/CreateActionGuard'
import { useGetTidbCloudRegions } from 'dbaas/screens/NextGen/my-tidb-creation/shared/premium-byoc/basic-settings/use-cloud-providers-regions'
import { useDualLayerDataEncryptionFeatEnabled } from 'dbaas/screens/NextGen/my-tidb-creation/shared/premium-byoc/dual-layer-data-encryption/use-dual-layer-data-encryption-feat-enabled'
import { PremiumByocFormValue } from 'dbaas/screens/NextGen/my-tidb-creation/shared/premium-byoc/types'
import { useAddCreditCard } from 'dbaas/screens/NextGen/my-tidb-creation/shared/use-add-credit-card'
import { useCreateResourceRoleState } from 'dbaas/screens/NextGen/shared/access/create-resource-role'
import { getDisplayServicePlan } from 'dbaas/screens/NextGen/shared/tidb-instance/service-plan/ServicePlanTag'
import { PaymentMethodModal } from 'dbaas/screens/Stripe/PaymentMethod/PaymentMethodModal'
import { useTidbServiceListPremiumReservedCapacityOptions } from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2'
import {
  Commonv1beta1ServicePlan,
  V1beta2TidbHighAvailabilityType
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import useStores from 'dbaas/stores/useStores'
import { MixpanelEvents } from 'dbaas/utils/tracking'

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

import { PremiumReservedPricingCost } from './summary/PremiumReservedPricingCost'

interface PremiumReservedSummaryProps {
  formId: string
  servicePlan: Commonv1beta1ServicePlan
  disabled?: boolean
  isPending?: boolean
}

const SumInfoItem = ({ label, value }: { label: string; value: React.ReactNode }) => {
  return (
    <PropertyKV label={label} labelProps={{ w: 144 }}>
      {value}
    </PropertyKV>
  )
}

export const PremiumReservedSummary = observer(
  ({ formId, servicePlan, disabled, isPending }: PremiumReservedSummaryProps) => {
    const {
      store: {
        lastVisitLocation: { orgId },
        userProfile: { projects: allProjects }
      }
    } = useStores()
    const history = useHistory()
    const location = useLocation()
    const { watch } = useFormContext<PremiumByocFormValue>()

    const projectId = watch('projectId')
    const name = watch('name')
    const cloudProvider = watch('cloudProvider')
    const regionId = watch('regionId')
    const reservedCapacityTemplateId = watch('reservedCapacityTemplateId')
    const highAvailabilityType = watch('highAvailabilityType')
    const dataEncryptionEnabled = watch('dualLayerDataEncryption.encrypted')
    const dataEncryptionKeyType = watch('dualLayerDataEncryption.keyType')
    const virtualProjectId = useVirtualProjectId()
    const { isOrgOwner } = useCreateResourceRoleState()
    const effectiveProjectId = isOrgOwner ? projectId || virtualProjectId : projectId

    const { regions, isLoading: isLoadingRegions } = useGetTidbCloudRegions(servicePlan, cloudProvider ?? '', {
      projectId: effectiveProjectId
    })
    const isLoading = isLoadingRegions

    const projectName = allProjects?.find((project) => project.id === projectId)?.name ?? '-'
    const regionName = regions.find((r) => r.regionId === regionId)?.displayName ?? regionId ?? ''
    const haLabel =
      highAvailabilityType === V1beta2TidbHighAvailabilityType.REGIONAL
        ? 'Regional'
        : highAvailabilityType === V1beta2TidbHighAvailabilityType.ZONAL
          ? 'Zonal'
          : '-'
    const dataEncryptionKeyLabel =
      dataEncryptionKeyType === 'customer-managed'
        ? 'Customer-managed Encryption Key (CMEK)'
        : dataEncryptionKeyType === 'service-managed'
          ? 'Service-managed Encryption Key'
          : undefined

    const dataEncryptionValue = dataEncryptionEnabled
      ? `Enabled${dataEncryptionKeyLabel ? ` with ${dataEncryptionKeyLabel}` : ''}`
      : 'Disabled'
    const { isEnabled: isDataEncryptionFeatEnabled } = useDualLayerDataEncryptionFeatEnabled({
      servicePlan,
      cloudProvider
    })

    const capacityList = useTidbServiceListPremiumReservedCapacityOptions(
      { orgId, projectId },
      {
        query: {
          enabled: !!orgId,
          refetchOnWindowFocus: false,
          select: (data) => data?.reservedCapacities ?? []
        }
      }
    )

    const { creditCardNeeded, creditCardModalVisible, creditCardModalHandlers } = useAddCreditCard({
      enabled: servicePlan === Commonv1beta1ServicePlan.Premium_Reserved
    })

    const curCapacityOption = useMemo(() => {
      return capacityList.data?.find((option) => option.id === reservedCapacityTemplateId)
    }, [capacityList.data, reservedCapacityTemplateId])

    return (
      <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', minHeight: 0 }}>
        <Box>
          <Typography variant="title-lg">Summary</Typography>
          <Typography variant="body-lg" c="carbon.7" mt={4}>
            Your new instance will be:
          </Typography>
          <Stack justify="flex-start" gap={8} pt="xl" pb="md">
            <SumInfoItem label="Plan" value={getDisplayServicePlan(servicePlan)} />
            <SumInfoItem label="Project" value={projectName} />
            <SumInfoItem label="Instance Name" value={name || '-'} />
            <SumInfoItem label="Cloud Provider" value={cloudProvider ? getCloudProviderLabel(cloudProvider) : '-'} />
            <SumInfoItem label="Region" value={regionName || '-'} />
            <Divider my={8} />
            <SumInfoItem label="Capacity" value={curCapacityOption ? `${curCapacityOption.purchasedVcpu} vCPU` : '-'} />
            <Divider my={8} />
            {isDataEncryptionFeatEnabled && (
              <SumInfoItem label="Dual-Layer Data Encryption" value={dataEncryptionValue} />
            )}
            <SumInfoItem label="High Availability" value={haLabel} />
          </Stack>
        </Box>
        <Divider />
        <Box sx={{ marginTop: 'auto' }}>
          <PremiumReservedPricingCost
            cloudProvider={cloudProvider ?? ''}
            region={regionId ?? ''}
            projectId={effectiveProjectId}
          />
          <Group justify="space-between">
            <Button
              variant="default"
              onClick={() => history.push(`/tidbs${location.search}`)}
              data-mp-event={MixpanelEvents.TidbResource.Create.CancelClicked}
              data-mp-service-plan={servicePlan}
            >
              Cancel
            </Button>
            <CreateActionGuard
              projectId={projectId}
              projectAccessId="TidbxCreateInProject"
              orgAccessId="TidbxCreateInVirtualProject"
              permissionMessage={'Please ask your admin to grant you the permission to create a Premium instance.'}
            >
              {!creditCardNeeded && (
                <Button
                  type="submit"
                  form={formId}
                  disabled={isLoading || disabled}
                  sx={{ flexGrow: 1 }}
                  loading={isPending}
                  data-mp-event={MixpanelEvents.TidbResource.Create.SubmitClicked}
                  data-mp-service-plan={servicePlan}
                >
                  Create
                </Button>
              )}
              {creditCardNeeded && (
                <AccessGuard
                  id="BillingPaymentCreation"
                  fallback={
                    <HoverCard withArrow withinPortal>
                      <HoverCard.Target>
                        <span style={{ flexGrow: 1 }}>
                          <Button disabled sx={{ width: '100%' }}>
                            Add Credit Card
                          </Button>
                        </span>
                      </HoverCard.Target>
                      <HoverCard.Dropdown maw={320}>
                        Please contact your Organization Owner or Billing Manager to add a credit card.
                      </HoverCard.Dropdown>
                    </HoverCard>
                  }
                >
                  <Button
                    onClick={creditCardModalHandlers.open}
                    sx={{ flexGrow: 1 }}
                    data-mp-event="Add Credit Card Button Clicked"
                    data-mp-service-plan={servicePlan}
                  >
                    Add Credit Card
                  </Button>
                </AccessGuard>
              )}
            </CreateActionGuard>
          </Group>
        </Box>

        {creditCardNeeded && (
          <PaymentMethodModal
            open={creditCardModalVisible}
            onClose={creditCardModalHandlers.close}
            onComplete={() => {
              creditCardModalHandlers.close()
              notifier.success('Your credit card was added successfully!')
            }}
          />
        )}
      </Box>
    )
  }
)
