import {
  mdiArrowUpBoldCircleOutline,
  mdiCheckCircleOutline,
  mdiCreditCardOutline,
  mdiRefresh,
} from '@mdi/js'
import axios from 'axios'
import Head from 'next/head'
import React, { ReactElement, useEffect, useState } from 'react'
import BaseButton from '../components/BaseButton'
import CardBox from '../components/CardBox'
import SectionMain from '../components/SectionMain'
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton'
import LayoutAuthenticated from '../layouts/Authenticated'
import { getPageTitle } from '../config'
import { SubscriptionPlan } from '../subscriptionPlans'

type SubscriptionStatusResponse = {
  subscription: {
    planId: string
    planName: string
    status: string
    effectiveStatus: string
    isActive: boolean
    trialEndsAt?: string | null
    trialDaysLeft?: number | null
    priceMonthly: number
    currency: string
  }
  usage: {
    monthlyReviewRequests: number
    businesses: number
    teamMembers: number
    paymentConnectors: number
    periodStart?: string
    periodEnd?: string
  }
  limits: SubscriptionPlan['limits']
  plans: SubscriptionPlan[]
}

const usageLabels: Array<{
  key: keyof SubscriptionStatusResponse['usage']
  limitKey: keyof SubscriptionPlan['limits']
  label: string
}> = [
  { key: 'monthlyReviewRequests', limitKey: 'monthlyReviewRequests', label: 'Review requests this month' },
  { key: 'businesses', limitKey: 'businesses', label: 'Businesses / locations' },
  { key: 'teamMembers', limitKey: 'teamMembers', label: 'Team members' },
  { key: 'paymentConnectors', limitKey: 'paymentConnectors', label: 'Connected payment providers' },
]

function formatDate(value?: string | null) {
  if (!value) return 'Not set'

  return new Intl.DateTimeFormat('en', {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  }).format(new Date(value))
}

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

export default function SubscriptionPage() {
  const [status, setStatus] = useState<SubscriptionStatusResponse | null>(null)
  const [isLoading, setIsLoading] = useState(true)
  const [selectingPlanId, setSelectingPlanId] = useState('')
  const [message, setMessage] = useState('')
  const [error, setError] = useState('')

  const loadStatus = async () => {
    setIsLoading(true)
    try {
      const response = await axios.get('/subscription/me')
      setStatus(response.data)
      setError('')
    } catch (requestError) {
      console.error('Failed to load subscription status:', requestError)
      setError('Could not load your subscription status. Please refresh and try again.')
    } finally {
      setIsLoading(false)
    }
  }

  useEffect(() => {
    loadStatus()
  }, [])

  const selectPlan = async (planId: string) => {
    setSelectingPlanId(planId)
    setError('')
    setMessage('')

    try {
      const response = await axios.post('/subscription/select-plan', { planId })
      setStatus(response.data)
      setMessage(`Your trial plan is now ${response.data.subscription.planName}.`)
    } catch (requestError) {
      console.error('Failed to select subscription plan:', requestError)
      if (axios.isAxiosError(requestError) && requestError.response?.data) {
        setError(String(requestError.response.data))
      } else {
        setError('Could not update your plan. Please try again.')
      }
    } finally {
      setSelectingPlanId('')
    }
  }

  const currentPlanId = status?.subscription.planId

  return (
    <>
      <Head>
        <title>{getPageTitle('Subscription')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={mdiCreditCardOutline}
          title='Subscription and limits'
          main
        >
          <BaseButton
            icon={mdiRefresh}
            label='Refresh'
            color='whiteDark'
            onClick={loadStatus}
          />
        </SectionTitleLineWithButton>

        {message && (
          <div className='mb-6 rounded-2xl border border-emerald-200 bg-emerald-50 p-4 text-emerald-900'>
            {message}
          </div>
        )}
        {error && (
          <div className='mb-6 rounded-2xl border border-rose-200 bg-rose-50 p-4 text-rose-900'>
            {error}
          </div>
        )}

        {isLoading && !status ? (
          <CardBox>Loading subscription details...</CardBox>
        ) : status ? (
          <>
            <CardBox className='mb-6 overflow-hidden border-0 bg-gradient-to-br from-slate-950 via-indigo-950 to-emerald-950 text-white shadow-2xl'>
              <div className='grid gap-6 lg:grid-cols-[1fr_0.8fr] lg:items-center'>
                <div>
                  <p className='text-sm font-black uppercase tracking-[0.3em] text-emerald-300'>
                    Current plan
                  </p>
                  <h2 className='mt-3 text-4xl font-black tracking-tight md:text-5xl'>
                    {status.subscription.planName}
                  </h2>
                  <p className='mt-3 max-w-2xl text-slate-200'>
                    Status: <strong>{status.subscription.effectiveStatus}</strong>. Trial ends {formatDate(status.subscription.trialEndsAt)}
                    {status.subscription.trialDaysLeft !== null && status.subscription.trialDaysLeft !== undefined
                      ? ` (${status.subscription.trialDaysLeft} days left)`
                      : ''}
                    .
                  </p>
                </div>
                <div className='rounded-3xl bg-white/10 p-6 ring-1 ring-white/15'>
                  <p className='text-sm font-bold text-slate-300'>Monthly price</p>
                  <p className='mt-2 text-5xl font-black'>${status.subscription.priceMonthly}</p>
                  <p className='mt-1 text-sm text-slate-300'>per month after trial</p>
                </div>
              </div>
            </CardBox>

            <div className='mb-6 grid gap-6 lg:grid-cols-2'>
              {usageLabels.map((item) => {
                const used = Number(status.usage[item.key]) || 0
                const limit = Number(status.limits[item.limitKey]) || 1
                const percent = Math.min(100, Math.round((used / limit) * 100))
                const isNearLimit = percent >= 80

                return (
                  <CardBox key={item.key} className='border-0 shadow-xl ring-1 ring-slate-200/70 dark:ring-dark-700'>
                    <div className='mb-3 flex items-center justify-between gap-3'>
                      <p className='font-black text-slate-900 dark:text-white'>{item.label}</p>
                      <p className={isNearLimit ? 'font-black text-amber-600' : 'font-black text-emerald-600'}>
                        {formatLimit(used)} / {formatLimit(limit)}
                      </p>
                    </div>
                    <div className='h-3 overflow-hidden rounded-full bg-slate-100 dark:bg-dark-800'>
                      <div
                        className={isNearLimit ? 'h-full rounded-full bg-amber-500' : 'h-full rounded-full bg-emerald-500'}
                        style={{ width: `${percent}%` }}
                      />
                    </div>
                  </CardBox>
                )
              })}
            </div>

            <div className='grid gap-6 lg:grid-cols-2'>
              {status.plans.map((plan) => {
                const isCurrent = currentPlanId === plan.id
                const isPro = plan.id === 'pro'

                return (
                  <CardBox
                    key={plan.id}
                    className={`relative overflow-hidden border-0 shadow-2xl ${isPro ? 'ring-2 ring-indigo-600' : 'ring-1 ring-slate-200 dark:ring-dark-700'}`}
                    cardBoxClassName='p-0'
                  >
                    {isPro && (
                      <div className='absolute right-6 top-6 rounded-full bg-indigo-600 px-4 py-1 text-sm font-black text-white'>
                        Pro growth tools
                      </div>
                    )}
                    <div className='p-8'>
                      <p className='text-sm font-black uppercase tracking-[0.3em] text-slate-400'>Review Flow</p>
                      <h3 className='mt-3 text-3xl font-black text-slate-900 dark:text-white'>{plan.name}</h3>
                      <p className='mt-3 min-h-[56px] leading-7 text-slate-500 dark:text-slate-400'>{plan.tagline}</p>
                      <div className='mt-8 flex items-end gap-2'>
                        <span className='text-5xl font-black tracking-tight text-slate-900 dark:text-white'>${plan.priceMonthly}</span>
                        <span className='pb-2 font-bold text-slate-500'>/month</span>
                      </div>
                      <div className='mt-8 grid gap-3 rounded-3xl bg-slate-50 p-5 dark:bg-dark-800 sm:grid-cols-2'>
                        <div>
                          <p className='text-2xl font-black'>{formatLimit(plan.limits.monthlyReviewRequests)}</p>
                          <p className='text-sm text-slate-500'>requests/month</p>
                        </div>
                        <div>
                          <p className='text-2xl font-black'>{formatLimit(plan.limits.businesses)}</p>
                          <p className='text-sm text-slate-500'>businesses</p>
                        </div>
                        <div>
                          <p className='text-2xl font-black'>{formatLimit(plan.limits.teamMembers)}</p>
                          <p className='text-sm text-slate-500'>team members</p>
                        </div>
                        <div>
                          <p className='text-2xl font-black'>{formatLimit(plan.limits.paymentConnectors)}</p>
                          <p className='text-sm text-slate-500'>connectors</p>
                        </div>
                      </div>
                      <BaseButton
                        icon={isCurrent ? mdiCheckCircleOutline : mdiArrowUpBoldCircleOutline}
                        label={isCurrent ? 'Current plan' : `Switch trial to ${plan.name}`}
                        color={isCurrent ? 'success' : isPro ? 'info' : 'whiteDark'}
                        className='mt-8 w-full'
                        disabled={isCurrent || Boolean(selectingPlanId)}
                        onClick={() => selectPlan(plan.id)}
                      />
                    </div>
                    <div className={isPro ? 'bg-indigo-950 p-8 text-white' : 'bg-slate-950 p-8 text-white'}>
                      <p className='mb-5 text-sm font-black uppercase tracking-[0.25em] text-emerald-300'>Included</p>
                      <div className='grid gap-3'>
                        {plan.features.map((feature) => (
                          <div key={feature} className='flex items-start gap-3'>
                            <span className='mt-1 text-emerald-300'>✓</span>
                            <span className='font-semibold text-slate-100'>{feature}</span>
                          </div>
                        ))}
                      </div>
                    </div>
                  </CardBox>
                )
              })}
            </div>
          </>
        ) : null}
      </SectionMain>
    </>
  )
}

SubscriptionPage.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated>{page}</LayoutAuthenticated>
}
