// --- DATA SOURCE / ACCURACY / PRECISION REFERENCE (Weather Page) ---
// Mirrors the same system used on the Planning page: one central place
// describing where every live figure on this page comes from, so every
// "i" info icon reads from the same information and stays consistent if a
// provider ever changes.
const DATA_SOURCE_INFO = {
    weatherConditions: {
        label: "Live Weather & Forecast",
        source: "Open-Meteo (blending UK Met Office UKV 2km model for UK/Ireland with ECMWF globally), automatically falling back through wttr.in and MET Norway if unavailable.",
        accuracy: "Typically accurate to within roughly ±1-2°C for temperature and ±10-20% for cloud cover over the next 0-48 hours; accuracy falls the further ahead you look.",
        precision: "Hourly figures for today, daily max/min for the extended forecast, all for your exact dropped-pin location.",
        updates: "Refetched whenever you move the pin; underlying models refresh hourly (UKV) to every 6 hours (ECMWF) at source.",
        caveats: "A forecast model, not a measurement - treat it as strong guidance, especially beyond 2-3 days out."
    },
    spaceWeather: {
        label: "Live Solar Wind & Aurora (Kp-Index)",
        source: "NOAA Space Weather Prediction Center's real-time solar wind (magnetometer + plasma, updated every ~1 minute) and 3-hourly planetary Kp forecast, automatically falling back to GFZ Potsdam's official Kp nowcast if NOAA's forecast feed goes stale.",
        accuracy: "Real-time solar wind readings (Bz, Speed, Density) are direct satellite measurements, not a forecast, so they're accurate to the instrument - but they describe conditions right now, roughly 30-60 minutes before any resulting aurora reaches Earth. The Kp forecast itself is genuinely reliable roughly 12-36 hours ahead; confidence drops off sharply further out.",
        precision: "Solar wind updates roughly every 1 minute; Kp forecast in 3-hourly steps, compared against a threshold calibrated to your latitude.",
        updates: "Solar wind polled continuously while this page is open; Kp forecast refreshes roughly every 3 hours at source.",
        caveats: "Geomagnetic storms are hard to predict precisely more than a day or two out. Whether you'll actually see anything also depends on local cloud cover and light pollution."
    },
    tide: {
        label: "Tide Times",
        source: "UK Admiralty (UKHO) official tidal predictions where available, falling back to TideCheck's verified station data, and finally to a single-harmonic estimate if neither covers your location.",
        accuracy: "UKHO predictions are the official government-grade standard for UK waters. The single-harmonic fallback (used only when no proper station is nearby) is a rough approximation and can be off by up to an hour.",
        precision: "To the nearest minute at the named reference station or port; accuracy naturally decreases the further your dropped pin is from that station.",
        updates: "Fetched fresh for your exact location each time you move the pin.",
        caveats: "Always marked in the app as Official, Verified, or Est. so you can see at a glance which kind of prediction you're looking at - for anything safety-critical, cross-check with ADMIRALTY EasyTide."
    },
    marine: {
        label: "Sea State (Wave Height, Period & Swell)",
        source: "Open-Meteo's Marine Weather API, blending wave/swell model data from meteorological agencies including the UK Met Office and ECMWF.",
        accuracy: "Generally reliable for open-water forecasting 0-48 hours out, in the same range as the underlying weather model accuracy. Coastal/harbour conditions can differ from the open-water figures shown here due to local sheltering, headlands, and shallow-water effects.",
        precision: "Hourly wave height, period, direction and swell height, for your exact dropped pin - only available over open water, so this card simply won't appear for inland locations.",
        updates: "Fetched alongside the rest of the weather data whenever you move the pin.",
        caveats: "This is forecast guidance, not a substitute for an official marine forecast or a skipper's own judgement before sailing - always follow harbour authority and Coastguard advice for anything safety-critical."
    },
    lightning: {
        label: "Lightning Strikes",
        source: "Precise strikes (dashed circle around your last tap) from Xweather's professional detection network. Broader haze/activity layers from EUMETSAT's satellite Lightning Imager (Europe/Africa/parts of S. America) and NOAA's ground-network density product (Americas, Asia, Pacific).",
        accuracy: "Xweather's ground-network strikes are individually located and generally accurate to within a few hundred metres to a few kilometres. The satellite haze layers show broad regional activity, not individual strike locations.",
        precision: "Precise strikes shown for a fixed radius around your last tapped point; the rolling Replay view covers the past 60 minutes for the Northumberland area specifically.",
        updates: "Precise strikes are polled on a short interval while lightning mode is active; the satellite layers update roughly every 5-15 minutes at source.",
        caveats: "Not the same underlying data as consumer sites like Blitzortung/lightningmaps.org - Xweather's terms don't allow using their feed that way, so a professional network is used instead."
    },
    radar: {
        label: "Rain Radar & Satellite",
        source: "RainViewer's composite radar/nowcast mosaic, plus RainViewer and EUMETSAT infrared satellite imagery for cloud cover.",
        accuracy: "Radar accuracy is generally good for tracking existing rain in real time; the short-range nowcast portion (future frames) is an extrapolation and becomes less reliable more than ~30-60 minutes ahead.",
        precision: "Tiled imagery refreshed at roughly 10-minute intervals for radar, and 5-15 minute intervals for satellite depending on provider.",
        updates: "New frames are pulled automatically while the radar/satellite layer is active.",
        caveats: "Radar can miss very light rain/snow and can be affected by hills blocking the radar beam in some areas."
    },
    holyIsland: {
        label: "Holy Island Causeway Crossing Times",
        source: "Officially published safe crossing times, scraped daily from the Northumberland County Council causeway crossing times page.",
        accuracy: "As accurate as the official published schedule itself - this app doesn't calculate independent tide predictions for the causeway, it reads the same table the council publishes.",
        precision: "To the nearest 5 minutes, matching the source table's own resolution.",
        updates: "Re-scraped once daily by an automated job; the app also checks the scraped date genuinely matches today before showing it as current.",
        caveats: "Always a safety-critical crossing - if this data ever looks stale or unavailable, the app tells you to check the official site directly rather than guessing."
    }
};

// Small reusable "i" icon + detail card, used throughout the weather page to
// explain exactly where a given live figure comes from and how much to
// trust it. Renders via a React portal straight into <body>, so it always
// appears as a fully readable, correctly positioned card - centred on
// desktop, a bottom sheet on mobile - regardless of which panel it's
// triggered from or whether that panel uses backdrop-blur (which would
// otherwise trap a plain `position:fixed` popover inside the panel's own
// bounds instead of the real viewport).
//
// `id` selects which DATA_SOURCE_INFO entry to display. `tipKey` is the
// state key used to track open/closed - defaults to `id`, but MUST be given
// a unique value if the same `id` is used more than once within the same
// component, so multiple icons don't all pop open together.
const SourceInfoTip = ({ id, tipKey, activeInfoTip, setActiveInfoTip }) => {
    const info = DATA_SOURCE_INFO[id];
    if (!info) return null;
    const key = `source:${tipKey || id}`;
    const isOpen = activeInfoTip === key;

    return (
        <span className="relative inline-flex items-center">
            <button
                type="button"
                onClick={(e) => { e.stopPropagation(); setActiveInfoTip(isOpen ? null : key); }}
                className="inline-flex items-center justify-center ml-1 rounded-full text-current opacity-60 hover:opacity-100 transition-opacity"
                title={`Data source, accuracy & precision: ${info.label}`}
                aria-label={`Data source and accuracy info for ${info.label}`}
            >
                <Icon name="info" size={11} />
            </button>
            {isOpen && ReactDOM.createPortal(
                <div
                    className="fixed inset-0 z-[2500] bg-slate-900/70 backdrop-blur-sm flex items-end sm:items-center justify-center animate-in fade-in"
                    onClick={() => setActiveInfoTip(null)}
                >
                    <div
                        className="relative bg-white w-full sm:w-[26rem] sm:max-w-[90vw] max-h-[80dvh] overflow-y-auto custom-scrollbar rounded-t-3xl sm:rounded-2xl shadow-2xl p-5 pt-6 text-slate-700 normal-case font-normal"
                        onClick={(e) => e.stopPropagation()}
                    >
                        <button onClick={() => setActiveInfoTip(null)} className="absolute top-3 right-3 p-1.5 bg-slate-100 hover:bg-slate-200 rounded-full transition-colors text-slate-500">
                            <Icon name="x" size={14} />
                        </button>
                        <div className="flex items-center gap-2 mb-4 pr-8">
                            <div className="bg-sky-50 text-sky-600 p-2 rounded-lg shrink-0"><Icon name="info" size={16} /></div>
                            <h4 className="font-black uppercase tracking-widest text-xs md:text-sm text-slate-800 leading-snug">{info.label}</h4>
                        </div>
                        <div className="space-y-3 text-[12px] md:text-[13px] leading-relaxed">
                            <div>
                                <span className="block font-bold text-slate-400 uppercase tracking-wider text-[10px] mb-0.5">Source</span>
                                {info.source}
                            </div>
                            <div>
                                <span className="block font-bold text-slate-400 uppercase tracking-wider text-[10px] mb-0.5">Accuracy</span>
                                {info.accuracy}
                            </div>
                            <div>
                                <span className="block font-bold text-slate-400 uppercase tracking-wider text-[10px] mb-0.5">Precision</span>
                                {info.precision}
                            </div>
                            <div>
                                <span className="block font-bold text-slate-400 uppercase tracking-wider text-[10px] mb-0.5">Updates</span>
                                {info.updates}
                            </div>
                            {info.caveats && (
                                <div className="pt-3 mt-1 border-t border-slate-100 text-slate-500 italic">{info.caveats}</div>
                            )}
                        </div>
                    </div>
                </div>,
                document.body
            )}
        </span>
    );
};
