/**
 * SpecialistIdentity — Reusable specialist profile header, rewritten against the live
 * Specialists Search API shape (specialists-api-reference-pack). Renders avatar with a
 * category icon, the Mould Detect vetting badge (when earned), star rating (only when the
 * platform actually captured one — ~2% of records, per the pack §6), and location.
 *
 * Props:
 *   specialist (object) — a record from GET /v1/specialists (via /api/specialists), i.e.
 *                          { id, name, categories[], coverage, location, contact, ratings,
 *                            accreditations[], mould_detect, provenance }.
 *
 * `SpecialistVetting` is exported alongside this component (not folded into it) because
 * SpecialistDirectoryPage's compact card needs the SAME badge logic and the SAME inline
 * check-seal icon at a smaller size — duplicating the status/tier -> label mapping in two
 * files is exactly the kind of drift the pack warns about (INTEGRATION-GUIDE.md §10:
 * "Two files once both defined `mapPayload`; one silently clobbered the other").
 *
 * REMOVED: the file-local pseudo-rating helper this file used to export (a deterministic
 * hash of the company name into a fake "4.7 stars, 83 reviews") and the promise-cached
 * loader for the old bundled JSON file. Both were fabricated data standing in for what the
 * live API now provides for real — a synthesised rating on every card was never a real
 * one, and the API's own real `ratings.google_rating` is null on ~98% of records, which
 * the old code could never represent. See
 * components/SpecialistsService/SpecialistsService.jsx for the real data plane.
 */

/**
 * SpecialistVetting — status/tier -> badge mapping, the inline check-seal icon, and the
 * quiet "Listed from public directories" note for unvetted listings. Table source:
 * specialists-api-reference-pack/INTEGRATION-GUIDE.md §5.
 */
var SpecialistVetting = (function () {

    /**
     * describe(mouldDetect) -> { label, sublabel } or null (no badge earned).
     * Only an `approved` record ever gets a badge — `pending_review` and `unvetted` are
     * treated as unvetted in the UI, and `rejected`/`suspended` must never reach this
     * component at all (the caller filters those out defensively — see isListable below).
     */
    function describe(mouldDetect) {
        var md = mouldDetect || {};
        if (md.status !== 'approved') return null;
        if (md.tier === 'preferred') {
            return { label: 'Mould Detect Approved', sublabel: 'Credentials verified' };
        }
        // 'standard', 'premium' (roadmap — "not yet issued to anyone," pack §5, wording
        // unsettled), or any other/unset tier on an approved record all read as the base
        // approved badge. Read `tier` here, in this one place, exactly as the pack
        // instructs — never hardcode "Mould Detect Certified" against a specific record.
        return { label: 'Mould Detect Approved', sublabel: null };
    }

    /** rejected/suspended must never be rendered anywhere — client-side belt-and-braces
     *  even though the server already ranks/excludes them (pack §5). */
    function isListable(status) {
        return status !== 'rejected' && status !== 'suspended';
    }

    /** The quiet micro-text unvetted cards carry. `pending_review` gets neither a badge
     *  nor this note — silently treated as an ordinary directory listing. */
    /**
     * CheckSeal — inline SVG, deliberately NOT a new icon-font glyph. The subset font
     * (assets/fonts/symbols.icons.txt) is load-bearing (pack §10, hard constraint 5): a
     * glyph name not in that file renders as literal ligature text.
     */
    function CheckSeal(props) {
        var size = props.size || 14;
        return (
            <svg width={size} height={size} viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">
                <path
                    d="M12 2l2.39 1.7 2.92-.2 1.1 2.7 2.7 1.1-.2 2.92L22.6 12l-1.7 2.39.2 2.92-2.7 1.1-1.1 2.7-2.92-.2L12 22.6l-2.39-1.7-2.92.2-1.1-2.7-2.7-1.1.2-2.92L1.4 12l1.7-2.39-.2-2.92 2.7-1.1 1.1-2.7 2.92.2L12 2z"
                    fill="currentColor"
                />
                <path
                    d="M8.4 12.2l2.3 2.3 4.6-4.9" stroke={props.checkColor || '#fff'} strokeWidth="1.7"
                    strokeLinecap="round" strokeLinejoin="round" fill="none"
                />
            </svg>
        );
    }

    /** Badge — the pill used on both the directory card and the profile hero. Renders
     *  nothing (not even a placeholder) when the record hasn't earned one — silence is
     *  the correct default per the pack, not an empty box. */
    function Badge(props) {
        var d = describe(props.mouldDetect);
        if (!d) return null;
        var text = d.label + (d.sublabel ? ' · ' + d.sublabel : '');
        // Two surfaces, two treatments (legibility golden rule): the tinted primary-green
        // reads fine on cream bio-surface cards, but on the GREEN PAGE GROUND light green
        // is near-invisible — there, `solid` renders the badge as a forest seal with white
        // text (the only sanctioned light-text-on-fill combination).
        var cls = props.solid
            ? 'bg-forest text-white px-2.5 py-1 rounded-full inline-flex items-center gap-1.5 max-w-full shadow-soft '
            : 'bg-primary/10 text-primary px-2 py-0.5 rounded-lg inline-flex items-center gap-1 max-w-full ';
        return (
            <div className={cls + (props.className || '')}>
                <CheckSeal size={12} checkColor={props.solid ? '#1a4332' : '#fff'} />
                <span className="text-[9px] font-black uppercase tracking-wider">{text}</span>
            </div>
        );
    }

    return {
        describe: describe,
        isListable: isListable,
        CheckSeal: CheckSeal,
        Badge: Badge,
    };
})();

var SpecialistIdentity = function (props) {
    var specialist = props.specialist;
    if (!specialist) return null;

    var name = specialist.name || '';
    var categories = specialist.categories || [];
    var primaryCategory = categories[0] || '';
    var icon = (AppConstants.SPECIALIST_CATEGORY_ICONS || {})[primaryCategory] || 'support_agent';

    var mouldDetect = specialist.mould_detect || {};
    var vetting = SpecialistVetting.describe(mouldDetect);

    var loc = specialist.location || {};
    var approx = loc.geocode_precision === 'postcode';

    var ratings = specialist.ratings || {};
    // ~2% of records carry a real Google rating (pack §6) — never a fallback number, only
    // ever the real value when it exists.
    var hasRating = typeof ratings.google_rating === 'number';

    return (
        <section className="flex flex-col items-center py-6 mt-2 bg-gradient-to-b from-primary/5 to-transparent rounded-2xl">
            <div className="relative">
                <div className="w-24 h-24 rounded-full bg-primary/40 border-4 border-surface shadow-soft flex items-center justify-center">
                    <span
                        className="material-symbols-outlined text-white text-4xl"
                        style={{ fontVariationSettings: "'FILL' 1" }}
                    >{icon}</span>
                </div>
                {vetting && (
                    <div className="absolute bottom-0 right-0 bg-primary text-white p-1.5 rounded-full border-2 border-surface">
                        <SpecialistVetting.CheckSeal size={14} />
                    </div>
                )}
            </div>
            <div className="mt-3 text-center px-4">
                <h1 className="text-xl font-black text-forest tracking-tight">{name}</h1>
                <p className="text-forest font-bold text-sm mt-1">{categories.join(', ')}</p>

                {vetting && (
                    <div className="flex justify-center mt-2">
                        <SpecialistVetting.Badge mouldDetect={mouldDetect} solid={true} />
                    </div>
                )}
                {hasRating && (
                    <div className="flex items-center justify-center gap-1 mt-2">
                        <span className="material-symbols-outlined text-terracotta text-base" style={{ fontVariationSettings: "'FILL' 1" }}>star</span>
                        <span className="font-bold text-forest text-sm">{ratings.google_rating.toFixed(1)}</span>
                        {typeof ratings.google_review_count === 'number' && (
                            <span className="text-forest text-xs">({ratings.google_review_count} reviews)</span>
                        )}
                    </div>
                )}

                {loc.suburb && (
                    <div className="flex items-center justify-center gap-1 mt-1 text-muted">
                        <span className="material-symbols-outlined text-sm text-forest">location_on</span>
                        <span className="text-xs font-medium text-forest">
                            {loc.suburb}{loc.state ? ', ' + loc.state : ''}{approx ? ' (approx.)' : ''}
                        </span>
                    </div>
                )}
                {specialist.coverage === 'service_area' && (
                    <p className="text-[10px] text-forest/60 font-bold mt-1 uppercase tracking-wide">Services this area</p>
                )}
            </div>
        </section>
    );
};

window.SpecialistIdentity = SpecialistIdentity;
window.SpecialistVetting = SpecialistVetting;
