/// <reference types="@dhwaniapp/plugin-sdk" />

(function() {
    const React = window.React;
    const { Node, ReactNodeViewRenderer, NodeViewWrapper } = window.DhwaniEditorSDK;
    const { useState, useEffect } = React;
    let sdk; // closure variable populated on registration

    function WeatherCardComponent(props) {
        const { node, updateAttributes } = props;
        const { city = "", temp = "", condition = "", lastUpdated = "" } = node.attrs;
        const [inputCity, setInputCity] = useState(city);
        const [loading, setLoading] = useState(false);
        const [error, setError] = useState(null);

        const fetchWeather = async (cityName) => {
            if (!cityName) return;
            setLoading(true);
            setError(null);
            try {
                // 1. Get Lat/Lon from Geocoding API
                const geoUrl = `https://geocoding-api.open-meteo.com/v1/search`;
                const geoRes = await sdk.api.makeHttpCall(geoUrl, 'GET', {
                    query: { name: cityName, count: '1', language: 'en', format: 'json' }
                });

                if (!geoRes || geoRes.status !== 200 || !geoRes.data || !geoRes.data.results || geoRes.data.results.length === 0) {
                    throw new Error(`City "${cityName}" not found.`);
                }

                const location = geoRes.data.results[0];
                const { latitude, longitude, name: resolvedName, country } = location;

                // 2. Get Forecast from Weather API
                const weatherUrl = `https://api.open-meteo.com/v1/forecast`;
                const weatherRes = await sdk.api.makeHttpCall(weatherUrl, 'GET', {
                    query: {
                        latitude: String(latitude),
                        longitude: String(longitude),
                        current: 'temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m'
                    }
                });

                if (!weatherRes || weatherRes.status !== 200 || !weatherRes.data || !weatherRes.data.current) {
                    throw new Error("Failed to fetch weather data.");
                }

                const current = weatherRes.data.current;
                const temperature = current.temperature_2m;
                const weatherCode = current.weather_code;
                const humidity = current.relative_humidity_2m;
                const wind = current.wind_speed_10m;

                // Map weather code to description and emoji
                const weatherMap = {
                    0: "☀️ Sunny",
                    1: "🌤️ Mainly Clear", 2: "🌤️ Partly Cloudy", 3: "☁️ Overcast",
                    45: "🌫️ Fog", 48: "🌫️ Depositing Rime Fog",
                    51: "🌧️ Light Drizzle", 53: "🌧️ Moderate Drizzle", 55: "🌧️ Dense Drizzle",
                    61: "🌧️ Slight Rain", 63: "🌧️ Moderate Rain", 65: "🌧️ Heavy Rain",
                    71: "❄️ Slight Snowfall", 73: "❄️ Moderate Snowfall", 75: "❄️ Heavy Snowfall",
                    80: "🌦️ Slight Rain Showers", 81: "🌦️ Moderate Rain Showers", 82: "🌦️ Violent Rain Showers",
                    95: "⛈️ Thunderstorm", 96: "⛈️ Thunderstorm with Slight Hail", 99: "⛈️ Thunderstorm with Heavy Hail"
                };

                const condText = weatherMap[weatherCode] || "🌡️ Unknown Weather";
                const displayLocation = `${resolvedName}, ${country}`;

                // Update attributes to persist in document
                updateAttributes({
                    city: displayLocation,
                    temp: `${temperature}°C`,
                    condition: `${condText} (Humidity: ${humidity}%, Wind: ${wind} km/h)`,
                    lastUpdated: new Date().toLocaleTimeString()
                });
            } catch (err) {
                console.error("[WeatherCardPlugin] Error fetching weather:", err);
                setError(err.message || "An error occurred.");
            } finally {
                setLoading(false);
            }
        };

        // Auto-fetch on mount if city is set but weather is empty
        useEffect(() => {
            if (city && !temp && !loading) {
                fetchWeather(city);
            }
        }, []);

        return React.createElement(
            NodeViewWrapper,
            {
                className: "card bg-base-200 shadow-xl my-4 border border-base-content/10 max-w-md mx-auto overflow-hidden transition-all duration-200",
                style: { borderRadius: "1rem" }
            },
            React.createElement(
                "div",
                { className: "card-body p-6" },
                React.createElement(
                    "h2",
                    { className: "card-title text-lg font-bold flex items-center justify-between" },
                    React.createElement("span", null, "⛅ Live Weather Forecast"),
                    lastUpdated && React.createElement(
                        "span",
                        { className: "text-xs font-normal opacity-60" },
                        `Updated: ${lastUpdated}`
                    )
                ),
                React.createElement(
                    "div",
                    { className: "flex gap-2 my-2" },
                    React.createElement("input", {
                        type: "text",
                        className: "input input-bordered input-sm flex-1",
                        placeholder: "Enter city (e.g. London)",
                        value: inputCity,
                        onChange: (e) => setInputCity(e.target.value),
                        onKeyDown: (e) => {
                            if (e.key === "Enter") {
                                fetchWeather(inputCity);
                            }
                        }
                    }),
                    React.createElement(
                        "button",
                        {
                            className: `btn btn-sm btn-primary ${loading ? "loading" : ""}`,
                            disabled: loading || !inputCity,
                            onClick: () => fetchWeather(inputCity)
                        },
                        "Get"
                    )
                ),
                error && React.createElement(
                    "div",
                    { className: "alert alert-error py-2 text-xs mt-2" },
                    error
                ),
                city && React.createElement(
                    "div",
                    { className: "mt-4 bg-base-100 p-4 rounded-lg border border-base-content/5" },
                    React.createElement("div", { className: "text-md font-semibold opacity-80" }, city),
                    React.createElement(
                        "div",
                        { className: "flex items-baseline gap-2 mt-1" },
                        React.createElement("div", { className: "text-3xl font-black text-primary" }, temp),
                        React.createElement("div", { className: "text-sm font-medium opacity-70" }, condition)
                    )
                )
            )
        );
    }

    const WeatherCardNode = Node.create({
        name: "weatherCard",
        group: "block",
        atom: true,

        addAttributes() {
            return {
                city: { default: "" },
                temp: { default: "" },
                condition: { default: "" },
                lastUpdated: { default: "" }
            };
        },

        parseHTML() {
            return [{
                tag: 'div[data-type="weather-card"]',
                getAttrs: (element) => ({
                    city: element.getAttribute("data-city") || "",
                    temp: element.getAttribute("data-temp") || "",
                    condition: element.getAttribute("data-condition") || "",
                    lastUpdated: element.getAttribute("data-last-updated") || ""
                })
            }];
        },

        renderHTML({ HTMLAttributes }) {
            return [
                "div",
                {
                    "data-type": "weather-card",
                    "data-city": HTMLAttributes.city || "",
                    "data-temp": HTMLAttributes.temp || "",
                    "data-condition": HTMLAttributes.condition || "",
                    "data-last-updated": HTMLAttributes.lastUpdated || "",
                    ...HTMLAttributes
                }
            ];
        },

        addNodeView() {
            return ReactNodeViewRenderer(WeatherCardComponent);
        }
    });

    sdk = window.Dhwani.registerPageExtension({
        name: "weatherCard",
        tiptapExtension: WeatherCardNode,
        slashCommand: {
            title: "Weather Card",
            description: "Insert a live, auto-updating weather forecast card",
            icon: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5 text-primary">
              <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15a4.5 4.5 0 0 0 4.5 4.5H18a3.75 3.75 0 0 0 1.332-7.257 3 3 0 0 0-3.758-3.848 5.25 5.25 0 0 0-10.233 2.33A4.502 4.502 0 0 0 2.25 15Z" />
            </svg>`,
            command: (editor) => {
                editor.chain().focus().insertContent({ type: "weatherCard" }).run();
            }
        }
    });
})();
