import { Alert, Group, Paper, Stack, Typography, TypographyProps } from '@tidbcloud/uikit'
import { useDebouncedValue } from '@tidbcloud/uikit/hooks'
import { observer } from 'mobx-react'

import { usePredictClusterSpendLimit, usePredictSpendLimit } from 'dbaas/services'
import useStores from 'dbaas/stores/useStores'
import { formatStorage, formatToMillions, toCents } from 'dbaas/utils/format'

interface SpendLimitInputDescProps extends TypographyProps {
  value?: number
  region: string
  encrypted?: boolean
  clusterId?: string
  suffix?: string
  resourceName?: string
}

export const SpendLimitInputDesc = observer(
  ({
    value,
    region,
    encrypted,
    clusterId = '',
    suffix,
    resourceName = 'cluster',
    ...restProps
  }: SpendLimitInputDescProps) => {
    const {
      store: {
        lastVisitLocation: { orgId, projectId }
      }
    } = useStores()

    const fixedValue = Number(value ?? 0)
    const [debouncedValue] = useDebouncedValue(fixedValue, 500)

    const { data: creationData, isFetching: creationLoading } = usePredictSpendLimit(
      orgId,
      {
        spend_limit: toCents(debouncedValue),
        project_id: projectId,
        region,
        enhanced_encryption_enabled: encrypted
      },
      {
        query: {
          enabled: !!(orgId && projectId && region && debouncedValue) && !clusterId
        }
      }
    )

    const { data: editData, isFetching: editLoading } = usePredictClusterSpendLimit(
      orgId,
      clusterId,
      {
        spend_limit: toCents(debouncedValue),
        region
      },
      {
        query: {
          enabled: !!(orgId && clusterId && region && debouncedValue)
        }
      }
    )

    const data = clusterId ? editData : creationData
    const loading = clusterId ? editLoading : creationLoading

    if (!fixedValue || isNaN(fixedValue)) {
      return (
        <Typography variant="body-sm" c="carbon.7" {...restProps}>
          If the limit is set to $0, you can use only the free quota. Once the free quota is exhausted and the spending
          limit is reached, the {resourceName} will be automatically throttled. You can update the spending limit at any
          time.
        </Typography>
      )
    }

    if (loading) {
      return (
        <Typography variant="body-sm" c="carbon.7" {...restProps}>
          Calculating quota...
        </Typography>
      )
    }

    if (!data) {
      return null
    }

    return (
      <Typography variant="body-sm" c="carbon.7" {...restProps}>
        Up to {formatToMillions(+data.max_request_units)} Request Units per month
        {+data.free_request_units > 0 ? ` with ${formatToMillions(+data.free_request_units)} free quota included` : ''},
        up to {formatStorage(+data.max_row_storage)} of Row-based Storage per month
        {+data.free_row_storage > 0 ? ` with ${formatStorage(+data.free_row_storage)} free quota included` : ''}.
        {/* or up
        to {formatStorage(+data.max_column_storage)} of Columnar Storage per month
        {+data.free_column_storage > 0 ? ` with ${formatStorage(+data.free_column_storage)} free quota included` : ''}. */}
        {suffix ? ` ${suffix}` : null}
      </Typography>
    )
  }
)

export const SpendLimitInputInstruction = observer(({ region }: { region: string }) => {
  const {
    store: {
      lastVisitLocation: { orgId, projectId }
    }
  } = useStores()

  const { data, isLoading } = usePredictSpendLimit(
    orgId,
    {
      spend_limit: 100,
      project_id: projectId,
      region
    },
    {
      query: {
        enabled: !!region
      }
    }
  )

  return (
    <Group align="stretch" grow wrap="nowrap" gap="xl" mt={24}>
      <Alert
        color="carbon"
        styles={(theme) => ({ root: { borderColor: theme.colors.carbon[5], backgroundColor: theme.colors.carbon[2] } })}
      >
        <Typography variant="body-lg">
          You will only be charged if you exceed the free 5GiB storage or free 50M Request Units per month. If you reach
          your spending limit, the cluster will be throttled to 10RU/s until the customer sets a larger spending limit
          or the current usage is reset after the next month. You'll receive alerts when you are nearing your limit.
        </Typography>
      </Alert>
      <Paper
        shadow="none"
        withBorder
        sx={(theme) => ({
          padding: theme.spacing.md,
          borderColor: theme.colors.carbon[4],
          background: theme.colors.carbon[1]
        })}
      >
        <Stack gap={8}>
          <Typography variant="action-md" c="carbon.9">
            Resource cost:
          </Typography>
          {isLoading || !data ? (
            <Typography variant="label-lg" c="carbon.9">
              Loading...
            </Typography>
          ) : (
            <>
              <Typography variant="label-lg" c="carbon.9">
                $1 = {formatStorage(data.max_row_storage - data.free_row_storage)} Row-based Storage / month
                <br />
                $1 = {formatStorage(data.max_column_storage - data.free_column_storage)} Columnar Storage / month
                <br />
                $1 = {formatToMillions(+data.max_request_units - +data.free_request_units)} Request Units / month
              </Typography>
              <Typography variant="body-lg">
                Learn more about{' '}
                <a href="https://www.pingcap.com/tidb-serverless-pricing-details/" target="_blank" rel="noreferrer">
                  pricing
                </a>
                .
              </Typography>
            </>
          )}
        </Stack>
      </Paper>
    </Group>
  )
})
