import { AdminPageHeader, adminLayout } from '@/Layouts/AdminLayout';
import { Button, Card, Input, Modal, Pill } from '@/Components/ui';
import {
    invoiceDashboardUrl,
    providerLabel,
} 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';

type InvoiceDetail = {
    id: number;
    provider_key: string;
    provider_invoice_id: string;
    amount_cents: number;
    tax_cents: number;
    tax_rate_bps: number | null;
    tax_label: string | null;
    tax_country: string | null;
    subtotal_cents: number;
    currency: string;
    status: string;
    paid_at: string | null;
    hosted_url: string | null;
    created_at: string | null;
};

type SubscriptionLink = {
    id: number;
    plan: { id: number; key: string; name: string } | null;
    period: string;
    provider_subscription_id: string | null;
    status: string;
};

type UserLink = {
    id: number | null;
    name: string | null;
    email: string | null;
    deleted: boolean;
};

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 Props = {
    invoice: InvoiceDetail;
    subscription: SubscriptionLink | null;
    user: UserLink;
    auditLogs: AuditEntry[];
    auditLogsTotal: number;
};

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

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 AdminInvoicesShow({
    invoice,
    subscription,
    user,
    auditLogs,
    auditLogsTotal,
}: Props) {
    const [refunding, setRefunding] = useState(false);
    const [error, setError] = useState<string | null>(null);

    const dashboardUrl = invoiceDashboardUrl(
        invoice.provider_key,
        invoice.provider_invoice_id,
    );
    const providerName = providerLabel(invoice.provider_key);

    // Refund eligibility mirrors the server-side guard in
    // InvoicesController::refund — paid-only. Both Stripe and Razorpay
    // refunds dispatch through BillingProvider::refundInvoice; the
    // controller surfaces a clear "provider not configured" 422 when
    // the linked provider's API keys are missing.
    const canRefund = invoice.status === 'paid';

    return (
        <>
            <Head title={`Admin · Invoice #${invoice.id}`} />
            <AdminPageHeader
                title={`Invoice #${invoice.id}`}
                description={user.email ?? undefined}
                actions={
                    <Link
                        href="/admin/invoices"
                        className="text-[11px] font-medium text-muted-foreground hover:text-foreground"
                        data-testid="admin-invoice-show-back"
                    >
                        ← All invoices
                    </Link>
                }
            />
                {error && (
                    <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-invoice-error"
                    >
                        <AlertCircle className="mt-0.5 h-3.5 w-3.5" strokeWidth={2.5} />
                        <span>{error}</span>
                    </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-invoice-header">
                            <div className="flex items-start justify-between gap-3">
                                <div>
                                    <div className="flex items-center gap-2">
                                        <StatusBadge status={invoice.status} />
                                    </div>
                                    <h2 className="mt-3 text-2xl font-semibold tracking-tight tabular-nums text-foreground">
                                        {formatCents(
                                            invoice.amount_cents,
                                            invoice.currency,
                                        )}
                                    </h2>
                                    {invoice.tax_cents > 0 && (
                                        <dl
                                            data-testid="admin-invoice-tax-breakdown"
                                            className="mt-2 inline-grid grid-cols-[auto_auto] gap-x-3 gap-y-0.5 text-[11px] text-muted-foreground"
                                        >
                                            <dt>Subtotal</dt>
                                            <dd className="text-right tabular-nums text-foreground">
                                                {formatCents(invoice.subtotal_cents, invoice.currency)}
                                            </dd>
                                            <dt>
                                                {(invoice.tax_label ?? 'Tax')}
                                                {invoice.tax_rate_bps && invoice.tax_rate_bps > 0
                                                    ? ` (${(invoice.tax_rate_bps / 100).toFixed(invoice.tax_rate_bps % 100 === 0 ? 0 : 2)}%)`
                                                    : ''}
                                                {invoice.tax_country ? ` · ${invoice.tax_country}` : ''}
                                            </dt>
                                            <dd className="text-right tabular-nums text-foreground">
                                                {formatCents(invoice.tax_cents, invoice.currency)}
                                            </dd>
                                            <dt className="border-t border-border pt-0.5 font-medium text-foreground">Total</dt>
                                            <dd className="border-t border-border pt-0.5 text-right font-medium tabular-nums text-foreground">
                                                {formatCents(invoice.amount_cents, invoice.currency)}
                                            </dd>
                                        </dl>
                                    )}
                                    <div className="mt-2 flex flex-wrap items-center gap-1.5">
                                        <span className="rounded bg-muted px-1.5 py-0.5 font-mono text-[10px] font-medium uppercase text-muted-foreground">
                                            {invoice.provider_key}
                                        </span>
                                        <span className="rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium uppercase text-muted-foreground">
                                            {invoice.currency}
                                        </span>
                                    </div>
                                </div>
                                <div className="flex flex-col items-end gap-2">
                                    {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-invoice-provider-link"
                                        >
                                            Open in {providerName}
                                            <ExternalLink className="h-3 w-3" strokeWidth={2} />
                                        </a>
                                    )}
                                    {invoice.hosted_url && (
                                        <a
                                            href={invoice.hosted_url}
                                            target="_blank"
                                            rel="noopener noreferrer"
                                            className="inline-flex items-center gap-1 text-[11px] font-medium text-muted-foreground hover:text-foreground"
                                            data-testid="admin-invoice-hosted-link"
                                        >
                                            Hosted receipt
                                            <ExternalLink className="h-3 w-3" strokeWidth={2} />
                                        </a>
                                    )}
                                </div>
                            </div>
                            <p className="mt-3 font-mono text-[11px] text-muted-foreground">
                                {invoice.provider_invoice_id}
                            </p>
                        </Card>

                        <Card padding="lg" data-testid="admin-invoice-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(invoice.created_at)}
                                />
                                <TimelineRow
                                    label="Paid at"
                                    value={formatDate(invoice.paid_at)}
                                />
                            </dl>
                        </Card>

                        <Card padding="lg" data-testid="admin-invoice-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=Invoice&target_id=${invoice.id}`}
                                        className="text-[11px] font-medium text-accent hover:underline"
                                        data-testid="admin-invoice-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-invoice-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-invoice-user">
                            <h3 className="text-[11px] font-medium text-muted-foreground">
                                User
                            </h3>
                            {user.id ? (
                                <Link
                                    href={`/admin/users/${user.id}`}
                                    className="mt-2 block hover:text-accent"
                                    data-testid="admin-invoice-user-link"
                                >
                                    <p className="text-sm font-medium text-foreground">
                                        {user.name ?? '—'}
                                    </p>
                                    <p className="font-mono text-[11px] text-muted-foreground">
                                        {user.email ?? '—'}
                                    </p>
                                </Link>
                            ) : (
                                <div className="mt-2">
                                    <p className="font-mono text-[11px] text-muted-foreground">
                                        {user.email ?? '—'}
                                        {user.deleted && (
                                            <span className="ml-1 italic">(deleted)</span>
                                        )}
                                    </p>
                                    {user.deleted && (
                                        <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-invoice-subscription">
                            <h3 className="text-[11px] font-medium text-muted-foreground">
                                Subscription
                            </h3>
                            {subscription ? (
                                <Link
                                    href={`/admin/subscriptions/${subscription.id}`}
                                    className="mt-2 block hover:text-accent"
                                    data-testid="admin-invoice-subscription-link"
                                >
                                    <div className="flex items-center gap-2">
                                        <span className="text-sm font-medium text-foreground">
                                            {subscription.plan?.name ?? 'Plan'}
                                        </span>
                                        {subscription.plan?.key && (
                                            <Pill
                                                tone={
                                                    PLAN_TONES[subscription.plan.key] ??
                                                    'neutral'
                                                }
                                                size="sm"
                                            >
                                                {subscription.plan.key.toUpperCase()}
                                            </Pill>
                                        )}
                                    </div>
                                    <p className="mt-1 text-[11px] text-muted-foreground">
                                        {subscription.period}
                                    </p>
                                </Link>
                            ) : (
                                <p className="mt-2 text-[12px] text-muted-foreground">
                                    No subscription on file.
                                </p>
                            )}
                        </Card>

                        <Card padding="lg" data-testid="admin-invoice-actions">
                            <h3 className="text-[11px] font-medium text-muted-foreground">
                                Actions
                            </h3>
                            <div className="mt-3 flex flex-col gap-2">
                                {canRefund ? (
                                    <Button
                                        variant="dangerGhost"
                                        size="sm"
                                        onClick={() => setRefunding(true)}
                                        data-testid="admin-invoice-refund"
                                    >
                                        Refund…
                                    </Button>
                                ) : (
                                    <p
                                        className="text-[11px] text-muted-foreground"
                                        data-testid="admin-invoice-refund-disabled"
                                    >
                                        Cannot refund — status is {invoice.status}.
                                    </p>
                                )}
                            </div>
                        </Card>
                    </div>
                </div>

            {refunding && (
                <RefundModal
                    invoice={invoice}
                    onClose={() => setRefunding(false)}
                    onError={(msg) => setError(msg)}
                    onSuccess={() => {
                        setRefunding(false);
                        setError(null);
                        router.reload({ only: ['invoice', 'auditLogs', 'auditLogsTotal'] });
                    }}
                />
            )}
        </>
    );
}

AdminInvoicesShow.layout = adminLayout;

export default AdminInvoicesShow;

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 RefundModal({
    invoice,
    onClose,
    onError,
    onSuccess,
}: {
    invoice: InvoiceDetail;
    onClose: () => void;
    onError: (msg: string) => void;
    onSuccess: () => void;
}) {
    const [amountStr, setAmountStr] = useState<string>(
        (invoice.amount_cents / 100).toFixed(2),
    );
    const [busy, setBusy] = useState(false);
    const [localError, setLocalError] = useState<string | null>(null);

    const submit = async () => {
        setBusy(true);
        setLocalError(null);
        try {
            const major = parseFloat(amountStr);
            const cents =
                Number.isFinite(major) && major > 0
                    ? Math.round(major * 100)
                    : invoice.amount_cents;

            const res = await fetch(`/admin/invoices/${invoice.id}/refund`, {
                method: 'POST',
                credentials: 'same-origin',
                headers: csrfHeaders(),
                body: JSON.stringify({ amount_cents: cents }),
            });
            if (!res.ok) {
                const j = await res.json().catch(() => null);
                const msg = j?.message ?? `Refund failed (${res.status}).`;
                setLocalError(msg);
                onError(msg);
                return;
            }
            onSuccess();
        } catch {
            const msg = 'Network error.';
            setLocalError(msg);
            onError(msg);
        } finally {
            setBusy(false);
        }
    };

    return (
        <Modal
            open
            onClose={onClose}
            size="md"
            closeOnBackdrop={false}
            closeOnEsc={!busy}
            data-testid={`admin-invoice-refund-modal-${invoice.id}`}
        >
            <Modal.Header
                eyebrow="Refund invoice"
                eyebrowClassName="text-destructive"
                title={formatCents(invoice.amount_cents, invoice.currency)}
                subtitle={
                    <span className="font-mono">{invoice.provider_invoice_id}</span>
                }
            />
            <Modal.Body fade={false}>
                <div>
                    <label
                        htmlFor="refund-amount"
                        className="block text-[11px] font-medium text-muted-foreground"
                    >
                        Amount ({invoice.currency})
                    </label>
                    <Input
                        id="refund-amount"
                        type="number"
                        min="0"
                        step="0.01"
                        value={amountStr}
                        onChange={(e) => setAmountStr(e.target.value)}
                        data-testid={`admin-invoice-refund-amount-${invoice.id}`}
                        className="mt-1.5"
                    />
                    <p className="mt-1 text-[11px] text-muted-foreground">
                        Defaults to the full invoice amount. Partial refunds allowed.
                    </p>
                </div>
                {localError && (
                    <p className="text-[12px] font-medium text-destructive">
                        {localError}
                    </p>
                )}
            </Modal.Body>
            <Modal.Footer>
                <Button
                    type="button"
                    variant="ghost"
                    onClick={onClose}
                    disabled={busy}
                >
                    Cancel
                </Button>
                <Button
                    type="button"
                    variant="danger"
                    disabled={busy}
                    onClick={submit}
                    data-testid={`admin-invoice-refund-confirm-${invoice.id}`}
                >
                    {busy ? (
                        <Loader2
                            className="h-3.5 w-3.5 animate-spin"
                            strokeWidth={2}
                        />
                    ) : null}
                    Refund
                </Button>
            </Modal.Footer>
        </Modal>
    );
}
