import {
  Card,
  Button,
  Divider,
  Group,
  Stack,
  Typography,
  Tooltip,
  Box,
  TypographyProps,
  notifier,
  Flex
} from '@tidbcloud/uikit'
import { useMemoizedFn } from 'ahooks'
import { observer } from 'mobx-react'
import { useFormContext } from 'react-hook-form'
import { useHistory } from 'react-router-dom'

import { PropertyKV } from 'dbaas/components'
import { AccessGuard } from 'dbaas/contexts/access-control'
import { SharedCluster } from 'dbaas/features/ClusterManagement/cluster'
import { useAddCreditCard } from 'dbaas/screens/ClustersV2/new/Serverless/helpers'
import { PaymentMethodModal } from 'dbaas/screens/Stripe'
import { useModifySpendLimit } from 'dbaas/services/api-clients/legacy/serverless'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'
import { toCents } from 'dbaas/utils/format'
import { moneyFormatter } from 'dbaas/utils/numberFormat'

import { EditFormValueState, useCancel } from './helpers'

interface SumInfoItemProps {
  label: string
  value?: React.ReactNode
  isError?: boolean
  errors?: React.ReactNode
  labelProps?: TypographyProps
}

export const SumInfoItem = ({ label, value = '', isError, errors, labelProps = {} }: SumInfoItemProps) => {
  return (
    <PropertyKV
      label={label}
      labelProps={{
        w: 112,
        ...labelProps
      }}
      valueProps={{ color: isError ? 'red' : 'carbon.8' }}
    >
      {isError ? (errors ?? `Invalid ${label}`) : value}
    </PropertyKV>
  )
}

const SpendingLimitCost = ({ value = 0 }: { value?: number }) => {
  return (
    <Stack gap={4} py="xl">
      <Group gap={8}>
        <Typography variant="headline-md" c="carbon.9">
          {moneyFormatter(value)}
        </Typography>
        <Typography variant="body-lg">maximum/month</Typography>
      </Group>
      <Typography variant="body-lg">
        {value ? 'No upfront charges. Pay only for your actual usage.' : 'No credit card required.'}
      </Typography>
    </Stack>
  )
}

interface SumCardProps {
  cluster: SharedCluster
}

export const SumCard = observer(({ cluster }: SumCardProps) => {
  const {
    store: {
      lastVisitLocation: { orgId }
    }
  } = useStores()
  const cancel = useCancel()
  const history = useHistory()

  const {
    watch,
    handleSubmit,

    formState: { errors }
  } = useFormContext<EditFormValueState>()
  const { monthlySpendingLimit } = watch()

  const updator = useModifySpendLimit({
    mutation: {
      onSuccess: () => {
        if (cluster.id) {
          history.push(`/clusters/${cluster.id}/overview`)
        }
      },
      onError: (error) => {
        const errorMsg = getErrorMessage(error)

        notifier.error(<div dangerouslySetInnerHTML={{ __html: errorMsg }}></div>)
      }
    }
  })
  const onSubmit = useMemoizedFn(async (data: EditFormValueState) => {
    if (!orgId || !cluster?.id) {
      notifier.error(<div dangerouslySetInnerHTML={{ __html: 'Failed to update instance plan' }}></div>)

      return
    }

    return await updator.mutateAsync({
      orgId,
      clusterId: cluster.id,
      data: {
        spend_limit: toCents(data.monthlySpendingLimit),
        region: cluster.region
      }
    })
  })
  const onConfirm = handleSubmit(onSubmit)

  const { creditAddVisible, creditModalVisible, creditModalHandlers } = useAddCreditCard(monthlySpendingLimit)

  return (
    <Card shadow="none" p="xl">
      <Typography variant="title-lg">Summary</Typography>
      <Stack justify="flex-start" gap={8} py="xl">
        <SumInfoItem label="Plan" value={cluster?.servicePlan} />
        <SumInfoItem label="Name" value={cluster?.name} />
        <SumInfoItem
          label="Spending Limit"
          value={`$${monthlySpendingLimit} / month`}
          isError={!!errors?.monthlySpendingLimit}
        />
      </Stack>
      <Divider color="carbon.4" />
      <SpendingLimitCost value={monthlySpendingLimit} />
      <Divider color="carbon.4" />
      <Flex align="center" gap="md" mt="xl">
        <Button variant="default" onClick={cancel} data-mp-event="mp-cancel-1691461017863">
          Cancel
        </Button>
        {!creditAddVisible && (
          <Button
            disabled={!monthlySpendingLimit}
            loading={updator.isLoading}
            onClick={onConfirm}
            sx={{ flexGrow: 1 }}
            data-mp-event="Update Spending Limit Button Clicked"
            data-mp-ev-alias="Update Cluster Plan Button Clicked"
          >
            Update Instance Plan
          </Button>
        )}
        {creditAddVisible && (
          <AccessGuard
            id="BillingPaymentCreation"
            fallback={
              <Tooltip
                sx={{ flexGrow: 1 }}
                label="Please contact the Owner or Billing Manager to add a credit card and your discount will be applied to your next billing cycle."
              >
                <Box>
                  <Button disabled data-mp-event="mp-addcreditcard-1691461017865">
                    Add Credit Card
                  </Button>
                </Box>
              </Tooltip>
            }
          >
            <Button
              disabled={!orgId || !cluster?.id || !!errors?.monthlySpendingLimit}
              onClick={creditModalHandlers.open}
              sx={{ flexGrow: 1 }}
              data-mp-event="Add Credit Card and Update Cluster Plan Button Clicked"
            >
              Add Credit Card
            </Button>
          </AccessGuard>
        )}
      </Flex>
      {creditAddVisible && (
        <PaymentMethodModal
          open={creditModalVisible}
          onClose={creditModalHandlers.close}
          onComplete={() => {
            creditModalHandlers.close()
            onConfirm()
            notifier.success('Your credit card is added successfully!')
          }}
        />
      )}
    </Card>
  )
})
