import { mdiCreditCardOutline } from '@mdi/js'
import axios from 'axios'
import React, { useEffect, useState } from 'react'
import BaseButton from './BaseButton'
import CardBox from './CardBox'
import { useAppSelector } from '../stores/hooks'
import { isInternalAdmin } from '../helpers/portalRoles'

type LimitKey = 'monthlyReviewRequests' | 'businesses' | 'teamMembers' | 'paymentConnectors'

type SubscriptionLimitStatus = {
  subscription: {
    planId: string
    planName: string
    effectiveStatus: string
    isActive: boolean
  }
  usage: Record<LimitKey, number>
  limits: Record<LimitKey, number>
}

type Props = {
  limitKey: LimitKey
  actionLabel: string
  label?: string
  className?: string
  nearLimitPercent?: number
}

const defaultLabels: Record<LimitKey, string> = {
  monthlyReviewRequests: 'review requests this month',
  businesses: 'business profiles',
  teamMembers: 'team members',
  paymentConnectors: 'connected payment providers',
}

function formatNumber(value: number) {
  return value.toLocaleString()
}

export default function SubscriptionLimitGate({
  limitKey,
  actionLabel,
  label,
  className = 'mb-6',
  nearLimitPercent = 80,
}: Props) {
  const { currentUser } = useAppSelector((state) => state.auth)
  const [status, setStatus] = useState<SubscriptionLimitStatus | null>(null)
  const [error, setError] = useState('')

  useEffect(() => {
    let isMounted = true

    const loadStatus = async () => {
      try {
        const response = await axios.get('/subscription/me')

        if (isMounted) {
          setStatus(response.data)
          setError('')
        }
      } catch (requestError) {
        console.error('Failed to load subscription limit status:', requestError)

        if (isMounted) {
          setError('Could not check plan limits right now. The backend will still enforce them when you submit.')
        }
      }
    }

    if (!currentUser || isInternalAdmin(currentUser)) {
      setStatus(null)
      setError('')
      return () => {
        isMounted = false
      }
    }

    loadStatus()

    return () => {
      isMounted = false
    }
  }, [currentUser])

  if (error) {
    return (
      <CardBox className={`${className} border-0 bg-amber-50 text-amber-950 ring-1 ring-amber-200 dark:bg-amber-950 dark:text-amber-50 dark:ring-amber-800`}>
        <p className='text-sm font-black uppercase tracking-[0.25em]'>Plan check unavailable</p>
        <p className='mt-2 text-sm leading-6'>{error}</p>
      </CardBox>
    )
  }

  if (!status) {
    return null
  }

  const used = Number(status.usage[limitKey]) || 0
  const limit = Number(status.limits[limitKey]) || 0
  const limitLabel = label || (limit === 1 && limitKey === 'businesses'
    ? 'business profile'
    : defaultLabels[limitKey])
  const percent = limit > 0 ? Math.round((used / limit) * 100) : 0
  const isInactive = !status.subscription.isActive
  const isBlocked = isInactive || (limit > 0 && used >= limit)
  const isNearLimit = !isBlocked && percent >= nearLimitPercent

  if (!isBlocked && !isNearLimit) {
    return null
  }

  const cardClass = isBlocked
    ? 'border-0 bg-rose-50 text-rose-950 ring-1 ring-rose-200 dark:bg-rose-950 dark:text-rose-50 dark:ring-rose-800'
    : 'border-0 bg-amber-50 text-amber-950 ring-1 ring-amber-200 dark:bg-amber-950 dark:text-amber-50 dark:ring-amber-800'
  const buttonLabel = status.subscription.planId === 'starter' ? 'Upgrade to Pro' : 'Manage plan'

  return (
    <CardBox className={`${className} ${cardClass}`}>
      <div className='flex flex-col gap-4 md:flex-row md:items-center md:justify-between'>
        <div>
          <p className='text-sm font-black uppercase tracking-[0.25em]'>
            {isBlocked ? 'Plan limit reached' : 'Plan limit almost reached'}
          </p>
          <h3 className='mt-2 text-xl font-black'>
            {actionLabel} {isBlocked ? 'may be blocked' : 'is getting close to the limit'}
          </h3>
          <p className='mt-2 text-sm leading-6'>
            {isInactive
              ? `Your ${status.subscription.planName} plan is ${status.subscription.effectiveStatus}. Reactivate or choose a plan before continuing.`
              : `${status.subscription.planName} includes ${formatNumber(limit)} ${limitLabel}. This account is using ${formatNumber(used)}.`}
            {' '}Existing data stays available.
          </p>
        </div>
        <BaseButton
          href='/subscription'
          icon={mdiCreditCardOutline}
          label={buttonLabel}
          color={isBlocked ? 'danger' : 'warning'}
          className='self-start md:self-center'
        />
      </div>
    </CardBox>
  )
}
