<?php

declare(strict_types=1);


/**
 * Sustainability Data Provider
 *
 * @package ProRank\SEO\Core\DataProviders
 */

namespace ProRank\SEO\Core\DataProviders;

use ProRank\SEO\Plugin;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}


/**
 * Provides sustainability metrics for web pages
 */


class SustainabilityProvider {
    /**
     * Cache prefix for transients
     */
    const CACHE_PREFIX = 'prorank_sustainability_';

    /**
     * Cache duration in seconds (24 hours)
     */
    const CACHE_DURATION = 86400;

    /**
     * CO2 API endpoint (using Website Carbon API data endpoint)
     */
    const API_ENDPOINT = 'https://api.websitecarbon.com/data';

    /**
     * Get page sustainability estimate
     *
     * @param string $url URL to estimate
     * @return array|\WP_Error
     */
    public function get_page_sustainability_estimate( string $url ) {
        // Validate URL
        if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
            return new \WP_Error( 'invalid_url', __( 'Invalid URL provided', 'prorank-seo' ) );
        }

        // Check cache first
        $cache_key = self::CACHE_PREFIX . md5( $url );
        $cached = get_transient( $cache_key );
        
        if ( $cached !== false ) {
            return $cached;
        }

        // Get page size first
        $page_bytes = $this->get_page_size( $url );
        if ( is_wp_error( $page_bytes ) ) {
            return $page_bytes;
        }

        // Check if hosting is green (simplified check)
        $is_green = $this->check_green_hosting( $url );

        // Make API request with bytes and green parameters
        $api_url = add_query_arg( [
            'bytes' => $page_bytes,
            'green' => $is_green ? '1' : '0',
        ], self::API_ENDPOINT );

        $response = wp_remote_get( $api_url, [
            'timeout' => 10,
            'headers' => [
                'Accept' => 'application/json',
            ],
        ] );

        if ( is_wp_error( $response ) ) {
            prorank_log( sprintf( 
                'ProRank SEO: Sustainability API request failed for %s - %s', 
                $url, 
                $response->get_error_message() 
            ) );
            return new \WP_Error( 'api_error', __( 'Failed to fetch sustainability data', 'prorank-seo' ) );
        }

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

        if ( json_last_error() !== JSON_ERROR_NONE ) {
            return new \WP_Error( 'parse_error', __( 'Failed to parse API response', 'prorank-seo' ) );
        }

        // Transform API response to our format
        $estimate = $this->transform_api_response( $data, $url );

        // Cache the result
        set_transient( $cache_key, $estimate, self::CACHE_DURATION );

        return $estimate;
    }

    /**
     * Get page size in bytes
     *
     * @param string $url URL to check
     * @return int|\WP_Error
     */
    private function get_page_size( string $url ) {
        // For local URLs, try to calculate actual size
        if ( $this->is_local_url( $url ) ) {
            return $this->calculate_local_page_size( $url );
        }

        // For external URLs, make a HEAD request
        $response = wp_remote_head( $url, [
            'timeout' => 5,
            'redirection' => 3,
        ] );

        if ( is_wp_error( $response ) ) {
            // Fallback to GET request with byte range
            $response = wp_remote_get( $url, [
                'timeout' => 5,
                'redirection' => 3,
            ] );

            if ( is_wp_error( $response ) ) {
                // Use a default size if we can't get the actual size
                return 1500000; // 1.5MB default
            }
        }

        $body = wp_remote_retrieve_body( $response );
        $size = strlen( $body );

        // If size is too small, likely an error page
        if ( $size < 1000 ) {
            return 1500000; // Default size
        }

        return $size;
    }

    /**
     * Green Web Foundation API endpoint
     */
    const GREEN_WEB_API = 'https://api.thegreenwebfoundation.org/api/v3/greencheck/';

    /**
     * Known green hosting providers (verified carbon-neutral or 100% renewable)
     * Last updated: 2025
     */
    private const GREEN_HOSTS = [
        // Original providers
        'greengeeks.com',
        'dreamhost.com',
        'a2hosting.com',
        'siteground.com',
        'kinsta.com',

        // USA - Verified Green Hosts
        'wpengine.com',
        'pantheon.io',
        'cloudways.com',
        'flywheel.com',
        'hostpapa.com',
        'inmotionhosting.com',
        'greenhost.net',
        'aiso.net',
        'ecohosting.com',
        'sustainablewebsites.com',
        'acornhost.com',
        'canvahost.com',

        // Europe - Verified Green Hosts
        'hetzner.com',
        'hetzner.de',
        'infomaniak.com',
        'greenwebbox.com',
        'leaf.cloud',
        'datacenterlight.ch',
        'krystal.uk',
        'krystal.io',
        'kualo.com',
        'easyspace.com',
        'webarchitects.coop',
        'positive-internet.com',
        'raidboxes.io',
        'raidboxes.de',
        'eco-host.co',
        'biohost.de',
        'all-inkl.com',
        'mittwald.de',
        'manitu.de',
        'hostsharing.net',
        'jpberlin.de',
        'greensta.de',
        'petricore.nl',
        'antagonist.nl',
        'greengeeks.nl',
        'vimexx.nl',
        'strato.de',
        'strato.nl',

        // Cloud Providers (Carbon Neutral / 100% Renewable Regions)
        'cloud.google.com',
        'googlecloud.com',
        'azure.microsoft.com',
        'azure.com',
        'digitalocean.com',
        'linode.com',
        'akamai.com',
        'vultr.com',
        'netlify.com',
        'vercel.com',
        'render.com',
        'railway.app',
        'fly.io',
        'heroku.com',

        // European Cloud / VPS
        'scaleway.com',
        'ovhcloud.com',
        'ovh.com',
        'contabo.com',
        'ionos.com',
        'ionos.de',
        'hosteurope.de',
        'webgo.de',
        'netcup.de',
        'netcup.eu',
        'servinga.com',
        'gandi.net',
        'ikoula.com',
        'online.net',
        'pulseheberg.com',

        // Nordic (100% renewable grid)
        'simply.com',
        'one.com',
        'binero.se',
        'loopia.se',
        'webhuset.no',
        'domeneshop.no',
        'websupport.se',
        'miss.hosting',
        'oderland.se',
        'bahnhof.net',

        // UK Green Hosts
        'fasthosts.co.uk',
        '34sp.com',
        'tsohost.com',
        'lcn.com',
        'memset.com',
        'mythic-beasts.com',
        'bytemark.co.uk',

        // Australia / NZ
        'ventraip.com.au',
        'digital.nz',
        'netregistry.com.au',
        'crucial.com.au',
        'digitalpacific.com.au',
        'panthur.com.au',

        // Managed WordPress (Green certified)
        'pressable.com',
        'closte.com',
        'templ.io',
        'servebolt.com',
        'wordify.com',
        'developer.developer',
        'developer.developer',

        // CDN Providers (Carbon Neutral). Listed for detection/reporting only.
        'cloudflare.com',
        'fastly.com',
        'bunny.net',
        'bunnycdn.com',
        'keycdn.com',
        'stackpath.com',
    ];

    /**
     * Check if hosting is green
     *
     * @param string $url URL to check
     * @return bool
     */
    private function check_green_hosting( string $url ) {
        $host = wp_parse_url( $url, PHP_URL_HOST );
        if ( ! $host ) {
            return false;
        }

        // First check against our known green hosts list (fast, no API call)
        foreach ( self::GREEN_HOSTS as $green_host ) {
            if ( stripos( $host, $green_host ) !== false ) {
                return true;
            }
        }

        // Check if site has green hosting setting enabled
        if ( $this->is_local_url( $url ) ) {
            $settings_manager = \ProRank\SEO\Plugin::get_instance()->settings();
            $green_hosting = $settings_manager->get( 'ethical_seo_green_hosting_option', false );
            if ( $green_hosting ) {
                return true;
            }
        }

        // Fallback: Check Green Web Foundation API for dynamic verification
        return $this->check_green_web_foundation( $host );
    }

    /**
     * Check hosting via Green Web Foundation API
     *
     * @param string $host Hostname to check
     * @return bool
     */
    private function check_green_web_foundation( string $host ) {
        // Cache the result to avoid repeated API calls
        $cache_key = 'prorank_gwf_' . md5( $host );
        $cached = get_transient( $cache_key );

        if ( $cached !== false ) {
            return $cached === 'green';
        }

        $api_url = self::GREEN_WEB_API . rawurlencode( $host );

        $response = wp_remote_get( $api_url, [
            'timeout' => 5,
            'headers' => [
                'Accept' => 'application/json',
            ],
        ] );

        if ( is_wp_error( $response ) ) {
            // Don't cache errors, return false
            return false;
        }

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

        $is_green = ! empty( $data['green'] );

        // Cache for 7 days (hosting doesn't change often)
        set_transient( $cache_key, $is_green ? 'green' : 'not_green', 7 * DAY_IN_SECONDS );

        return $is_green;
    }

    /**
     * Get list of known green hosting providers
     *
     * @return array
     */
    public function get_green_hosts_list() {
        return self::GREEN_HOSTS;
    }

    /**
     * Verify a specific host via Green Web Foundation
     *
     * @param string $host Hostname to verify
     * @return array Verification result with details
     */
    public function verify_green_host( string $host ) {
        $api_url = self::GREEN_WEB_API . rawurlencode( $host );

        $response = wp_remote_get( $api_url, [
            'timeout' => 10,
            'headers' => [
                'Accept' => 'application/json',
            ],
        ] );

        if ( is_wp_error( $response ) ) {
            return [
                'verified' => false,
                'error' => $response->get_error_message(),
            ];
        }

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

        return [
            'verified' => true,
            'green' => ! empty( $data['green'] ),
            'hosted_by' => $data['hosted_by'] ?? null,
            'hosted_by_website' => $data['hosted_by_website'] ?? null,
            'supporting_documents' => $data['supporting_documents'] ?? [],
            'checked_at' => current_time( 'mysql' ),
        ];
    }

    /**
     * Check if URL is local
     *
     * @param string $url URL to check
     * @return bool
     */
    private function is_local_url( string $url ) {
        $site_url = home_url();
        return strpos( $url, $site_url ) === 0;
    }

    /**
     * Calculate local page size
     *
     * @param string $url Local URL
     * @return int
     */
    private function calculate_local_page_size( string $url ) {
        // Get the path from URL
        $path = str_replace( home_url(), '', $url );
        
        // Simulate a request to get the content
        $args = [
            'timeout' => 5,
            'redirection' => 0,
            'headers' => [
                'Accept-Encoding' => 'gzip, deflate',
            ],
        ];

        $response = wp_remote_get( $url, $args );
        
        if ( ! is_wp_error( $response ) ) {
            $body = wp_remote_retrieve_body( $response );
            $size = strlen( $body );
            
            // Add estimated size for external resources (CSS, JS, images)
            $size += $this->estimate_external_resources_size();
            
            return $size;
        }

        // Default fallback
        return 1500000;
    }

    /**
     * Estimate size of external resources
     *
     * @return int
     */
    private function estimate_external_resources_size() {
        // Rough estimate based on average WordPress site
        // This could be improved by actually parsing the page
        return 500000; // 500KB for CSS, JS, images
    }

    /**
     * Transform API response to standardized format
     *
     * @param array  $data API response data
     * @param string $url  Original URL
     * @return array
     */
    private function transform_api_response( array $data, string $url ) {
        $cleaner_than = isset($data['cleanerThan']) ? $data['cleanerThan'] * 100 : 0;
        
        return [
            'url' => $url,
            'timestamp' => current_time( 'mysql' ),
            'metrics' => [
                'carbon_per_view' => $data['gco2e'] ?? $data['statistics']['co2']['grid']['grams'] ?? 0,
                'carbon_rating' => $cleaner_than,
                'green_hosting' => $data['green'] ?? false,
                'bytes_transferred' => $data['bytes'] ?? 0,
                'energy_per_view' => $data['statistics']['energy'] ?? 0,
            ],
            'comparison' => [
                'cleaner_than_percent' => $cleaner_than,
                'rating' => $data['rating'] ?? $this->calculate_rating( $cleaner_than ),
            ],
            'recommendations' => $this->generate_recommendations( $data ),
        ];
    }

    /**
     * Calculate sustainability rating
     *
     * @param float $cleaner_than Percentage cleaner than other sites
     * @return string
     */
    private function calculate_rating( float $cleaner_than ) {
        if ( $cleaner_than >= 90 ) {
            return 'A+';
        } elseif ( $cleaner_than >= 80 ) {
            return 'A';
        } elseif ( $cleaner_than >= 70 ) {
            return 'B';
        } elseif ( $cleaner_than >= 60 ) {
            return 'C';
        } elseif ( $cleaner_than >= 50 ) {
            return 'D';
        } else {
            return 'F';
        }
    }

    /**
     * Generate sustainability recommendations
     *
     * @param array $data API response data
     * @return array
     */
    private function generate_recommendations( array $data ) {
        $recommendations = [];

        // Check green hosting
        if ( empty( $data['green'] ) ) {
            $recommendations[] = [
                'type' => 'hosting',
                'priority' => 'high',
                'message' => __( 'Consider switching to a green web hosting provider', 'prorank-seo' ),
                'impact' => __( 'Can reduce carbon emissions by up to 80%', 'prorank-seo' ),
            ];
        }

        // Check page size
        $bytes = $data['bytes'] ?? 0;
        if ( $bytes > 3000000 ) { // 3MB
            $recommendations[] = [
                'type' => 'optimization',
                'priority' => 'high',
                'message' => __( 'Reduce page size by optimizing images and assets', 'prorank-seo' ),
/* translators: %1$: value */
                'impact' => sprintf( __( 'Current page size: %1$s', 'prorank-seo' ), size_format( $bytes ) ),
            ];
        }

        // Check carbon per view
        $co2 = $data['statistics']['co2']['grid']['grams'] ?? 0;
        if ( $co2 > 1 ) { // More than 1g CO2 per view
            $recommendations[] = [
                'type' => 'efficiency',
                'priority' => 'medium',
                'message' => __( 'Improve page efficiency to reduce carbon emissions', 'prorank-seo' ),
/* translators: %1$: value */
                'impact' => sprintf( __( '%1$.2fg CO2 per page view', 'prorank-seo' ), $co2 ),
            ];
        }

        return $recommendations;
    }

    /**
     * Clear cache for a specific URL
     *
     * @param string $url URL to clear cache for
     * @return bool
     */
    public function clear_cache( string $url ) {
        $cache_key = self::CACHE_PREFIX . md5( $url );
        return delete_transient( $cache_key );
    }

    /**
     * Clear all sustainability caches
     *
     * @return int Number of caches cleared
     */
    public function clear_all_caches() {
        global $wpdb;
        
        return $wpdb->query(
            $wpdb->prepare(
                "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
                $wpdb->esc_like( '_transient_' . self::CACHE_PREFIX ) . '%'
            )
        );
    }

    /**
     * Get bulk sustainability estimates
     *
     * @param array $urls Array of URLs
     * @return array
     */
    public function get_bulk_estimates( array $urls ) {
        $results = [];
        
        foreach ( $urls as $url ) {
            $results[ $url ] = $this->get_page_sustainability_estimate( $url );
        }
        
        return $results;
    }

    /**
     * Calculate site-wide sustainability score
     *
     * @param int $sample_size Number of pages to sample
     * @return array|\WP_Error
     */
    public function calculate_site_score( int $sample_size = 10 ) {
        // Get sample of site URLs
        $urls = $this->get_sample_urls( $sample_size );
        
        if ( empty( $urls ) ) {
            return new \WP_Error( 'no_content', __( 'No content found to analyze', 'prorank-seo' ) );
        }

        // Get estimates for all URLs
        $estimates = $this->get_bulk_estimates( $urls );
        
        // Calculate averages
        $total_co2 = 0;
        $total_bytes = 0;
        $total_energy = 0;
        $green_count = 0;
        $valid_count = 0;
        
        foreach ( $estimates as $estimate ) {
            if ( ! is_wp_error( $estimate ) ) {
                $total_co2 += $estimate['metrics']['carbon_per_view'];
                $total_bytes += $estimate['metrics']['bytes_transferred'];
                $total_energy += $estimate['metrics']['energy_per_view'];
                if ( $estimate['metrics']['green_hosting'] ) {
                    $green_count++;
                }
                $valid_count++;
            }
        }
        
        if ( $valid_count === 0 ) {
            return new \WP_Error( 'no_valid_data', __( 'No valid sustainability data collected', 'prorank-seo' ) );
        }
        
        return [
            'sample_size' => $valid_count,
            'averages' => [
                'co2_per_view' => $total_co2 / $valid_count,
                'bytes_per_page' => $total_bytes / $valid_count,
                'energy_per_view' => $total_energy / $valid_count,
            ],
            'green_hosting_percentage' => ( $green_count / $valid_count ) * 100,
            'timestamp' => current_time( 'mysql' ),
        ];
    }

    /**
     * Get sample URLs from the site
     *
     * @param int $count Number of URLs to get
     * @return array
     */
    private function get_sample_urls( int $count ) {
        $urls = [];
        
        // Add home page
        $urls[] = home_url( '/' );
        
        // Get recent posts
        $posts = get_posts( [
            'numberposts' => $count - 1,
            'post_type' => 'post',
            'post_status' => 'publish',
            'orderby' => 'rand',
        ] );
        
        foreach ( $posts as $post ) {
            $urls[] = get_permalink( $post );
        }
        
        // Get some pages if we need more
        if ( count( $urls ) < $count ) {
            $pages = get_posts( [
                'numberposts' => $count - count( $urls ),
                'post_type' => 'page',
                'post_status' => 'publish',
                'orderby' => 'rand',
            ] );
            
            foreach ( $pages as $page ) {
                $urls[] = get_permalink( $page );
            }
        }
        
        return array_slice( $urls, 0, $count );
    }
}
