import {
  AnimatedNumber,
  Badge,
  Button,
  Divider,
  Flex,
  Group,
  Modal,
  Select,
  Stack,
  Typography,
  notifier
} from '@tidbcloud/uikit'
import { useMemoizedFn } from 'ahooks'
import { useEffect, useMemo, useState } from 'react'
import { useQuery } from 'react-query'

import { getApiErrorMsgDom } from 'dbaas/components/Notification/ErrorMessag'
import { queryClient } from 'dbaas/reactQueryClient'
import { SharedTiDB } from 'dbaas/screens/NextGen/shared/model/shared-tidb-state'
import { getTiDBServiceGetTidbQueryKey } from 'dbaas/services/api-clients/v2023/cluster-management/v1beta2'
import {
  getTidbServiceGetTidbQueryKey,
  useTidbServiceEstimatePrice,
  useTidbServiceListPremiumReservedCapacityOptions,
  useTidbServiceUpdateTidb
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2'
import {
  Commonv1beta1ServicePlan,
  V1beta2ReservedCapacityScope
} from 'dbaas/services/api-clients/v2025/tidb-management/v1beta2/interface'
import useStores from 'dbaas/stores/useStores'
// import { formatToK } from 'dbaas/utils/format'

interface PremiumReservedCapacityEditModalProps {
  tidb: SharedTiDB
  opened: boolean
  onClose: () => void
}

export interface EditFormValueState {
  reservedCapacityTemplateId: string
}

interface CapacityOption {
  value: string
  label: string
  // peakQpsLabel: string
  purchasedVcpuLabel: string
  scope?: V1beta2ReservedCapacityScope
}

// const formatPeakQpsLabel = (peakQps?: string) =>
//   `Peak QPS up to about ${peakQps ? formatToK(peakQps).replace(/\.\d+\sK$/, ' K') : '-'}`

export const PremiumReservedCapacityEditModal = ({ tidb, opened, onClose }: PremiumReservedCapacityEditModalProps) => {
  const {
    store: {
      lastVisitLocation: { orgId, projectId }
    }
  } = useStores()

  const effectiveProjectId = tidb.computed.projectId || projectId

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

  const capacityOptions = useMemo<CapacityOption[]>(() => {
    return (capacityOptionsQuery.data ?? [])
      .filter((option) => !!option.id)
      .map((option) => ({
        value: option.id!,
        label: `${option.purchasedVcpu ?? '-'} vCPU`,
        // peakQpsLabel: '',
        purchasedVcpuLabel: `${option.purchasedVcpu ?? '-'} vCPU`,
        scope: option.scope
      }))
  }, [capacityOptionsQuery.data])

  const currentCapacityOptionValue = useMemo(() => {
    return tidb.reservedCapacity?.id ?? ''
  }, [tidb.reservedCapacity?.id])

  const [selectedCapacityOption, setSelectedCapacityOption] = useState<string | null>(null)
  const estimatePriceMutator = useTidbServiceEstimatePrice()
  const priceEstimateQuery = useQuery(
    ['premium-reserved-estimate-price', orgId, effectiveProjectId, tidb.regionId, selectedCapacityOption],
    () =>
      estimatePriceMutator.mutateAsync({
        data: {
          regionId: tidb.regionId,
          reservedCapacityTemplateId: selectedCapacityOption ?? undefined,
          servicePlan: Commonv1beta1ServicePlan.Premium_Reserved
        },
        params: {
          orgId,
          projectId: effectiveProjectId
        }
      }),
    {
      enabled: opened && !!(orgId && tidb.regionId && selectedCapacityOption),
      select: (data) => Number(data?.rcuCostMonthly || 0),
      keepPreviousData: true,
      refetchOnWindowFocus: false
    }
  )

  useEffect(() => {
    if (!opened) {
      setSelectedCapacityOption(null)

      return
    }

    setSelectedCapacityOption((previousValue) => {
      if (currentCapacityOptionValue) {
        if (!previousValue) {
          return currentCapacityOptionValue
        }

        return capacityOptions.some((option) => option.value === previousValue)
          ? previousValue
          : currentCapacityOptionValue
      }

      return capacityOptions.some((option) => option.value === previousValue)
        ? previousValue
        : (capacityOptions[0]?.value ?? null)
    })
  }, [capacityOptions, currentCapacityOptionValue, opened])

  const updator = useTidbServiceUpdateTidb({
    mutation: {
      onSuccess: async () => {
        if (tidb.tidbId) {
          const v2023QueryKey = getTiDBServiceGetTidbQueryKey(tidb.tidbId, { orgId })
          const v2025QueryKey = getTidbServiceGetTidbQueryKey(tidb.tidbId, {
            orgId,
            projectId: effectiveProjectId
          })

          notifier.success('Capacity updated successfully!')
          onClose()
          await Promise.all([
            queryClient.refetchQueries(v2023QueryKey, { exact: true }),
            queryClient.refetchQueries(v2025QueryKey, { exact: true })
          ])
        }
      },
      onError: (error) => {
        const errorMsgDom = getApiErrorMsgDom(error)

        notifier.error(errorMsgDom)
      }
    }
  })

  const onConfirm = useMemoizedFn(async () => {
    if (!orgId || !tidb?.tidbId || !selectedCapacityOption) {
      notifier.error(<div dangerouslySetInnerHTML={{ __html: 'Failed to update instance plan' }}></div>)
      return
    }

    return await updator.mutateAsync({
      tidbId: tidb.tidbId,
      data: {
        reservedCapacityTemplateId: selectedCapacityOption
      },
      params: {
        orgId,
        projectId: effectiveProjectId
      }
    })
  })

  return (
    <Modal
      centered
      size={640}
      opened={opened}
      onClose={onClose}
      closeOnClickOutside={false}
      title="Update Capacity"
      data-testid="premium-capacity-edit-modal"
    >
      <Stack gap="xl">
        <Typography variant="body-lg">
          Select a default capacity option for this instance. Contact PingCAP sales to do size estimation if you need a
          custom option.
        </Typography>
        <Select
          label="Available Capacity Options"
          placeholder={capacityOptionsQuery.isLoading ? 'Loading capacity options...' : 'Select a capacity option'}
          data={capacityOptions}
          renderOption={({ option }) => {
            const capacityOption = option as CapacityOption

            return (
              <Group justify="space-between" wrap="nowrap" gap={8}>
                <Group gap={4} wrap="wrap" sx={{ flex: 1 }}>
                  <Typography>{capacityOption.purchasedVcpuLabel}</Typography>
                  {/* <Typography c="carbon.6">{capacityOption.peakQpsLabel}</Typography> */}
                </Group>
                {capacityOption.scope && capacityOption.scope !== V1beta2ReservedCapacityScope.DEFAULT && (
                  <Badge variant="outline" size="xs" c="peacock.7" fw={500}>
                    customed
                  </Badge>
                )}
              </Group>
            )
          }}
          value={selectedCapacityOption}
          onChange={setSelectedCapacityOption}
          disabled={capacityOptionsQuery.isLoading || capacityOptions.length <= 1}
          data-testid="premium-capacity-options-select"
        />
      </Stack>

      <Divider mt={24} mx={-24} />
      <Flex align="center" justify="space-between" gap="md" mt="xl">
        <Stack gap={4}>
          {priceEstimateQuery.isLoading ? (
            <Typography variant="title-lg" c="carbon.9">
              Calculating...
            </Typography>
          ) : (
            <AnimatedNumber
              value={priceEstimateQuery.data ?? 0}
              format={{ maximumFractionDigits: 5, minimumFractionDigits: 2 }}
              prefix="$"
              suffix=" /month"
              c="carbon.9"
              fw={700}
              fz={20}
              sx={{
                '&::part(suffix)': {
                  color: 'var(--mantine-color-carbon-8)',
                  fontWeight: 400,
                  fontSize: 14,
                  marginLeft: 4
                }
              }}
            />
          )}
        </Stack>

        <Flex align="center" gap="md">
          <Button variant="default" onClick={onClose} data-testid="premium-capacity-edit-cancel-button">
            Cancel
          </Button>
          <Button
            disabled={!selectedCapacityOption || selectedCapacityOption === currentCapacityOptionValue}
            loading={updator.isLoading}
            onClick={onConfirm}
            data-testid="premium-capacity-edit-update-button"
          >
            Update
          </Button>
        </Flex>
      </Flex>
    </Modal>
  )
}
