import { useEffect, useState } from 'react';
import { Globe } from 'lucide-react';

interface FaviconImageProps {
    domain: string;
    /** WordPress Site Icon URL, when the admin has set one. Preferred source. */
    siteIcon?: string;
    className?: string;
    fallbackClassName?: string;
}

function directFaviconUrl(domain: string) {
    return `https://${domain}/favicon.ico`;
}

function preload(url: string, timeoutMs = 4000): Promise<{ ok: boolean; width: number; height: number }> {
    return new Promise((resolve) => {
        const img = new Image();
        const timer = setTimeout(() => resolve({ ok: false, width: 0, height: 0 }), timeoutMs);
        img.onload = () => {
            clearTimeout(timer);
            resolve({ ok: img.naturalWidth > 1 && img.naturalHeight > 1, width: img.naturalWidth, height: img.naturalHeight });
        };
        img.onerror = () => {
            clearTimeout(timer);
            resolve({ ok: false, width: 0, height: 0 });
        };
        img.src = url;
    });
}

export function FaviconImage({ domain, siteIcon, className = 'size-8 rounded-xl', fallbackClassName = 'size-8 text-white/60' }: FaviconImageProps) {
    const [resolved, setResolved] = useState<string | null | undefined>(undefined);

    useEffect(() => {
        // Preferred source: WordPress's own Site Icon, handed to us by PHP via
        // get_site_icon_url(). It is served from this site's media library, is
        // already the right size, and needs no network guessing.
        if (siteIcon) {
            setResolved(siteIcon);
            return;
        }
        if (!domain) {
            setResolved(null);
            return;
        }
        let cancelled = false;
        (async () => {
            // No Site Icon configured — try the site's own /favicon.ico. We only
            // ever ask the site itself: a third-party favicon service (we used
            // Google's) would leak which domains an admin is viewing, and the
            // plugin documents making no such request. Failure falls through to
            // the bundled icon below.
            const direct = directFaviconUrl(domain);
            const d = await preload(direct);
            if (cancelled) return;
            setResolved(d.ok ? direct : null);
        })();
        return () => {
            cancelled = true;
        };
    }, [domain, siteIcon]);

    if (resolved === undefined) return <div className={`${className} bg-white/10 animate-pulse`} />;
    if (resolved === null) return <Globe className={fallbackClassName} />;
    return <img src={resolved} alt="" decoding="async" className={className} />;
}
