import { AdminPageHeader, adminLayout } from '@/Layouts/AdminLayout';
import { Button, Card, Modal, Pill, Radio, Select } from '@/Components/ui';
import { cn } from '@/lib/cn';
import {
    providerLabel,
    subscriptionDashboardUrl,
} from '@/lib/providerDashboard';
import { StatusBadge } from '@/Pages/Admin/Subscriptions/Index';
import { Head, Link, router } from '@inertiajs/react';
import { AlertCircle, ExternalLink, Loader2 } from 'lucide-react';
import { useState } from 'react';

const PLAN_TONES: Record<string, 'accent' | 'neutral'> = {
    pro: 'accent',
    scale: 'accent',
    free: 'neutral',
};

type SubscriptionDetail = {
    id: number;
    user: { id: number | null; email: string | null; name: string | null; deleted: boolean };
    plan: { id: number | null; key: string | null; name: string | null };
    provider_key: string;
    provider_subscription_id: string | null;
    period: string;
    status: string;
    trial_ends_at: string | null;
    current_period_starts_at: string | null;
    current_period_ends_at: string | null;
    canceled_at: string | null;
    cancels_at_period_end: boolean;
    created_at: string | null;
    seats: number;
    /** Set for pending Razorpay subs awaiting customer authorization —
     *  the URL admin can copy/email to direct the customer to checkout. */
    pending_checkout_url: string | null;
};

type InvoiceRow = {
    id: number;
    provider_key: string;
    provider_invoice_id: string;
    amount_cents: number;
    currency: string;
    status: string;
    paid_at: string | null;
    hosted_url: string | null;
    created_at: string | null;
};

type AuditEntry = {
    id: number;
    action: string;
    summary: string | null;
    context: Record<string, unknown> | null;
    created_at: string | null;
    actor: { id: number; name: string; email: string } | null;
};

type PlanOption = { id: number; key: string; name: string };

type Props = {
    subscription: SubscriptionDetail;
    invoices: InvoiceRow[];
    auditLogs: AuditEntry[];
    auditLogsTotal: number;
    plans: PlanOption[];
};

// Mirrors the server-side gate in Admin\SubscriptionsController::changePlan.
// Plan swap only makes sense on a sub that's actually running — providers
// reject it on incomplete/canceled subs and our Razorpay fallback would
// destructively create yet another pending sub if we let it through.
function planChangeable(status: string): boolean {
    return ['active', 'trialing', 'past_due', 'authenticated'].includes(status);
}

function formatCents(cents: number, currency: string): string {
    const major = cents / 100;
    if (currency === 'INR') {
        return `₹${major.toLocaleString('en-IN', {
            maximumFractionDigits: major % 1 === 0 ? 0 : 2,
            minimumFractionDigits: major % 1 === 0 ? 0 : 2,
        })}`;
    }
    try {
        return new Intl.NumberFormat('en-US', {
            style: 'currency',
            currency: currency || 'USD',
            maximumFractionDigits: 2,
        }).format(major);
    } catch {
        return `${major.toFixed(2)} ${currency}`;
    }
}

function formatDate(iso: string | null): string {
    if (!iso) return '—';
    try {
        return new Date(iso).toLocaleString('en-US', {
            year: 'numeric',
            month: 'short',
            day: 'numeric',
            hour: '2-digit',
            minute: '2-digit',
        });
    } catch {
        return iso;
    }
}

function csrfHeaders(): Record<string, string> {
    const xsrf = document
        .querySelector('meta[name="csrf-token"]')
        ?.getAttribute('content');
    const cookieMatch = document.cookie.match(/(?:^|;\s*)XSRF-TOKEN=([^;]+)/);
    const cookieToken = cookieMatch ? decodeURIComponent(cookieMatch[1]) : null;
    const headers: Record<string, string> = {
        'Content-Type': 'application/json',
        Accept: 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
    };
    if (xsrf) headers['X-CSRF-TOKEN'] = xsrf;
    if (cookieToken) headers['X-XSRF-TOKEN'] = cookieToken;
    return headers;
}

function AdminSubscriptionsShow({
    subscription,
    invoices,
    auditLogs,
    auditLogsTotal,
    plans,
}: Props) {
    const [actionError, setActionError] = useState<string | null>(null);
    const [actionNotice, setActionNotice] = useState<string | null>(null);
    const [busy, setBusy] = useState(false);
    const [cancelOpen, setCancelOpen] = useState(false);
    const [planOpen, setPlanOpen] = useState(false);

    const post = async (path: string, body: Record<string, unknown> = {}) => {
        setBusy(true);
        setActionError(null);
        setActionNotice(null);
        try {
            const res = await fetch(path, {
                method: 'POST',
                credentials: 'same-origin',
                headers: csrfHeaders(),
                body: JSON.stringify(body),
            });
            if (!res.ok) {
                const j = await res.json().catch(() => null);
                setActionError(j?.message ?? `Request failed (${res.status}).`);
                return false;
            }
            const j = (await res.json().catch(() => null)) as
                | { redirect_url?: string | null }
                | null;
            // Provider needs customer-side auth (Stripe 3DS / Razorpay
            // re-checkout). Admin can't authenticate for the customer —
            // surface the URL so they can copy/email it.
            if (j?.redirect_url) {
                setActionNotice(
                    `Customer must complete payment authorization at: ${j.redirect_url}`,
                );
            }
            router.reload({ only: ['subscription', 'auditLogs'] });
            return true;
        } catch {
            setActionError('Network error.');
            return false;
        } finally {
            setBusy(false);
        }
    };

    const onResume = () => {
        void post(`/admin/subscriptions/${subscription.id}/resume`);
    };

    const dashboardUrl = subscriptionDashboardUrl(
        subscription.provider_key,
        subscription.provider_subscription_id,
    );
    const providerName = providerLabel(subscription.provider_key);

    return (
        <>
            <Head title={`Admin · Subscription #${subscription.id}`} />
            <AdminPageHeader
                title={`Subscription #${subscription.id}`}
                description={subscription.user.email ?? undefined}
                actions={
                    <Link
                        href="/admin/subscriptions"
                        className="text-[11px] font-medium text-muted-foreground hover:text-foreground"
                    >
                        ← All subscriptions
                    </Link>
                }
            />
                {actionError && (
                    <div
                        className="mb-4 flex items-start gap-2 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-[12px] font-medium text-destructive"
                        role="alert"
                        data-testid="admin-subscription-error"
                    >
                        <AlertCircle className="mt-0.5 h-3.5 w-3.5" strokeWidth={2.5} />
                        <span>{actionError}</span>
                    </div>
                )}

                {actionNotice && (
                    <div
                        className="mb-4 rounded-lg border border-warning/30 bg-warning/10 px-3 py-3"
                        role="status"
                        data-testid="admin-subscription-notice"
                    >
                        <div className="flex items-start gap-2 text-[12px]">
                            <AlertCircle
                                className="mt-0.5 h-3.5 w-3.5 shrink-0 text-warning"
                                strokeWidth={2.5}
                            />
                            <div className="flex-1">
                                <p className="font-medium text-warning">
                                    Customer authentication required
                                </p>
                                <p className="mt-1 text-muted-foreground">
                                    The plan change is staged but the customer must
                                    complete payment authorization. Subscription will
                                    stay in pending state until they do.
                                </p>
                                <p className="mt-2 break-all font-mono text-[11px] text-foreground">
                                    {actionNotice.replace(
                                        /^Customer must complete payment authorization at: /,
                                        '',
                                    )}
                                </p>
                            </div>
                        </div>
                    </div>
                )}

                {/* Persistent companion to actionNotice — shows on every
                    page load while a Razorpay sub stays in pending state.
                    actionNotice is the transient post-action confirmation;
                    this is the permanent recovery affordance for admins
                    who land on a sub that's been pending since a previous
                    session (abandoned checkout, in-flight upgrade, etc). */}
                {!actionNotice && subscription.pending_checkout_url && (
                    <div
                        className="mb-4 rounded-lg border border-warning/30 bg-warning/10 px-3 py-3"
                        role="status"
                        data-testid="admin-subscription-pending-recovery"
                    >
                        <div className="flex items-start gap-2 text-[12px]">
                            <AlertCircle
                                className="mt-0.5 h-3.5 w-3.5 shrink-0 text-warning"
                                strokeWidth={2.5}
                            />
                            <div className="flex-1">
                                <p className="font-medium text-warning">
                                    Pending — awaiting customer payment
                                </p>
                                <p className="mt-1 text-muted-foreground">
                                    This Razorpay subscription was created but the
                                    customer hasn't authorized payment yet. Send them
                                    this link to complete checkout, or use Cancel to
                                    discard the unauthorized sub.
                                </p>
                                <div className="mt-2 flex flex-wrap items-start gap-2">
                                    <p className="break-all font-mono text-[11px] text-foreground">
                                        {subscription.pending_checkout_url}
                                    </p>
                                    <button
                                        type="button"
                                        onClick={() => {
                                            void navigator.clipboard?.writeText(
                                                subscription.pending_checkout_url ?? '',
                                            );
                                        }}
                                        className="rounded border border-warning/30 bg-warning/10 px-2 py-0.5 text-[11px] font-medium text-warning hover:bg-warning/20"
                                        data-testid="admin-subscription-pending-copy"
                                    >
                                        Copy
                                    </button>
                                    <a
                                        href={subscription.pending_checkout_url}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                        className="inline-flex items-center gap-1 rounded border border-warning/30 bg-warning/10 px-2 py-0.5 text-[11px] font-medium text-warning hover:bg-warning/20"
                                    >
                                        Open
                                        <ExternalLink className="h-3 w-3" strokeWidth={2} />
                                    </a>
                                </div>
                            </div>
                        </div>
                    </div>
                )}

                <div className="grid gap-4 lg:grid-cols-3">
                    <div className="space-y-4 lg:col-span-2">
                        <Card padding="lg" data-testid="admin-subscription-header">
                            <div className="flex items-start justify-between gap-3">
                                <div>
                                    <div className="flex items-center gap-2">
                                        <StatusBadge status={subscription.status} />
                                        {subscription.cancels_at_period_end && (
                                            <span className="rounded-full border border-warning/30 bg-warning/10 px-2 py-0.5 text-[11px] font-medium text-warning">
                                                Cancels at period end
                                            </span>
                                        )}
                                    </div>
                                    <div className="mt-3 flex items-center gap-2">
                                        <h2 className="text-lg font-semibold tracking-tight text-foreground">
                                            {subscription.plan.name ?? 'Plan'}
                                        </h2>
                                        {subscription.plan.key && (
                                            <Pill
                                                tone={
                                                    PLAN_TONES[subscription.plan.key] ?? 'neutral'
                                                }
                                                size="sm"
                                            >
                                                {subscription.plan.key.toUpperCase()}
                                            </Pill>
                                        )}
                                    </div>
                                    <div className="mt-2 flex flex-wrap items-center gap-1.5">
                                        <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase text-muted-foreground">
                                            {subscription.period}
                                        </span>
                                        <span className="rounded bg-muted px-1.5 py-0.5 font-mono text-[10px] font-medium uppercase text-muted-foreground">
                                            {subscription.provider_key}
                                        </span>
                                    </div>
                                </div>
                                {dashboardUrl && (
                                    <a
                                        href={dashboardUrl}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                        className="inline-flex items-center gap-1 text-[11px] font-medium text-accent hover:underline"
                                        data-testid="admin-subscription-provider-link"
                                    >
                                        Open in {providerName}
                                        <ExternalLink className="h-3 w-3" strokeWidth={2} />
                                    </a>
                                )}
                            </div>
                            {subscription.provider_subscription_id && (
                                <p className="mt-3 font-mono text-[11px] text-muted-foreground">
                                    {subscription.provider_subscription_id}
                                </p>
                            )}
                        </Card>

                        <Card padding="lg" data-testid="admin-subscription-timeline">
                            <h3 className="text-[11px] font-medium text-muted-foreground">
                                Timeline
                            </h3>
                            <dl className="mt-3 grid gap-3 text-[12px] sm:grid-cols-2">
                                <TimelineRow label="Created" value={formatDate(subscription.created_at)} />
                                <TimelineRow label="Trial ends" value={formatDate(subscription.trial_ends_at)} />
                                <TimelineRow label="Period starts" value={formatDate(subscription.current_period_starts_at)} />
                                <TimelineRow label="Period ends" value={formatDate(subscription.current_period_ends_at)} />
                                <TimelineRow label="Canceled" value={formatDate(subscription.canceled_at)} />
                                <TimelineRow
                                    label="Cancels at period end"
                                    value={subscription.cancels_at_period_end ? 'Yes' : 'No'}
                                />
                            </dl>
                        </Card>

                        <Card padding="lg" data-testid="admin-subscription-invoices">
                            <div className="flex items-baseline justify-between">
                                <h3 className="text-[11px] font-medium text-muted-foreground">
                                    Recent invoices
                                </h3>
                                <Link
                                    href="/admin/invoices"
                                    className="text-[11px] font-medium text-muted-foreground hover:text-foreground"
                                >
                                    All invoices →
                                </Link>
                            </div>
                            {invoices.length === 0 ? (
                                <p
                                    className="mt-4 text-[12px] text-muted-foreground"
                                    data-testid="admin-subscription-invoices-empty"
                                >
                                    No invoices yet.
                                </p>
                            ) : (
                                <table className="mt-3 w-full text-sm">
                                    <thead>
                                        <tr className="text-left text-[10px] font-medium uppercase tracking-wide text-muted-foreground">
                                            <th className="py-2 pr-3">Invoice</th>
                                            <th className="py-2 pr-3 text-right">Amount</th>
                                            <th className="py-2 pr-3">Status</th>
                                            <th className="py-2 pr-3">Paid</th>
                                            <th className="w-16 py-2" />
                                        </tr>
                                    </thead>
                                    <tbody>
                                        {invoices.map((inv) => (
                                            <tr
                                                key={inv.id}
                                                className="border-t border-border/60"
                                                data-testid={`admin-subscription-invoice-${inv.id}`}
                                            >
                                                <td className="py-2 pr-3">
                                                    <Link
                                                        href={`/admin/invoices/${inv.id}`}
                                                        className="font-mono text-[11px] text-foreground/80 hover:text-accent"
                                                    >
                                                        {inv.provider_invoice_id}
                                                    </Link>
                                                </td>
                                                <td className="py-2 pr-3 text-right tabular-nums text-foreground/80">
                                                    {formatCents(inv.amount_cents, inv.currency)}
                                                </td>
                                                <td className="py-2 pr-3">
                                                    <StatusBadge status={inv.status} />
                                                </td>
                                                <td className="py-2 pr-3 text-[11px] text-muted-foreground">
                                                    {formatDate(inv.paid_at)}
                                                </td>
                                                <td className="py-2 text-right">
                                                    <Link
                                                        href={`/admin/invoices/${inv.id}`}
                                                        className="text-[11px] font-medium text-accent hover:underline"
                                                    >
                                                        Open
                                                    </Link>
                                                </td>
                                            </tr>
                                        ))}
                                    </tbody>
                                </table>
                            )}
                        </Card>

                        <Card padding="lg" data-testid="admin-subscription-audit">
                            <div className="flex items-baseline justify-between gap-3">
                                <h3 className="flex items-baseline gap-2 text-[11px] font-medium text-muted-foreground">
                                    Audit log
                                    {auditLogsTotal > 0 && (
                                        <span className="text-[11px] text-muted-foreground">
                                            {auditLogsTotal}
                                        </span>
                                    )}
                                </h3>
                                {auditLogsTotal > auditLogs.length && (
                                    <Link
                                        href={`/admin/audit-log?target_type=Subscription&target_id=${subscription.id}`}
                                        className="text-[11px] font-medium text-accent hover:underline"
                                        data-testid="admin-subscription-audit-view-all"
                                    >
                                        View all ({auditLogsTotal}) →
                                    </Link>
                                )}
                            </div>
                            {auditLogs.length === 0 ? (
                                <p className="mt-4 text-[12px] text-muted-foreground">
                                    No audit entries.
                                </p>
                            ) : (
                                <ul className="mt-3 max-h-[480px] space-y-2 overflow-y-auto">
                                    {auditLogs.map((log) => (
                                        <li
                                            key={log.id}
                                            className="border-t border-border/60 pt-2 text-[12px]"
                                            data-testid={`admin-subscription-audit-${log.id}`}
                                        >
                                            <div className="flex items-baseline justify-between gap-2">
                                                <span className="font-mono text-[11px] font-medium text-foreground">
                                                    {log.action}
                                                </span>
                                                <span className="text-[11px] text-muted-foreground">
                                                    {formatDate(log.created_at)}
                                                </span>
                                            </div>
                                            {log.summary && (
                                                <p className="mt-0.5 text-foreground/80">
                                                    {log.summary}
                                                </p>
                                            )}
                                            {log.actor && (
                                                <p className="mt-0.5 text-[11px] text-muted-foreground">
                                                    by {log.actor.email}
                                                </p>
                                            )}
                                        </li>
                                    ))}
                                </ul>
                            )}
                        </Card>
                    </div>

                    <div className="space-y-4">
                        <Card padding="lg" data-testid="admin-subscription-user">
                            <h3 className="text-[11px] font-medium text-muted-foreground">
                                User
                            </h3>
                            {subscription.user.id ? (
                                <Link
                                    href={`/admin/users/${subscription.user.id}`}
                                    className="mt-2 block hover:text-accent"
                                >
                                    <p className="text-sm font-medium text-foreground">
                                        {subscription.user.name ?? '—'}
                                    </p>
                                    <p className="font-mono text-[11px] text-muted-foreground">
                                        {subscription.user.email ?? '—'}
                                    </p>
                                </Link>
                            ) : (
                                <div className="mt-2">
                                    <p className="font-mono text-[11px] text-muted-foreground">
                                        {subscription.user.email ?? '—'}
                                        <span className="ml-1 italic">(deleted)</span>
                                    </p>
                                    <p className="mt-1 text-[11px] text-muted-foreground">
                                        Account purged. Email retained from
                                        snapshot for accounting reference.
                                    </p>
                                </div>
                            )}
                        </Card>

                        <Card padding="lg" data-testid="admin-subscription-actions">
                            <h3 className="text-[11px] font-medium text-muted-foreground">
                                Actions
                            </h3>
                            <div className="mt-3 flex flex-col gap-2">
                                <Button
                                    variant="secondary"
                                    size="sm"
                                    disabled={busy || !planChangeable(subscription.status)}
                                    onClick={() => setPlanOpen(true)}
                                    title={
                                        planChangeable(subscription.status)
                                            ? undefined
                                            : `Can't change plan on a ${subscription.status} subscription`
                                    }
                                    data-testid="admin-subscription-change-plan"
                                >
                                    Change plan…
                                </Button>
                                {subscription.cancels_at_period_end ||
                                subscription.status === 'canceled' ? (
                                    subscription.provider_key === 'razorpay' ? (
                                        <p className="text-[11px] text-muted-foreground">
                                            Razorpay can't resume a canceled
                                            subscription — start a fresh one.
                                        </p>
                                    ) : (
                                        <Button
                                            variant="primary"
                                            size="sm"
                                            disabled={busy || subscription.status === 'canceled'}
                                            onClick={onResume}
                                            data-testid="admin-subscription-resume"
                                        >
                                            {busy ? (
                                                <Loader2
                                                    className="h-3.5 w-3.5 animate-spin"
                                                    strokeWidth={2}
                                                />
                                            ) : null}
                                            Resume
                                        </Button>
                                    )
                                ) : (
                                    <Button
                                        variant="dangerGhost"
                                        size="sm"
                                        disabled={busy}
                                        onClick={() => setCancelOpen(true)}
                                        data-testid="admin-subscription-cancel"
                                    >
                                        Cancel…
                                    </Button>
                                )}
                            </div>
                        </Card>
                    </div>
                </div>

            {cancelOpen && (
                <CancelModal
                    busy={busy}
                    subscriptionId={subscription.id}
                    onClose={() => setCancelOpen(false)}
                    onSubmit={async (mode) => {
                        const ok = await post(
                            `/admin/subscriptions/${subscription.id}/cancel`,
                            { mode },
                        );
                        if (ok) setCancelOpen(false);
                    }}
                />
            )}

            {planOpen && (
                <ChangePlanModal
                    busy={busy}
                    plans={plans}
                    currentKey={subscription.plan.key}
                    onClose={() => setPlanOpen(false)}
                    onSubmit={async (planKey) => {
                        const ok = await post(
                            `/admin/subscriptions/${subscription.id}/change-plan`,
                            { plan_key: planKey },
                        );
                        if (ok) setPlanOpen(false);
                    }}
                />
            )}
        </>
    );
}

AdminSubscriptionsShow.layout = adminLayout;

export default AdminSubscriptionsShow;

function TimelineRow({ label, value }: { label: string; value: string }) {
    return (
        <div>
            <dt className="text-[10px] font-medium uppercase tracking-wide text-muted-foreground">
                {label}
            </dt>
            <dd className="mt-0.5 text-foreground/90">{value}</dd>
        </div>
    );
}

function CancelModal({
    busy,
    subscriptionId,
    onClose,
    onSubmit,
}: {
    busy: boolean;
    subscriptionId: number;
    onClose: () => void;
    onSubmit: (mode: 'at_period_end' | 'immediate') => Promise<void> | void;
}) {
    const [mode, setMode] = useState<'at_period_end' | 'immediate'>('at_period_end');

    return (
        <Modal
            open
            onClose={onClose}
            size="md"
            closeOnBackdrop={false}
            closeOnEsc={!busy}
            data-testid={`admin-subscription-cancel-modal-${subscriptionId}`}
        >
            <Modal.Header
                eyebrow="Cancel subscription"
                eyebrowClassName="text-destructive"
                title="How should this cancel?"
            />
            <Modal.Body fade={false}>
                <fieldset className="space-y-2">
                    <label
                        className={cn(
                            'flex cursor-pointer items-start gap-2 rounded-lg border p-3 text-[12px] transition-colors',
                            mode === 'at_period_end'
                                ? 'border-accent/40 bg-accent/5'
                                : 'border-border hover:bg-muted',
                        )}
                    >
                        <Radio
                            name="cancel-mode"
                            value="at_period_end"
                            checked={mode === 'at_period_end'}
                            onChange={() => setMode('at_period_end')}
                            data-testid="admin-subscription-cancel-mode-at-period-end"
                        />
                        <div>
                            <p className="font-medium text-foreground">Cancel at period end</p>
                            <p className="text-muted-foreground">
                                User keeps access until the current period closes.
                                Default for self-serve cancellations.
                            </p>
                        </div>
                    </label>
                    <label
                        className={cn(
                            'flex cursor-pointer items-start gap-2 rounded-lg border p-3 text-[12px] transition-colors',
                            mode === 'immediate'
                                ? 'border-destructive/40 bg-destructive/5'
                                : 'border-border hover:bg-muted',
                        )}
                    >
                        <Radio
                            name="cancel-mode"
                            value="immediate"
                            checked={mode === 'immediate'}
                            onChange={() => setMode('immediate')}
                            data-testid="admin-subscription-cancel-mode-immediate"
                        />
                        <div>
                            <p className="font-medium text-foreground">Cancel immediately</p>
                            <p className="text-muted-foreground">
                                Access ends now. Use for fraud or refund cases.
                            </p>
                        </div>
                    </label>
                </fieldset>
            </Modal.Body>
            <Modal.Footer>
                <Button type="button" variant="ghost" onClick={onClose} disabled={busy}>
                    Keep
                </Button>
                <Button
                    type="button"
                    variant="danger"
                    disabled={busy}
                    onClick={() => onSubmit(mode)}
                    data-testid="admin-subscription-cancel-confirm"
                >
                    {busy ? (
                        <Loader2 className="h-3.5 w-3.5 animate-spin" strokeWidth={2} />
                    ) : null}
                    Cancel subscription
                </Button>
            </Modal.Footer>
        </Modal>
    );
}

function ChangePlanModal({
    busy,
    plans,
    currentKey,
    onClose,
    onSubmit,
}: {
    busy: boolean;
    plans: PlanOption[];
    currentKey: string | null;
    onClose: () => void;
    onSubmit: (planKey: string) => Promise<void> | void;
}) {
    const [planKey, setPlanKey] = useState<string>(currentKey ?? plans[0]?.key ?? '');

    return (
        <Modal
            open
            onClose={onClose}
            size="md"
            closeOnBackdrop={false}
            closeOnEsc={!busy}
            data-testid="admin-subscription-change-plan-modal"
        >
            <Modal.Header
                eyebrow="Change plan"
                eyebrowClassName="text-accent"
                title="Pick a target plan"
                subtitle="Upgrades prorate immediately. Downgrades take effect at the next renewal."
            />
            <Modal.Body fade={false}>
                <div>
                    <label
                        htmlFor="change-plan-select"
                        className="block text-[11px] font-medium text-muted-foreground"
                    >
                        Plan
                    </label>
                    <Select
                        id="change-plan-select"
                        value={planKey}
                        onChange={(e) => setPlanKey(e.target.value)}
                        data-testid="admin-subscription-change-plan-select"
                        wrapperClassName="mt-1 w-full"
                    >
                        {plans.map((p) => (
                            <option key={p.key} value={p.key}>
                                {p.name} ({p.key})
                            </option>
                        ))}
                    </Select>
                </div>
            </Modal.Body>
            <Modal.Footer>
                <Button type="button" variant="ghost" onClick={onClose} disabled={busy}>
                    Cancel
                </Button>
                <Button
                    type="button"
                    variant="primary"
                    disabled={busy || planKey === currentKey || !planKey}
                    onClick={() => onSubmit(planKey)}
                    data-testid="admin-subscription-change-plan-confirm"
                >
                    {busy ? (
                        <Loader2 className="h-3.5 w-3.5 animate-spin" strokeWidth={2} />
                    ) : null}
                    Change plan
                </Button>
            </Modal.Footer>
        </Modal>
    );
}
