import { Box, Button, Divider, Group, HoverCard, Skeleton, Stack, Typography } from '@tidbcloud/uikit'
import { notifier } from '@tidbcloud/uikit'
import { observer } from 'mobx-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 { useAddCreditCard } from 'dbaas/screens/NextGen/my-tidb-creation/shared/use-add-credit-card'
import { useServerlessPlanRegions } from 'dbaas/screens/NextGen/my-tidb-creation/shared/use-serverless-plan-regions'
import { PaymentMethodModal } from 'dbaas/screens/Stripe/PaymentMethod/PaymentMethodModal'
import { Serverlessv1beta1ClusterHighAvailabilityType } from 'dbaas/services/api-clients/v2023/serverless/v1beta1/interface'
import useStores from 'dbaas/stores/useStores'

import { CreateActionGuard } from '../../shared/CreateActionGuard'

import { SpendingLimitCost } from './summary/SpendingLimitCost'
import { StarterFormValue } from './types'

interface StarterSummaryProps {
  formId: string
  disabled?: boolean
  isPending?: boolean
}

const HADescriptions: Record<string, string> = {
  [Serverlessv1beta1ClusterHighAvailabilityType.ZONAL]: 'Zonal',
  [Serverlessv1beta1ClusterHighAvailabilityType.REGIONAL]: 'Regional'
}

const SumInfoItem = ({ label, value, isError }: { label: string; value: React.ReactNode; isError?: boolean }) => {
  return (
    <PropertyKV label={label} labelProps={{ w: 144 }} valueProps={{ c: isError ? 'red' : undefined }}>
      {value}
    </PropertyKV>
  )
}

export const StarterSummary = observer(({ formId, disabled, isPending }: StarterSummaryProps) => {
  const history = useHistory()
  const location = useLocation()
  const {
    store: {
      userProfile: { projects: allProjects }
    }
  } = useStores()

  const {
    watch,
    formState: { errors, dirtyFields }
  } = useFormContext<StarterFormValue>()

  const provider = watch('provider')
  const region = watch('region')
  const projectId = watch('projectId')
  const name = watch('name')
  const spendingLimit = watch('spendingLimit')
  const encrypted = watch('encrypted')
  const highAvailabilityType = watch('highAvailabilityType')

  const { regions, isLoading } = useServerlessPlanRegions('Starter', provider, { refetchOnMount: false })
  const regionName = regions.find((r) => r.name === region)?.displayName ?? ''

  const actionsDisabled = !!disabled || isLoading

  const spendingLimitValue = Number(spendingLimit ?? 0)
  const { creditCardNeeded, creditCardModalVisible, creditCardModalHandlers } = useAddCreditCard({
    enabled: spendingLimitValue > 0
  })

  const filledFields = (['provider', 'region', 'name'] as const).filter((key) => !!dirtyFields?.[key]).join(', ')
  const projectName = allProjects?.find((p) => p.id === projectId)?.name ?? '-'

  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="Starter" />
          <SumInfoItem label="Project" value={projectName} />
          <SumInfoItem
            label="Instance Name"
            value={isLoading ? <Skeleton width={100} height={16} /> : name || '-'}
            isError={!!errors?.name}
          />
          <SumInfoItem
            label="Cloud Provider"
            value={isLoading ? <Skeleton width={80} height={16} /> : getCloudProviderLabel(provider)}
          />
          <SumInfoItem label="Region" value={isLoading ? <Skeleton width={120} height={16} /> : regionName} />
          <Divider my={8} />
          <SumInfoItem
            label="Spending Limit"
            value={`$${Number.isFinite(spendingLimitValue) ? spendingLimitValue : 0} / month`}
            isError={!!errors?.spendingLimit}
          />
          <Divider my={8} />
          <SumInfoItem label="Dual-Layer Data Encryption" value={encrypted ? 'Enabled' : 'Disabled'} />
          {!!highAvailabilityType && (
            <SumInfoItem label="High Availability" value={HADescriptions[highAvailabilityType] || '-'} />
          )}
        </Stack>
      </Box>
      <Divider />
      <Box sx={{ marginTop: 'auto' }}>
        <SpendingLimitCost spendingLimit={spendingLimit} />

        <Group>
          <Button
            variant="default"
            onClick={() => history.push(`/tidbs${location.search}`)}
            data-mp-event="Cancel Created A Cluster"
            data-mp-service-plan="Starter"
            data-mp-source="My TiDB - Creation"
            data-mp-filled-fields={filledFields}
          >
            Cancel
          </Button>

          <CreateActionGuard
            projectId={projectId}
            permissionMessage={'Please ask your admin to grant you the permission to create a Starter instance.'}
          >
            {!creditCardNeeded && (
              <Button
                type="submit"
                form={formId}
                disabled={actionsDisabled}
                loading={isPending}
                sx={{ flexGrow: 1 }}
                data-mp-event="Cluster Creation Button Clicked"
                data-mp-service-plan="Starter"
                data-mp-source="My TiDB - Creation"
              >
                Create
              </Button>
            )}
            {creditCardNeeded && (
              <AccessGuard
                id="BillingPaymentCreation"
                fallback={
                  <HoverCard withArrow withinPortal>
                    <HoverCard.Target>
                      <span style={{ flexGrow: 1 }}>
                        <Button
                          disabled
                          fullWidth
                          data-mp-event="mp-addcreditcard-1691461017771"
                          data-mp-source="My TiDB - Creation"
                        >
                          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}
                  disabled={actionsDisabled}
                  sx={{ flexGrow: 1 }}
                  data-mp-event="Add Credit Card Button Clicked"
                  data-mp-service-plan="Starter"
                  data-mp-source="My TiDB - Creation"
                >
                  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>
  )
})
