import { Alert, AlertProps, Box, Typography } from '@tidbcloud/uikit'
import { useLocalStorage } from '@tidbcloud/uikit/hooks'
import { IconLinkExternal01 } from '@tidbcloud/uikit/icons'
import { Color } from '@tidbcloud/uikit/theme'
import Dompurify from 'dompurify'
import { observer } from 'mobx-react'
import { useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'

import config from 'config'
import { AccessGuard, useAccessCheck } from 'dbaas/contexts/access-control'
import { OrgPlanStatus } from 'dbaas/screens/Plans/constant'
import { useGetGlobalNotice } from 'dbaas/services'
import { useMeta } from 'dbaas/services/account'
import auth from 'dbaas/services/auth'
import { useGetTenantsCreditsSummary, useListBillingConfigs, useListTenantsCredits } from 'dbaas/services/billing'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

import { MoneyValue } from './MoneyValue'

const NOTIFICATION_LEVEL = {
  DANGER: 0,
  WARNING: 1,
  SUCCESS: 2,
  INFO: 3
} as const

const NOTIFICATION_COLOR: Record<number, Color> = {
  [NOTIFICATION_LEVEL.DANGER]: 'red',
  [NOTIFICATION_LEVEL.WARNING]: 'yellow',
  [NOTIFICATION_LEVEL.SUCCESS]: 'green',
  [NOTIFICATION_LEVEL.INFO]: 'peacock'
}

export const TrialUserBanner = observer(() => {
  const {
    store: {
      tenantData: { plan, id: orgId }
    },
    actions: { toggleNotification }
  } = useStores()

  const [extendedCreditsVisible, setExtendedCreditsVisible] = useLocalStorage({
    key: 'dbaas-ui.extended_credits_bannber',
    defaultValue: true
  })

  const [mfaNoticeVisible, setMFANoticeVisible] = useLocalStorage<null | boolean>({
    key: 'dbaas-ui.mfa_notice_banner',
    defaultValue: null
  })

  const billingBannerEnabled = useAccessCheck('OrgBillingGate')

  const { data: billingConfigs } = useListBillingConfigs(orgId, {
    query: {
      enabled: extendedCreditsVisible && billingBannerEnabled,
      refetchOnWindowFocus: false,
      refetchInterval: false
    }
  })

  const activeBillingConfig = useMemo(() => {
    return (billingConfigs || []).find((cfg) => cfg.status === 'Active')!
  }, [billingConfigs])

  const { data: credits } = useListTenantsCredits(orgId, activeBillingConfig?.billing_config_id, {
    query: {
      enabled: !!activeBillingConfig && !!activeBillingConfig.billing_config_id && extendedCreditsVisible,
      refetchOnWindowFocus: false,
      refetchInterval: false
    }
  })

  const { data: creditsSummary } = useGetTenantsCreditsSummary(orgId, activeBillingConfig?.billing_config_id, {
    query: {
      enabled: !!activeBillingConfig && !!activeBillingConfig.billing_config_id,
      refetchOnWindowFocus: false,
      refetchInterval: false
    }
  })

  const extendedCredits = (credits || []).find((c) => c.usage === 'program' && c.usage_extend === 'github_campaign')

  const [globalNoticeVisible, setGlobalNoticeVisible] = useState<null | boolean>(null)
  const [billingNoticeVisible, setBillingNoticeVisible] = useState<null | boolean>(null)

  const { data, isLoading } = useGetGlobalNotice({
    query: {
      enabled: config.ENABLE_GLOBAL_NOTICE,
      refetchInterval: 2 * 60 * 1000,
      onSuccess(data) {
        const hasNotice = !!data?.notice
        if (globalNoticeVisible === null && hasNotice) {
          setGlobalNoticeVisible(true)
        }
        // turn off notice by server
        if (globalNoticeVisible === true && !hasNotice) {
          setGlobalNoticeVisible(false)
        }
      }
    }
  })
  // @TODO remove this after 2025.03.31
  const { data: _mfaData } = useMeta({
    query: {
      enabled: mfaNoticeVisible === null,
      refetchInterval: 10 * 60 * 1000,
      onSuccess(data) {
        const connectionType = auth.getConnectionType()
        if (data.use_mfa && connectionType !== 'EMAIL') {
          if (mfaNoticeVisible === null) {
            setMFANoticeVisible(true)
          }
        } else {
          setMFANoticeVisible(false)
        }
      }
    }
  })

  const remainingCredit = Math.max(Number(creditsSummary?.available_remaining_credits || '0'), 0)

  const handleDismiss = () => {
    setBillingNoticeVisible(false)
  }

  const creditCardLink = (
    <AccessGuard
      id="BillingPaymentCreation"
      fallback="contact your organization Owner or Billing Manager to add a credit card"
    >
      <Box component={Link} to="/org-settings/billing/payments">
        add a credit card
      </Box>
    </AccessGuard>
  )

  useEffect(() => {
    // show notification for POC user
    if (billingNoticeVisible === null && billingBannerEnabled && plan === OrgPlanStatus.POC) {
      setBillingNoticeVisible(true)
    }
    // turn off notice by server
    if (billingNoticeVisible === true && plan !== OrgPlanStatus.POC) {
      setBillingNoticeVisible(false)
    }
  }, [plan, billingNoticeVisible, billingBannerEnabled])

  // sync store notification
  useEffect(() => {
    toggleNotification(!!globalNoticeVisible || !!billingNoticeVisible)
  }, [globalNoticeVisible, billingNoticeVisible, toggleNotification])

  useEffect(() => {
    if (extendedCredits && extendedCreditsVisible) {
      eventTracking('Show github campaign banner')
    }
  }, [extendedCreditsVisible, extendedCredits])

  if (isLoading) {
    return null
  }

  const styles: AlertProps['styles'] = {
    root: { borderLeft: 'none !important' }
  }

  const isNotificationVisible =
    globalNoticeVisible || billingNoticeVisible || (extendedCreditsVisible && extendedCredits) || mfaNoticeVisible
  let currentNotification: React.ReactNode | null = null

  if (mfaNoticeVisible) {
    currentNotification = (
      <Alert
        withCloseButton
        onClose={() => setMFANoticeVisible(false)}
        styles={styles}
        color={NOTIFICATION_COLOR[NOTIFICATION_LEVEL.WARNING]}
      >
        <Typography ta="center">
          You are logging in to TIDB Cloud based on SSO, so please switch the MFA configuration in SSO Management
          Platform as soon as possible and go to <Link to="/account/general">Account to disable MFA </Link> here before
          September 30, 2025.
        </Typography>
      </Alert>
    )
  }

  if (extendedCreditsVisible && extendedCredits) {
    currentNotification = (
      <Alert
        withCloseButton
        onClose={() => {
          eventTracking('Close github campaign banner')
          setExtendedCreditsVisible(false)
        }}
        styles={styles}
        color="peacock"
      >
        <Box m="0 auto" pr="xs" w="fit-content">
          Welcome! You have successfully claimed{' '}
          <strong>
            <MoneyValue amount={extendedCredits.total_credits || '0'} />
          </strong>{' '}
          free credits.
          <Box
            sx={{ display: 'inline-flex', alignItems: 'center', verticalAlign: 'top', gap: 4 }}
            ml="md"
            fw={600}
            component="a"
            target="_blank"
            href="https://docs.pingcap.com/tidbcloud/tidb-cloud-billing#credits"
          >
            <IconLinkExternal01 size={16} />
            Use the credits
          </Box>
          <Box component={Link} ml="md" fw={600} to="/org-settings/billing/credits">
            Check my credits
          </Box>
        </Box>
      </Alert>
    )
  }

  if (billingNoticeVisible) {
    currentNotification = (
      <Alert withCloseButton onClose={handleDismiss} styles={styles} color="peacock">
        <Box m="0 auto" pr="xs" w="fit-content">
          Welcome to TiDB Cloud! You currently have{' '}
          <strong>
            <MoneyValue amount={remainingCredit} />
          </strong>{' '}
          credits left for your free trial. You can also {creditCardLink} to extend use of your TiDB database.
        </Box>
      </Alert>
    )
  }

  if (globalNoticeVisible) {
    currentNotification = (
      <Alert
        withCloseButton
        onClose={() => setGlobalNoticeVisible(false)}
        styles={styles}
        color={NOTIFICATION_COLOR[data?.level ?? NOTIFICATION_LEVEL.INFO]}
      >
        <Box
          m="0 auto"
          pr="xs"
          w="fit-content"
          dangerouslySetInnerHTML={{ __html: Dompurify.sanitize(data?.notice || '') }}
        ></Box>
      </Alert>
    )
  }

  return isNotificationVisible ? (
    <>
      <div className="driver-placeholder-notification"></div>
      {currentNotification}
    </>
  ) : null
})

export default TrialUserBanner
