import { Button, Card } from '@/Components/ui';
import { AdminPageHeader, adminLayout } from '@/Layouts/AdminLayout';
import { Head, Link, router } from '@inertiajs/react';
import {
    AlertCircle,
    ArrowLeft,
    CheckCircle2,
    Loader2,
    RefreshCw,
} from 'lucide-react';
import { useState } from 'react';

type WebhookEventDetail = {
    id: number;
    provider_key: string;
    event_type: string;
    provider_event_id: string;
    processed_at: string | null;
    has_payload: boolean;
    payload: unknown;
};

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

type Props = {
    event: WebhookEventDetail;
    auditLog: AuditEntry[];
};

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 formatTimestamp(iso: string | null): string {
    if (!iso) return '—';
    return new Date(iso).toLocaleString();
}

function AdminWebhookEventsShow({ event, auditLog }: Props) {
    const [replaying, setReplaying] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [replayedAt, setReplayedAt] = useState<string | null>(null);

    const onReplay = async () => {
        setReplaying(true);
        setError(null);
        try {
            const res = await fetch(
                `/admin/webhook-events/${event.id}/replay`,
                {
                    method: 'POST',
                    credentials: 'same-origin',
                    headers: csrfHeaders(),
                },
            );
            const body = await res.json().catch(() => null);
            if (!res.ok) {
                const msg =
                    body?.error ?? body?.message ?? `Replay failed (${res.status}).`;
                setError(typeof msg === 'string' ? msg : 'Replay failed.');
                return;
            }
            setReplayedAt(body?.replayed_at ?? new Date().toISOString());
            // Replay deletes the original row and the provider's dispatch
            // re-inserts a fresh one with a new auto-increment id. The
            // server returned that id; navigate to its detail page rather
            // than reloading the (now-404) original URL.
            const newId =
                typeof body?.new_event_id === 'number'
                    ? body.new_event_id
                    : null;
            if (newId !== null) {
                router.visit(`/admin/webhook-events/${newId}`);
            } else {
                // Fallback: provider didn't return a new id (shouldn't
                // happen post-fix, but if it does the index is the safe
                // landing).
                router.visit('/admin/webhook-events');
            }
        } catch {
            setError('Network error. Try again.');
        } finally {
            setReplaying(false);
        }
    };

    const prettyPayload = event.payload
        ? JSON.stringify(event.payload, null, 2)
        : null;

    return (
        <>
            <Head title="Admin · Webhook event" />
            <AdminPageHeader
                title={`Webhook event #${event.id}`}
                description={`${event.provider_key} · ${event.event_type}`}
                actions={
                    <Link
                        href="/admin/webhook-events"
                        className="inline-flex items-center gap-1.5 text-[11px] font-medium text-muted-foreground hover:text-foreground"
                    >
                        <ArrowLeft className="h-3.5 w-3.5" strokeWidth={2} />
                        Back
                    </Link>
                }
            />
                <Card padding="lg" className="mb-4">
                    <dl className="grid gap-4 sm:grid-cols-2">
                        <Field label="Provider" value={event.provider_key} mono />
                        <Field label="Event type" value={event.event_type} mono />
                        <Field
                            label="Provider event id"
                            value={event.provider_event_id}
                            mono
                        />
                        <Field
                            label="Processed at"
                            value={formatTimestamp(event.processed_at)}
                        />
                    </dl>

                    <div className="mt-6 flex flex-wrap items-center gap-3 border-t border-border/60 pt-4">
                        <Button
                            variant="primary"
                            size="sm"
                            onClick={onReplay}
                            disabled={replaying || !event.has_payload}
                            data-testid="admin-webhook-event-replay"
                        >
                            {replaying ? (
                                <Loader2
                                    className="h-3.5 w-3.5 animate-spin"
                                    strokeWidth={2}
                                />
                            ) : (
                                <RefreshCw
                                    className="h-3.5 w-3.5"
                                    strokeWidth={2}
                                />
                            )}
                            Replay event
                        </Button>

                        {!event.has_payload && (
                            <span className="text-[11px] text-muted-foreground">
                                No payload stored — replay disabled.
                            </span>
                        )}

                        {replayedAt && !error && (
                            <span className="inline-flex items-center gap-1.5 text-[11px] font-medium text-success">
                                <CheckCircle2
                                    className="h-3.5 w-3.5"
                                    strokeWidth={2.5}
                                />
                                Replayed at {formatTimestamp(replayedAt)}
                            </span>
                        )}
                    </div>

                    {error && (
                        <div
                            className="mt-3 flex items-start gap-2 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2 text-[11px] font-medium text-destructive"
                            role="alert"
                            data-testid="admin-webhook-event-replay-error"
                        >
                            <AlertCircle
                                className="mt-0.5 h-3.5 w-3.5"
                                strokeWidth={2.5}
                            />
                            <span>{error}</span>
                        </div>
                    )}
                </Card>

                <Card padding="lg" className="mb-4">
                    <header className="mb-3 flex items-baseline justify-between gap-2">
                        <h2 className="text-base font-semibold tracking-tight text-foreground">
                            Payload
                        </h2>
                        <span className="text-[10px] text-muted-foreground/80">
                            Sensitive keys (client_secret, secret, api_key,
                            password, token) are masked.
                        </span>
                    </header>

                    {prettyPayload ? (
                        <pre
                            className="max-h-[600px] overflow-auto rounded-lg border border-border bg-muted/30 p-4 font-mono text-[12px] leading-relaxed text-foreground/90"
                            data-testid="admin-webhook-event-payload"
                        >
                            {prettyPayload}
                        </pre>
                    ) : (
                        <p className="text-[12px] text-muted-foreground">
                            No payload stored for this event.
                        </p>
                    )}
                </Card>

                <Card padding="lg">
                    <header className="mb-3">
                        <h2 className="text-base font-semibold tracking-tight text-foreground">
                            Audit log
                        </h2>
                        <p className="mt-0.5 text-[11px] text-muted-foreground">
                            Replay attempts and other admin actions on this
                            event.
                        </p>
                    </header>

                    {auditLog.length === 0 ? (
                        <p className="text-[12px] text-muted-foreground">
                            No audit entries yet.
                        </p>
                    ) : (
                        <ul className="divide-y divide-border/60">
                            {auditLog.map((entry) => (
                                <li
                                    key={entry.id}
                                    className="flex items-start justify-between gap-4 py-3"
                                    data-testid={`admin-webhook-event-audit-${entry.id}`}
                                >
                                    <div className="min-w-0">
                                        <p className="font-mono text-[11px] text-foreground">
                                            {entry.action}
                                        </p>
                                        {entry.summary && (
                                            <p className="mt-0.5 text-[12px] text-foreground/80">
                                                {entry.summary}
                                            </p>
                                        )}
                                        {entry.actor && (
                                            <p className="mt-0.5 text-[10px] text-muted-foreground">
                                                by {entry.actor.email}
                                            </p>
                                        )}
                                    </div>
                                    <span className="shrink-0 text-[10px] text-muted-foreground">
                                        {formatTimestamp(entry.created_at)}
                                    </span>
                                </li>
                            ))}
                        </ul>
                    )}
                </Card>
        </>
    );
}

AdminWebhookEventsShow.layout = adminLayout;

export default AdminWebhookEventsShow;

function Field({
    label,
    value,
    mono,
}: {
    label: string;
    value: string;
    mono?: boolean;
}) {
    return (
        <div>
            <dt className="text-[11px] font-medium text-muted-foreground">
                {label}
            </dt>
            <dd
                className={
                    mono
                        ? 'mt-1 break-all font-mono text-[12px] text-foreground'
                        : 'mt-1 text-[13px] text-foreground'
                }
            >
                {value}
            </dd>
        </div>
    );
}
