<?php
/**
 * Plugin Name: HD Weather Widget by The Waypoint
 * Plugin URI: http://consultants.thewaypoint.com
 * Description: A weather widget designed for 331dpi Screens, It's HD! Modernized for WordPress 6.6.1 and PHP 7.4+
 * Author: John Grefe - The Waypoint
 * Author URI: http://www.twitter.com/johngrefe
 * Version: 1.2.0
 * Stable: 1.2.0
 * Requires at least: 5.0
 * Requires PHP: 7.4
 * Text Domain: waypoint-hd-weather-widget
 * Domain Path: /languages
 * 
 * Based On: Awesome Weather Widget by Hal Gatewood
 * Modernized: October 2025 for WordPress 5.0+ and PHP 7.4+
 *
 * FILTERS AVAILABLE:
 * waypoint_weather_cache                      = How many seconds to cache weather: default 1800 (30 minutes)
 * waypoint_weather_forecast_cache             = How many seconds to cache forecast: default 10800 (3 hours)
 * waypoint_weather_error                      = Error message if weather is not found
 * waypoint_weather_sizes                      = array of sizes for widget
 * waypoint_weather_extended_forecast_text     = Change text of footer link
 *
 * SHORTCODE USAGE:
 * [[waypoint-weather lat="34.0537" lon="-118.2428" units="F" size="tall" forecast_days="hide" override_title="Los Angeles, California, US"]
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Plugin constants
define( 'WAYPOINT_WEATHER_VERSION', '1.2.0' );
define( 'WAYPOINT_WEATHER_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'WAYPOINT_WEATHER_PLUGIN_URL', plugin_dir_url( __FILE__ ) );

// Settings
$waypoint_weather_sizes = apply_filters( 'waypoint_weather_sizes', array( 'tall', 'wide' ) );

/**
 * Enqueue scripts and styles
 */
function waypoint_weather_enqueue_scripts() {
    wp_enqueue_style( 
        'waypoint-weather', 
        WAYPOINT_WEATHER_PLUGIN_URL . 'waypoint-weather.css',
        array(),
        WAYPOINT_WEATHER_VERSION
    );
    
    // Enqueue Google Fonts properly (non-blocking)
    wp_enqueue_style(
        'waypoint-weather-fonts',
        'https://fonts.googleapis.com/css?family=Open+Sans:400,300&display=swap',
        array(),
        null
    );
}
add_action( 'wp_enqueue_scripts', 'waypoint_weather_enqueue_scripts' );

/**
 * Register admin menu for settings
 */
function waypoint_weather_admin_menu() {
    add_options_page(
        __( 'HD Weather Widget Settings', 'waypoint-hd-weather-widget' ),
        __( 'HD Weather Widget', 'waypoint-hd-weather-widget' ),
        'manage_options',
        'waypoint-weather-settings',
        'waypoint_weather_settings_page'
    );
}
add_action( 'admin_menu', 'waypoint_weather_admin_menu' );

/**
 * Enqueue admin scripts for shortcode builder
 */
function waypoint_weather_admin_scripts($hook) {
    // Only load on our settings page
    if ($hook !== 'settings_page_waypoint-weather-settings') {
        return;
    }
    
    wp_enqueue_script(
        'waypoint-weather-admin',
        WAYPOINT_WEATHER_PLUGIN_URL . 'admin.js',
        array('jquery'),
        WAYPOINT_WEATHER_VERSION,
        true
    );
    
    wp_localize_script('waypoint-weather-admin', 'waypointWeather', array(
        'ajaxurl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('waypoint_weather_geocode'),
    ));
}
add_action('admin_enqueue_scripts', 'waypoint_weather_admin_scripts');

/**
 * AJAX handler for geocoding
 */
function waypoint_weather_geocode_location() {
    check_ajax_referer('waypoint_weather_geocode', 'nonce');
    
    if (!current_user_can('manage_options')) {
        wp_send_json_error('Unauthorized');
    }
    
    $location = isset($_POST['location']) ? sanitize_text_field($_POST['location']) : '';
    $api_key = get_option('waypoint_weather_api_key', '');
    
    if (empty($location)) {
        wp_send_json_error('Location is required');
    }
    
    if (empty($api_key)) {
        wp_send_json_error('API key not configured');
    }
    
    // Call OpenWeatherMap Geocoding API
    $geocode_url = add_query_arg(array(
        'q' => urlencode($location),
        'limit' => 5,
        'appid' => $api_key,
    ), 'https://api.openweathermap.org/geo/1.0/direct');
    
    $response = wp_remote_get($geocode_url, array(
        'timeout' => 10,
        'sslverify' => true,
    ));
    
    if (is_wp_error($response)) {
        wp_send_json_error('Could not connect to geocoding service');
    }
    
    $body = wp_remote_retrieve_body($response);
    $data = json_decode($body);
    
    if (empty($data) || !is_array($data)) {
        wp_send_json_error('Location not found. Try being more specific (e.g., "Paris, FR" or "Los Angeles, CA, US")');
    }
    
    // Format results
    $results = array();
    foreach ($data as $location_data) {
        $results[] = array(
            'name' => isset($location_data->name) ? $location_data->name : '',
            'state' => isset($location_data->state) ? $location_data->state : '',
            'country' => isset($location_data->country) ? $location_data->country : '',
            'lat' => isset($location_data->lat) ? round($location_data->lat, 4) : 0,
            'lon' => isset($location_data->lon) ? round($location_data->lon, 4) : 0,
        );
    }
    
    wp_send_json_success($results);
}
add_action('wp_ajax_waypoint_weather_geocode', 'waypoint_weather_geocode_location');



/**
 * Settings page callback with Shortcode Builder
 */
function waypoint_weather_settings_page() {
    // Check user capabilities
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }

    // Save settings
    if ( isset( $_POST['waypoint_weather_api_key'] ) && check_admin_referer( 'waypoint_weather_settings' ) ) {
        update_option( 'waypoint_weather_api_key', sanitize_text_field( $_POST['waypoint_weather_api_key'] ) );
        echo '<div class="notice notice-success"><p>' . esc_html__( 'Settings saved!', 'waypoint-hd-weather-widget' ) . '</p></div>';
    }

    $api_key = get_option( 'waypoint_weather_api_key', '' );
    ?>
    <div class="wrap">
        <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
        
        <!-- API Key Settings -->
        <form method="post" action="">
            <?php wp_nonce_field( 'waypoint_weather_settings' ); ?>
            <table class="form-table">
                <tr>
                    <th scope="row">
                        <label for="waypoint_weather_api_key">
                            <?php esc_html_e( 'OpenWeatherMap API Key', 'waypoint-hd-weather-widget' ); ?>
                        </label>
                    </th>
                    <td>
                        <input type="text" 
                               id="waypoint_weather_api_key" 
                               name="waypoint_weather_api_key" 
                               value="<?php echo esc_attr( $api_key ); ?>" 
                               class="regular-text" 
                               placeholder="<?php esc_attr_e( 'Enter your API key', 'waypoint-hd-weather-widget' ); ?>">
                        <p class="description">
                            <?php 
                            printf(
                                esc_html__( 'Get your free API key from %s (1,000 calls/day free)', 'waypoint-hd-weather-widget' ),
                                '<a href="https://openweathermap.org/appid" target="_blank">OpenWeatherMap</a>'
                            );
                            ?>
                        </p>
                    </td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>

        <hr style="margin: 40px 0;">

        <!-- Shortcode Builder -->
        <h2>🔧 Shortcode Builder</h2>
        <p>Build your custom weather widget shortcode in 3 easy steps:</p>

        <div style="background: #fff; border: 1px solid #c3c4c7; padding: 25px; margin: 20px 0;">
            
            <!-- Step 1: Find Location -->
            <div style="background: #f0f6fc; border-left: 4px solid #2271b1; padding: 15px; margin-bottom: 25px;">
                <h3 style="margin-top: 0;">Step 1: Find Your Location Coordinates</h3>
                <p>Enter a city name to get its latitude and longitude coordinates:</p>
                
                <div style="display: flex; gap: 10px; align-items: flex-start; margin: 15px 0;">
                    <input type="text" 
                           id="waypoint-location-input" 
                           class="regular-text" 
                           placeholder="e.g., Los Angeles, CA, US or Paris, FR"
                           style="flex: 1;">
                    <button id="waypoint-geocode-btn" class="button button-primary" style="height: 36px;">
                        Find Location
                    </button>
                </div>
                
                <p class="description">
                    💡 Tip: Be specific! Include state/province and country code for best results 
                    (e.g., "Springfield, IL, US" instead of just "Springfield")
                </p>
                
                <div id="waypoint-geocode-results"></div>
            </div>

            <!-- Step 2: Customize Options -->
            <div id="waypoint-shortcode-builder" style="background: #f0f6fc; border-left: 4px solid #2271b1; padding: 15px; margin-bottom: 25px;">
                <h3 style="margin-top: 0;">Step 2: Customize Your Widget</h3>
                
                <input type="hidden" id="builder-lat">
                <input type="hidden" id="builder-lon">
                
                <table class="form-table" style="margin-top: 0;">
                    <tr>
                        <th scope="row">
                            <label for="builder-location-name">Display Name</label>
                        </th>
                        <td>
                            <input type="text" 
                                   id="builder-location-name" 
                                   class="regular-text" 
                                   placeholder="Custom title (optional)">
                            <p class="description">Override the city name with custom text</p>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="builder-units">Temperature Units</label>
                        </th>
                        <td>
                            <select id="builder-units" class="regular-text">
                                <option value="F">Fahrenheit (°F)</option>
                                <option value="C">Celsius (°C)</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="builder-size">Widget Size</label>
                        </th>
                        <td>
                            <select id="builder-size" class="regular-text">
                                <option value="wide">Wide (Default)</option>
                                <option value="tall">Tall</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">
                            <label for="builder-forecast">Forecast Days</label>
                        </th>
                        <td>
                            <select id="builder-forecast" class="regular-text">
                                <option value="5">5 Days</option>
                                <option value="4">4 Days</option>
                                <option value="3">3 Days</option>
                                <option value="2">2 Days</option>
                                <option value="1">1 Day</option>
                                <option value="hide">Hide Forecast</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">Additional Options</th>
                        <td>
                            <label>
                                <input type="checkbox" id="builder-hide-stats" value="1">
                                Hide weather stats (humidity, wind)
                            </label>
                            <br>
                            <label style="margin-top: 10px; display: inline-block;">
                                <input type="checkbox" id="builder-show-link" value="1">
                                Show link to OpenWeatherMap
                            </label>
                        </td>
                    </tr>
                </table>
            </div>

            <!-- Step 3: Copy Shortcode -->
            <div style="background: #f0f6fc; border-left: 4px solid #00a32a; padding: 15px;">
                <h3 style="margin-top: 0;">Step 3: Copy Your Shortcode</h3>
                <p>Your custom shortcode is ready! Copy and paste it into any post or page:</p>
                
                <div style="display: flex; gap: 10px; align-items: flex-start; margin: 15px 0;">
                    <textarea id="shortcode-output" 
                              class="large-text code" 
                              rows="3" 
                              readonly 
                              style="flex: 1; font-family: monospace; background: #f0f0f1;"
                              onclick="this.select();">Please select a location above first</textarea>
                    <button id="copy-shortcode-btn" class="button button-primary" style="height: auto; white-space: nowrap;">
                        Copy Shortcode
                    </button>
                </div>
            </div>
        </div>

        <hr style="margin: 40px 0;">

        <!-- Documentation -->
        <h2>📚 Documentation & Examples</h2>
        
        <div style="background: #fff; border: 1px solid #ccd0d4; padding: 20px; margin: 20px 0;">
            <h3 style="margin-top: 0;">Example Shortcodes</h3>
            
            <h4>Los Angeles (Fahrenheit):</h4>
            <code style="display: block; background: #f0f0f1; padding: 10px; margin: 10px 0; font-size: 14px;">[waypoint-weather lat="34.0522" lon="-118.2437" units="F"]</code>
            
            <h4>London (Celsius, Tall Layout):</h4>
            <code style="display: block; background: #f0f0f1; padding: 10px; margin: 10px 0; font-size: 14px;">[waypoint-weather lat="51.5074" lon="-0.1278" units="C" size="tall"]</code>
            
            <h4>Tokyo (Custom Title):</h4>
            <code style="display: block; background: #f0f0f1; padding: 10px; margin: 10px 0; font-size: 14px;">[waypoint-weather lat="35.6762" lon="139.6503" units="C" override_title="Current Weather"]</code>
        </div>

        <div style="background: #fff; border: 1px solid #ccd0d4; padding: 20px; margin: 20px 0;">
            <h3 style="margin-top: 0;">⚙️ Available Parameters</h3>
            <table class="widefat" style="margin: 10px 0;">
                <thead>
                    <tr>
                        <th style="padding: 10px;"><strong>Parameter</strong></th>
                        <th style="padding: 10px;"><strong>Options</strong></th>
                        <th style="padding: 10px;"><strong>Description</strong></th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td style="padding: 10px;"><code>lat</code></td>
                        <td style="padding: 10px;">Decimal number</td>
                        <td style="padding: 10px;">✅ <strong>Required.</strong> Latitude coordinate (e.g., 34.0522)</td>
                    </tr>
                    <tr style="background: #f9f9f9;">
                        <td style="padding: 10px;"><code>lon</code></td>
                        <td style="padding: 10px;">Decimal number</td>
                        <td style="padding: 10px;">✅ <strong>Required.</strong> Longitude coordinate (e.g., -118.2437)</td>
                    </tr>
                    <tr>
                        <td style="padding: 10px;"><code>units</code></td>
                        <td style="padding: 10px;"><code>F</code> or <code>C</code></td>
                        <td style="padding: 10px;">Temperature units (F = Fahrenheit, C = Celsius)</td>
                    </tr>
                    <tr style="background: #f9f9f9;">
                        <td style="padding: 10px;"><code>size</code></td>
                        <td style="padding: 10px;"><code>wide</code> or <code>tall</code></td>
                        <td style="padding: 10px;">Widget layout (default: wide)</td>
                    </tr>
                    <tr>
                        <td style="padding: 10px;"><code>forecast_days</code></td>
                        <td style="padding: 10px;"><code>1-5</code> or <code>hide</code></td>
                        <td style="padding: 10px;">Number of forecast days to show (default: 5)</td>
                    </tr>
                    <tr style="background: #f9f9f9;">
                        <td style="padding: 10px;"><code>hide_stats</code></td>
                        <td style="padding: 10px;"><code>0</code> or <code>1</code></td>
                        <td style="padding: 10px;">Hide humidity/wind stats (0 = show, 1 = hide)</td>
                    </tr>
                    <tr>
                        <td style="padding: 10px;"><code>show_link</code></td>
                        <td style="padding: 10px;"><code>0</code> or <code>1</code></td>
                        <td style="padding: 10px;">Show link to OpenWeatherMap (0 = hide, 1 = show)</td>
                    </tr>
                    <tr style="background: #f9f9f9;">
                        <td style="padding: 10px;"><code>override_title</code></td>
                        <td style="padding: 10px;">Any text</td>
                        <td style="padding: 10px;">Replace city name with custom title</td>
                    </tr>
                </tbody>
            </table>
        </div>

        <div style="background: #fffbcc; border-left: 4px solid #ffb900; padding: 15px; margin: 20px 0;">
            <h3 style="margin-top: 0;">⚠️ Troubleshooting</h3>
            <ul style="margin: 0;">
                <li>If weather does not appear, make sure your API key is saved above</li>
                <li>New API keys take 10-15 minutes to activate</li>
                <li>Always use the Shortcode Builder to get accurate lat/lon coordinates</li>
                <li>Weather updates every 30 minutes (cached for performance)</li>
                <li>Check the browser console for JavaScript errors if the builder is not working</li>
            </ul>
        </div>
    </div>
    <?php
}

/**
 * Register shortcode
 */
add_shortcode( 'waypoint-weather', 'waypoint_weather_shortcode' );
function waypoint_weather_shortcode( $atts ) {
    return waypoint_weather_logic( $atts );
}

/**
 * Main weather logic
 */
function waypoint_weather_logic( $atts ) {
    global $waypoint_weather_sizes;

    $rtn = '';
    $weather_data = array();
    
    // Parse attributes
    $lat = isset( $atts['lat'] ) ? $atts['lat'] : false;
    $lon = isset( $atts['lon'] ) ? $atts['lon'] : false;
    $location = isset( $atts['location'] ) ? $atts['location'] : false; // Legacy support
    $size = ( isset( $atts['size'] ) && $atts['size'] === 'tall' ) ? 'tall' : 'wide';
    $units = ( isset( $atts['units'] ) && strtoupper( $atts['units'] ) === 'C' ) ? 'metric' : 'imperial';
    $units_display = $units === 'metric' ? esc_html__( 'C', 'waypoint-hd-weather-widget' ) : esc_html__( 'F', 'waypoint-hd-weather-widget' );
    $override_title = isset( $atts['override_title'] ) ? sanitize_text_field( $atts['override_title'] ) : false;
    $days_to_show = isset( $atts['forecast_days'] ) ? $atts['forecast_days'] : 5;
    $show_stats = ( isset( $atts['hide_stats'] ) && $atts['hide_stats'] == 1 ) ? 0 : 1;
    $show_link = ( isset( $atts['show_link'] ) && $atts['show_link'] == 1 ) ? 1 : 0;
    $background = isset( $atts['background'] ) ? esc_url( $atts['background'] ) : false;

    // Require either lat/lon or location
    if ( ! $lat || ! $lon ) {
        if ( ! $location ) {
            return waypoint_weather_error( esc_html__( 'No location specified. Please use lat/lon coordinates (recommended) or city name.', 'waypoint-hd-weather-widget' ) );
        }
    }

    // Get API key
    $api_key = get_option( 'waypoint_weather_api_key', '' );
    if ( empty( $api_key ) ) {
        return waypoint_weather_error( esc_html__( 'API key not configured. Please set your OpenWeatherMap API key in Settings > HD Weather Widget', 'waypoint-hd-weather-widget' ) );
    }

    // Create cache key
    if ( $lat && $lon ) {
        $cache_key = sanitize_key( $lat . '_' . $lon );
    } else {
        $cache_key = sanitize_key( $location );
    }
    $weather_transient_name = 'waypoint_weather_' . $units . '_' . $cache_key;

    // Try to get cached weather data
    $weather_data = get_transient( $weather_transient_name );

    if ( false === $weather_data || ! isset( $weather_data['today'] ) ) {
        // Fetch current weather from API v2.5
        // Use lat/lon if available (preferred), otherwise fall back to city name
        if ( $lat && $lon ) {
            $current_api_url = add_query_arg( array(
                'lat' => $lat,
                'lon' => $lon,
                'appid' => $api_key,
                'units' => $units,
            ), 'https://api.openweathermap.org/data/2.5/weather' );
        } else {
            $current_api_url = add_query_arg( array(
                'q' => urlencode( $location ),
                'appid' => $api_key,
                'units' => $units,
            ), 'https://api.openweathermap.org/data/2.5/weather' );
        }

        $response = wp_remote_get( $current_api_url, array(
            'timeout' => 10,
            'sslverify' => true,
        ) );

        if ( is_wp_error( $response ) ) {
            return waypoint_weather_error( esc_html__( 'Could not connect to weather service', 'waypoint-hd-weather-widget' ) );
        }

        $body = wp_remote_retrieve_body( $response );
        $data = json_decode( $body );

        if ( ! $data || ( isset( $data->cod ) && $data->cod != 200 ) ) {
            $error_msg = isset( $data->message ) ? $data->message : __( 'City could not be found', 'waypoint-hd-weather-widget' );
            return waypoint_weather_error( esc_html( $error_msg ) );
        }

        $weather_data['today'] = $data;

        // Fetch forecast data if needed
        if ( $days_to_show !== 'hide' ) {
            // Use lat/lon if available (preferred), otherwise city name
            if ( $lat && $lon ) {
                $forecast_api_url = add_query_arg( array(
                    'lat' => $lat,
                    'lon' => $lon,
                    'appid' => $api_key,
                    'units' => $units,
                    'cnt' => 7, // 7 days forecast
                ), 'https://api.openweathermap.org/data/2.5/forecast/daily' );
            } else {
                $forecast_api_url = add_query_arg( array(
                    'q' => urlencode( $location ),
                    'appid' => $api_key,
                    'units' => $units,
                    'cnt' => 7, // 7 days forecast
                ), 'https://api.openweathermap.org/data/2.5/forecast/daily' );
            }

            $forecast_response = wp_remote_get( $forecast_api_url, array(
                'timeout' => 10,
                'sslverify' => true,
            ) );

            if ( ! is_wp_error( $forecast_response ) ) {
                $forecast_body = wp_remote_retrieve_body( $forecast_response );
                $forecast_data = json_decode( $forecast_body );
                
                if ( $forecast_data && isset( $forecast_data->list ) ) {
                    $weather_data['forecast'] = $forecast_data;
                }
            }
        }

        // Cache current weather for 30 minutes (more frequent updates)
        set_transient( $weather_transient_name, $weather_data, apply_filters( 'waypoint_weather_cache', 1800 ) );
    }

    // No weather data available
    if ( ! $weather_data || ! isset( $weather_data['today'] ) ) {
        return waypoint_weather_error();
    }

    // Process today's data
    $today = $weather_data['today'];
    $today_temp = (int) $today->main->temp;
    $today_high = (int) $today->main->temp_max;
    $today_low = (int) $today->main->temp_min;
    $weather_id = isset( $today->weather[0]->id ) ? (int) $today->weather[0]->id : 800;

    // Background class based on weather condition
    $bg_class = 'feel' . $weather_id;

    // Header title
    $header_title = $override_title ? $override_title : $today->name;

    // Wind direction
    $wind_label = array(
        esc_html__( 'N', 'waypoint-hd-weather-widget' ),
        esc_html__( 'NNE', 'waypoint-hd-weather-widget' ),
        esc_html__( 'NE', 'waypoint-hd-weather-widget' ),
        esc_html__( 'ENE', 'waypoint-hd-weather-widget' ),
        esc_html__( 'E', 'waypoint-hd-weather-widget' ),
        esc_html__( 'ESE', 'waypoint-hd-weather-widget' ),
        esc_html__( 'SE', 'waypoint-hd-weather-widget' ),
        esc_html__( 'SSE', 'waypoint-hd-weather-widget' ),
        esc_html__( 'S', 'waypoint-hd-weather-widget' ),
        esc_html__( 'SSW', 'waypoint-hd-weather-widget' ),
        esc_html__( 'SW', 'waypoint-hd-weather-widget' ),
        esc_html__( 'WSW', 'waypoint-hd-weather-widget' ),
        esc_html__( 'W', 'waypoint-hd-weather-widget' ),
        esc_html__( 'WNW', 'waypoint-hd-weather-widget' ),
        esc_html__( 'NW', 'waypoint-hd-weather-widget' ),
        esc_html__( 'NNW', 'waypoint-hd-weather-widget' ),
    );

    $wind_deg = isset( $today->wind->deg ) ? $today->wind->deg : 0;
    $wind_direction = $wind_label[ (int) fmod( ( ( $wind_deg + 11 ) / 22.5 ), 16 ) ];
    $wind_speed = isset( $today->wind->speed ) ? (int) $today->wind->speed : 0;
    $humidity = isset( $today->main->humidity ) ? (int) $today->main->humidity : 0;
    $description = isset( $today->weather[0]->description ) ? $today->weather[0]->description : '';

    $show_stats_class = $show_stats ? 'awe_with_stats' : 'awe_without_stats';
    if ( $background ) {
        $bg_class = 'darken';
    }

    // Build output
    $rtn .= '<div id="waypoint-weather-' . esc_attr( $city_name_slug ) . '" class="waypoint-weather-wrap awecf ' . esc_attr( $bg_class ) . ' ' . esc_attr( $show_stats_class ) . ' awe_' . esc_attr( $size ) . '">';

    if ( $background ) {
        $rtn .= '<div class="waypoint-weather-cover" style="background: url(' . esc_url( $background ) . ') no-repeat;">';
        $rtn .= '<div class="waypoint-weather-darken">';
    }

    $rtn .= '<br><div class="waypoint-weather-header">' . esc_html( $header_title ) . '</div>';
    $rtn .= '<div class="waypoint-weather-current-temp">' . esc_html( $today_temp ) . '<sup>' . esc_html( $units_display ) . '</sup></div>';

    if ( $show_stats ) {
        $rtn .= '<div class="waypoint-weather-todays-stats">';
        $rtn .= '<div class="awe_desc">' . esc_html( $description ) . '</div>';
        $rtn .= '<div class="awe_humidity">' . esc_html__( 'humidity:', 'waypoint-hd-weather-widget' ) . ' ' . esc_html( $humidity ) . '%</div>';
        $rtn .= '<div class="awe_wind">' . esc_html__( 'wind:', 'waypoint-hd-weather-widget' ) . ' ' . esc_html( $wind_speed ) . 'mph ' . esc_html( $wind_direction ) . '</div>';
        $rtn .= '<div class="awe_highlow">H ' . esc_html( $today_high ) . ' &bull; L ' . esc_html( $today_low ) . '</div>';
        $rtn .= '</div><br><br><br>';
    }

    // Forecast
    if ( $days_to_show !== 'hide' && isset( $weather_data['forecast'] ) ) {
        $rtn .= '<div class="waypoint-weather-forecast awe_days_' . esc_attr( $days_to_show ) . ' awecf">';
        $c = 1;
        $dt_today = date( 'Ymd' );
        $forecast = $weather_data['forecast'];
        $days_to_show_int = (int) $days_to_show;

        foreach ( (array) $forecast->list as $forecast_day ) {
            if ( $dt_today > date( 'Ymd', $forecast_day->dt ) ) {
                continue;
            }

            $forecast_temp = isset( $forecast_day->temp->day ) ? (int) $forecast_day->temp->day : 0;
            $day_of_week = date( 'D', $forecast_day->dt );

            $rtn .= '<div class="waypoint-weather-forecast-day">';
            $rtn .= '<div class="waypoint-weather-forecast-day-temp">' . esc_html( $forecast_temp ) . '<sup>' . esc_html( $units_display ) . '</sup></div>';
            $rtn .= '<div class="waypoint-weather-forecast-day-abbr">' . esc_html( $day_of_week ) . '</div>';
            $rtn .= '</div>';

            if ( $c == $days_to_show_int ) {
                break;
            }
            $c++;
        }
        $rtn .= '</div>';
    }

    // Extended forecast link
    if ( $show_link && isset( $today->id ) ) {
        $show_link_text = apply_filters( 'waypoint_weather_extended_forecast_text', esc_html__( 'extended forecast', 'waypoint-hd-weather-widget' ) );
        $rtn .= '<div class="waypoint-weather-more-weather-link">';
        $rtn .= '<a href="' . esc_url( 'https://openweathermap.org/city/' . $today->id ) . '" target="_blank" rel="noopener">' . esc_html( $show_link_text ) . '</a>';
        $rtn .= '</div>';
    }

    if ( $background ) {
        $rtn .= '</div></div>';
    }

    $rtn .= '</div>';
    return $rtn;
}

/**
 * Error message helper
 */
function waypoint_weather_error( $msg = false ) {
    if ( ! $msg ) {
        $msg = esc_html__( 'No weather information available', 'waypoint-hd-weather-widget' );
    }
    
    // Show user-friendly error message instead of HTML comment
    $error_output = '<div class="waypoint-weather-error" style="padding:20px;background:#f8d7da;color:#721c24;border:1px solid #f5c6cb;border-radius:4px;margin:10px 0;">';
    $error_output .= '<strong>' . esc_html__( 'Weather Error:', 'waypoint-hd-weather-widget' ) . '</strong> ';
    $error_output .= esc_html( $msg );
    $error_output .= '</div>';
    
    return apply_filters( 'waypoint_weather_error', $error_output );
}

/**
 * Weather Widget Class
 */
class WaypointWeatherWidget extends WP_Widget {

    /**
     * Constructor (PHP 5+ style)
     */
    public function __construct() {
        parent::__construct(
            'waypoint_weather_widget',
            esc_html__( 'HD Weather Widget by The Waypoint', 'waypoint-hd-weather-widget' ),
            array( 
                'description' => esc_html__( 'A weather widget designed for 331dpi Screens, It\'s HD!', 'waypoint-hd-weather-widget' ),
                'classname' => 'waypoint_weather_widget',
            )
        );
    }

    /**
     * Widget output
     */
    public function widget( $args, $instance ) {
        $location = isset( $instance['location'] ) ? $instance['location'] : false;
        $override_title = isset( $instance['override_title'] ) ? $instance['override_title'] : false;
        $units = isset( $instance['units'] ) ? $instance['units'] : false;
        $size = isset( $instance['size'] ) ? $instance['size'] : false;
        $forecast_days = isset( $instance['forecast_days'] ) ? $instance['forecast_days'] : false;
        $hide_stats = ( isset( $instance['hide_stats'] ) && $instance['hide_stats'] == 1 ) ? 1 : 0;
        $show_link = ( isset( $instance['show_link'] ) && $instance['show_link'] == 1 ) ? 1 : 0;
        $background = isset( $instance['background'] ) ? $instance['background'] : false;

        echo $args['before_widget'];
        echo waypoint_weather_logic( array(
            'location' => $location,
            'override_title' => $override_title,
            'size' => $size,
            'units' => $units,
            'forecast_days' => $forecast_days,
            'hide_stats' => $hide_stats,
            'show_link' => $show_link,
            'background' => $background,
        ) );
        echo $args['after_widget'];
    }

    /**
     * Update widget settings
     */
    public function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['location'] = sanitize_text_field( $new_instance['location'] );
        $instance['override_title'] = sanitize_text_field( $new_instance['override_title'] );
        $instance['units'] = sanitize_text_field( $new_instance['units'] );
        $instance['size'] = sanitize_text_field( $new_instance['size'] );
        $instance['forecast_days'] = sanitize_text_field( $new_instance['forecast_days'] );
        $instance['hide_stats'] = isset( $new_instance['hide_stats'] ) ? 1 : 0;
        $instance['show_link'] = isset( $new_instance['show_link'] ) ? 1 : 0;
        $instance['background'] = esc_url_raw( $new_instance['background'] );
        return $instance;
    }

    /**
     * Widget form
     */
    public function form( $instance ) {
        global $waypoint_weather_sizes;

        $location = isset( $instance['location'] ) ? esc_attr( $instance['location'] ) : '';
        $override_title = isset( $instance['override_title'] ) ? esc_attr( $instance['override_title'] ) : '';
        $selected_size = isset( $instance['size'] ) ? esc_attr( $instance['size'] ) : 'wide';
        $units = isset( $instance['units'] ) ? esc_attr( $instance['units'] ) : 'imperial';
        $forecast_days = isset( $instance['forecast_days'] ) ? esc_attr( $instance['forecast_days'] ) : 5;
        $hide_stats = ( isset( $instance['hide_stats'] ) && $instance['hide_stats'] == 1 ) ? 1 : 0;
        $show_link = ( isset( $instance['show_link'] ) && $instance['show_link'] == 1 ) ? 1 : 0;
        $background = isset( $instance['background'] ) ? esc_attr( $instance['background'] ) : '';
        ?>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'location' ) ); ?>">
                <?php esc_html_e( 'Location:', 'waypoint-hd-weather-widget' ); ?>
            </label>
            <input class="widefat" 
                   id="<?php echo esc_attr( $this->get_field_id( 'location' ) ); ?>" 
                   name="<?php echo esc_attr( $this->get_field_name( 'location' ) ); ?>" 
                   type="text" 
                   value="<?php echo esc_attr( $location ); ?>" />
            <br /><a href="https://openweathermap.org/" target="_blank" rel="noopener"><?php esc_html_e( 'Use this link to find your city FIRST.', 'waypoint-hd-weather-widget' ); ?></a>
        </p>

        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'override_title' ) ); ?>">
                <?php esc_html_e( 'Override Title:', 'waypoint-hd-weather-widget' ); ?>
            </label>
            <input class="widefat" 
                   id="<?php echo esc_attr( $this->get_field_id( 'override_title' ) ); ?>" 
                   name="<?php echo esc_attr( $this->get_field_name( 'override_title' ) ); ?>" 
                   type="text" 
                   value="<?php echo esc_attr( $override_title ); ?>" />
        </p>

        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'units' ) ); ?>">
                <?php esc_html_e( 'Units:', 'waypoint-hd-weather-widget' ); ?>
            </label> &nbsp;
            <input id="<?php echo esc_attr( $this->get_field_id( 'units' ) ); ?>_f" 
                   name="<?php echo esc_attr( $this->get_field_name( 'units' ) ); ?>" 
                   type="radio" 
                   value="imperial" 
                   <?php checked( $units, 'imperial' ); ?> /> 
            <label for="<?php echo esc_attr( $this->get_field_id( 'units' ) ); ?>_f">F</label> &nbsp;
            <input id="<?php echo esc_attr( $this->get_field_id( 'units' ) ); ?>_c" 
                   name="<?php echo esc_attr( $this->get_field_name( 'units' ) ); ?>" 
                   type="radio" 
                   value="metric" 
                   <?php checked( $units, 'metric' ); ?> /> 
            <label for="<?php echo esc_attr( $this->get_field_id( 'units' ) ); ?>_c">C</label>
        </p>

        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'size' ) ); ?>">
                <?php esc_html_e( 'Size:', 'waypoint-hd-weather-widget' ); ?>
            </label>
            <select class="widefat" 
                    id="<?php echo esc_attr( $this->get_field_id( 'size' ) ); ?>" 
                    name="<?php echo esc_attr( $this->get_field_name( 'size' ) ); ?>">
                <?php foreach ( $waypoint_weather_sizes as $size_option ) { ?>
                    <option value="<?php echo esc_attr( $size_option ); ?>" <?php selected( $selected_size, $size_option ); ?>>
                        <?php echo esc_html( ucfirst( $size_option ) ); ?>
                    </option>
                <?php } ?>
            </select>
        </p>

        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'forecast_days' ) ); ?>">
                <?php esc_html_e( 'Forecast:', 'waypoint-hd-weather-widget' ); ?>
            </label>
            <select class="widefat" 
                    id="<?php echo esc_attr( $this->get_field_id( 'forecast_days' ) ); ?>" 
                    name="<?php echo esc_attr( $this->get_field_name( 'forecast_days' ) ); ?>">
                <option value="5" <?php selected( $forecast_days, '5' ); ?>>5 Days</option>
                <option value="4" <?php selected( $forecast_days, '4' ); ?>>4 Days</option>
                <option value="3" <?php selected( $forecast_days, '3' ); ?>>3 Days</option>
                <option value="2" <?php selected( $forecast_days, '2' ); ?>>2 Days</option>
                <option value="1" <?php selected( $forecast_days, '1' ); ?>>1 Day</option>
                <option value="hide" <?php selected( $forecast_days, 'hide' ); ?>><?php esc_html_e( "Don't Show", 'waypoint-hd-weather-widget' ); ?></option>
            </select>
        </p>

        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'background' ) ); ?>">
                <?php esc_html_e( 'Background Image:', 'waypoint-hd-weather-widget' ); ?>
            </label>
            <input class="widefat" 
                   id="<?php echo esc_attr( $this->get_field_id( 'background' ) ); ?>" 
                   name="<?php echo esc_attr( $this->get_field_name( 'background' ) ); ?>" 
                   type="text" 
                   value="<?php echo esc_attr( $background ); ?>" />
        </p>

        <p>
            <input id="<?php echo esc_attr( $this->get_field_id( 'hide_stats' ) ); ?>" 
                   name="<?php echo esc_attr( $this->get_field_name( 'hide_stats' ) ); ?>" 
                   type="checkbox" 
                   value="1" 
                   <?php checked( $hide_stats, 1 ); ?> />
            <label for="<?php echo esc_attr( $this->get_field_id( 'hide_stats' ) ); ?>">
                <?php esc_html_e( 'Hide Stats', 'waypoint-hd-weather-widget' ); ?>
            </label>
        </p>

        <p>
            <input id="<?php echo esc_attr( $this->get_field_id( 'show_link' ) ); ?>" 
                   name="<?php echo esc_attr( $this->get_field_name( 'show_link' ) ); ?>" 
                   type="checkbox" 
                   value="1" 
                   <?php checked( $show_link, 1 ); ?> />
            <label for="<?php echo esc_attr( $this->get_field_id( 'show_link' ) ); ?>">
                <?php esc_html_e( 'Link to OpenWeatherMap', 'waypoint-hd-weather-widget' ); ?>
            </label>
        </p>
        <?php
    }
}

/**
 * Register widget (PHP 7.4+ compatible)
 */
add_action( 'widgets_init', function() {
    register_widget( 'WaypointWeatherWidget' );
});
