import { Link } from '@inertiajs/react';
import type { ReactNode } from 'react';

/**
 * Wraps an admin-controlled CTA/link target safely. The marketing CMS
 * lets admin save links with empty href (label-only state before they
 * fill in the URL); Inertia's `<Link>` crashes with
 *   "Cannot read properties of null (reading 'toString')"
 * inside `mergeDataIntoQueryString` when href is null/undefined.
 *
 * Behavior:
 * - Empty / null / whitespace href → renders children with NO link
 *   wrapper. Visually present (the button/text still shows) but
 *   non-interactive. Admin sees the placeholder state until they
 *   fill in the URL.
 * - external=true → bare `<a target="_blank" rel="noopener noreferrer">`.
 *   Bypasses Inertia's SPA navigation (external sites don't want it
 *   anyway) and avoids the Link crash even on edge cases.
 * - Otherwise → Inertia `<Link>` for client-side navigation.
 *
 * Use this for ANY admin-controlled href in marketing components.
 * Hardcoded internal hrefs (e.g. `/register`, `/projects`) can still
 * use Inertia Link directly — they're guaranteed non-empty.
 */
export function SafeCmsLink({
    href,
    external,
    className,
    children,
}: {
    href: string | null | undefined;
    external?: boolean;
    className?: string;
    children: ReactNode;
}) {
    const trimmed = (href ?? '').trim();
    if (trimmed === '') {
        return <>{children}</>;
    }
    // Inertia's <Link> XHR-fetches the target as a same-origin SPA visit, which
    // throws HttpNetworkError on any off-site URL. Treat an absolute target
    // (http(s)://, protocol-relative //, mailto:, tel:) as external even when
    // the admin never ticked the `external` flag — the editors don't always
    // surface that toggle, and an absolute URL is never a valid Inertia visit.
    const isExternal = external || isAbsoluteTarget(trimmed);
    if (isExternal) {
        return (
            <a
                href={trimmed}
                className={className}
                target="_blank"
                rel="noopener noreferrer"
            >
                {children}
            </a>
        );
    }
    return (
        <Link href={trimmed} className={className}>
            {children}
        </Link>
    );
}

/** True when the href points off the SPA's routing scope: an explicit scheme
 *  (http/https/mailto/tel/etc.) or a protocol-relative `//host` URL. Relative
 *  paths (`/contact`, `pricing`) stay on the Inertia path. */
function isAbsoluteTarget(href: string): boolean {
    return /^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith('//');
}
