// Billing — URL `/billing`. The current plan (live from `billing.subscription`),
// a card-management button that redirects to the PROVIDER's hosted portal
// (`billing.portalUrl`), and a plan change that QUOTES the provider's prorated
// settlement first (`billing.previewChange`) before applying it
// (`billing.changePlan`) — never a locally-estimated figure.
import type { ReactNode } from 'react'
import { useState } from 'react'
import type { PageMeta } from '@voltro/web'
import { useSubscription, useAction } from '@voltro/client'
import { T, useLocale, useT } from '@voltro/i18n'
import { getCatalog } from '../../../locales/index'
import { formatMoney, type ChangePreview, type SubscriptionState } from '../../../lib/api'

export const renderMode = 'ssr' as const

export const meta = ({ locale }: { readonly locale: string }): PageMeta => ({
  title: getCatalog(locale)['meta.billing.title'],
})

// The plan a free tenant upgrades to — matches api-saas-starter's `plans`.
const UPGRADE_PLAN = 'pro'

export default function Billing(): ReactNode {
  const locale = useLocale()
  const { data } = useSubscription<SubscriptionState>('app', 'billing.subscription')
  const portal = useAction<{ returnUrl: string }, { url: string }>('app', 'billing.portalUrl')
  const preview = useAction<{ plan?: string; quantity?: number }, ChangePreview>('app', 'billing.previewChange')
  const change = useAction<{ plan: string }, ChangePreview>('app', 'billing.changePlan')

  const [quote, setQuote] = useState<ChangePreview | null>(null)
  const [changed, setChanged] = useState(false)
  const sub = data?.subscription ?? null
  const freeLabel = useT('billing.plan.free')
  const busy = portal.pending || preview.pending || change.pending

  const onManageCard = (): void => {
    const here = typeof window === 'undefined' ? '/billing' : window.location.href
    void portal.run({ returnUrl: here })
      .then((r) => { if (r && typeof window !== 'undefined') window.location.assign(r.url) })
      .catch(() => { /* surfaced via portal.error */ })
  }

  const onPreview = (): void => {
    setChanged(false)
    void preview.run({ plan: UPGRADE_PLAN }).then((q) => setQuote(q)).catch(() => setQuote(null))
  }

  const onConfirm = (): void => {
    void change.run({ plan: UPGRADE_PLAN }).then(() => { setChanged(true); setQuote(null) }).catch(() => { /* change.error */ })
  }

  return (
    <section>
      <h1><T id="billing.heading" /></h1>

      <dl className="facts">
        <dt><T id="billing.plan.label" /></dt>
        <dd>{sub?.plan ?? freeLabel}</dd>
        <dt><T id="billing.status.label" /></dt>
        <dd>{sub?.status ?? '—'}</dd>
        <dt><T id="billing.seats.label" /></dt>
        <dd>{sub?.quantity ?? 1}</dd>
      </dl>

      <div className="row" style={{ marginTop: '1.25rem' }}>
        <button type="button" className="btn ghost" disabled={busy} onClick={onManageCard}>
          <T id="billing.card.manage" />
        </button>
      </div>

      <div className="paywall" style={{ marginTop: '1.5rem' }}>
        <strong><T id="billing.change.title" /></strong>
        <p className="muted"><T id="billing.change.body" /></p>
        {quote ? (
          <p role="status">
            <T
              id="billing.change.quote"
              values={{ amount: formatMoney(Math.abs(quote.prorationMinor), quote.currency, locale) }}
            />
          </p>
        ) : null}
        {changed ? <p className="ok" role="status"><T id="billing.change.done" /></p> : null}
        <div className="row">
          {quote ? (
            <button type="button" className="btn" disabled={busy} onClick={onConfirm}>
              <T id={change.pending ? 'billing.pending' : 'billing.change.confirm'} />
            </button>
          ) : (
            <button type="button" className="btn" disabled={busy} onClick={onPreview}>
              <T id={preview.pending ? 'billing.pending' : 'billing.change.preview'} />
            </button>
          )}
        </div>
      </div>
    </section>
  )
}
