<?php

declare(strict_types=1);


/**
 * Privacy Compliance Provider
 *
 * Handles GDPR/CCPA compliance checking, cookie consent validation, and privacy auditing.
 *
 * @package ProRank\SEO\Core\DataProviders
 */

namespace ProRank\SEO\Core\DataProviders;

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


/**
 * Provides privacy compliance scanning and auditing functionality
 */


class PrivacyComplianceProvider {
    /**
     * Cache prefix for compliance scans
     */
    const CACHE_PREFIX = 'prorank_privacy_';

    /**
     * Cache duration (1 hour)
     */
    const CACHE_DURATION = 3600;

    /**
     * Known third-party tracking scripts
     */
    const TRACKING_SCRIPTS = [
        // Analytics
        'google-analytics.com'      => ['category' => 'analytics', 'name' => 'Google Analytics', 'privacy_impact' => 'medium'],
        'googletagmanager.com'      => ['category' => 'analytics', 'name' => 'Google Tag Manager', 'privacy_impact' => 'medium'],
        'analytics.google.com'      => ['category' => 'analytics', 'name' => 'Google Analytics 4', 'privacy_impact' => 'medium'],
        'matomo'                    => ['category' => 'analytics', 'name' => 'Matomo', 'privacy_impact' => 'low'],
        'plausible.io'              => ['category' => 'analytics', 'name' => 'Plausible', 'privacy_impact' => 'low'],
        'fathom'                    => ['category' => 'analytics', 'name' => 'Fathom', 'privacy_impact' => 'low'],
        'hotjar.com'                => ['category' => 'analytics', 'name' => 'Hotjar', 'privacy_impact' => 'high'],
        'clarity.ms'                => ['category' => 'analytics', 'name' => 'Microsoft Clarity', 'privacy_impact' => 'medium'],
        'mixpanel.com'              => ['category' => 'analytics', 'name' => 'Mixpanel', 'privacy_impact' => 'medium'],
        'segment.com'               => ['category' => 'analytics', 'name' => 'Segment', 'privacy_impact' => 'medium'],
        'heap'                      => ['category' => 'analytics', 'name' => 'Heap Analytics', 'privacy_impact' => 'medium'],

        // Advertising
        'googlesyndication.com'     => ['category' => 'advertising', 'name' => 'Google AdSense', 'privacy_impact' => 'high'],
        'doubleclick.net'           => ['category' => 'advertising', 'name' => 'DoubleClick', 'privacy_impact' => 'high'],
        'facebook.net'              => ['category' => 'advertising', 'name' => 'Facebook Pixel', 'privacy_impact' => 'high'],
        'connect.facebook.net'      => ['category' => 'advertising', 'name' => 'Facebook SDK', 'privacy_impact' => 'high'],
        'ads.linkedin.com'          => ['category' => 'advertising', 'name' => 'LinkedIn Ads', 'privacy_impact' => 'high'],
        'snap.licdn.com'            => ['category' => 'advertising', 'name' => 'LinkedIn Insight', 'privacy_impact' => 'high'],
        'ads.twitter.com'           => ['category' => 'advertising', 'name' => 'Twitter Ads', 'privacy_impact' => 'high'],
        'tiktok.com/i18n'           => ['category' => 'advertising', 'name' => 'TikTok Pixel', 'privacy_impact' => 'high'],
        'pinterest.com/ct'          => ['category' => 'advertising', 'name' => 'Pinterest Tag', 'privacy_impact' => 'medium'],
        'adroll.com'                => ['category' => 'advertising', 'name' => 'AdRoll', 'privacy_impact' => 'high'],

        // Social
        'platform.twitter.com'      => ['category' => 'social', 'name' => 'Twitter Embed', 'privacy_impact' => 'medium'],
        'platform.linkedin.com'     => ['category' => 'social', 'name' => 'LinkedIn Embed', 'privacy_impact' => 'medium'],
        'instagram.com/embed'       => ['category' => 'social', 'name' => 'Instagram Embed', 'privacy_impact' => 'medium'],
        'addthis.com'               => ['category' => 'social', 'name' => 'AddThis', 'privacy_impact' => 'high'],
        'sharethis.com'             => ['category' => 'social', 'name' => 'ShareThis', 'privacy_impact' => 'high'],

        // Essential / Low Impact
        'fonts.googleapis.com'      => ['category' => 'essential', 'name' => 'Google Fonts', 'privacy_impact' => 'low'],
        'fonts.gstatic.com'         => ['category' => 'essential', 'name' => 'Google Fonts Static', 'privacy_impact' => 'low'],
        'www.recaptcha.net'         => ['category' => 'essential', 'name' => 'reCAPTCHA', 'privacy_impact' => 'medium'],
        'www.google.com/recaptcha'  => ['category' => 'essential', 'name' => 'reCAPTCHA', 'privacy_impact' => 'medium'],
    ];

    /**
     * GDPR required sections in privacy policy
     */
    const GDPR_REQUIRED_SECTIONS = [
        'data_controller'     => ['keywords' => ['data controller', 'controller', 'responsible party'], 'required' => true],
        'data_collected'      => ['keywords' => ['data we collect', 'information we collect', 'personal data'], 'required' => true],
        'legal_basis'         => ['keywords' => ['legal basis', 'lawful basis', 'legitimate interest'], 'required' => true],
        'data_retention'      => ['keywords' => ['retention', 'how long', 'storage period'], 'required' => true],
        'data_rights'         => ['keywords' => ['your rights', 'right to access', 'right to erasure', 'right to rectification'], 'required' => true],
        'contact_info'        => ['keywords' => ['contact us', 'email', 'address'], 'required' => true],
        'cookies'             => ['keywords' => ['cookie', 'cookies'], 'required' => true],
        'third_parties'       => ['keywords' => ['third party', 'third parties', 'share', 'disclose'], 'required' => true],
        'international'       => ['keywords' => ['international', 'transfer', 'outside'], 'required' => false],
        'dpo'                 => ['keywords' => ['data protection officer', 'dpo'], 'required' => false],
    ];

    /**
     * CCPA required sections
     */
    const CCPA_REQUIRED_SECTIONS = [
        'categories'          => ['keywords' => ['categories of personal information', 'types of information'], 'required' => true],
        'purpose'             => ['keywords' => ['purpose', 'why we collect', 'business purpose'], 'required' => true],
        'sale_disclosure'     => ['keywords' => ['do not sell', 'sale of personal information', 'selling'], 'required' => true],
        'rights'              => ['keywords' => ['right to know', 'right to delete', 'california residents'], 'required' => true],
        'opt_out'             => ['keywords' => ['opt-out', 'opt out'], 'required' => true],
        'contact'             => ['keywords' => ['contact', 'submit a request'], 'required' => true],
        'non_discrimination'  => ['keywords' => ['non-discrimination', 'not discriminate'], 'required' => false],
    ];

    /**
     * Known cookie consent plugins
     */
    const CONSENT_PLUGINS = [
        'cookieyes'           => ['name' => 'CookieYes', 'indicators' => ['cookieyes', 'cky-consent']],
        'cookiebot'           => ['name' => 'Cookiebot', 'indicators' => ['cookiebot', 'Cookiebot']],
        'complianz'           => ['name' => 'Complianz', 'indicators' => ['complianz', 'cmplz']],
        'iubenda'             => ['name' => 'Iubenda', 'indicators' => ['iubenda']],
        'termly'              => ['name' => 'Termly', 'indicators' => ['termly']],
        'onetrust'            => ['name' => 'OneTrust', 'indicators' => ['onetrust', 'optanon']],
        'quantcast'           => ['name' => 'Quantcast Choice', 'indicators' => ['quantcast', '__cmpLocator']],
        'gdpr_cookie'         => ['name' => 'GDPR Cookie Compliance', 'indicators' => ['gdpr-cookie-notice']],
        'cookie_notice'       => ['name' => 'Cookie Notice', 'indicators' => ['cookie-notice', 'cn-']],
        'wp_consent_api'      => ['name' => 'WP Consent API', 'indicators' => ['wp-consent-api']],
    ];

    /**
     * Run full compliance scan
     *
     * @param bool $force_refresh Force cache refresh
     * @return array
     */
    public function run_compliance_scan( bool $force_refresh = false ) {
        $cache_key = self::CACHE_PREFIX . 'full_scan';

        if ( ! $force_refresh ) {
            $cached = get_transient( $cache_key );
            if ( $cached !== false ) {
                return $cached;
            }
        }

        $results = [
            'timestamp'        => current_time( 'mysql' ),
            'overall_score'    => 0,
            'status'           => 'unknown',
            'cookie_consent'   => $this->check_cookie_consent(),
            'privacy_policy'   => $this->check_privacy_policy(),
            'scripts'          => $this->audit_third_party_scripts(),
            'forms'            => $this->check_form_consent(),
            'recommendations'  => [],
        ];

        // Calculate overall score
        $scores = [];
        $scores[] = $results['cookie_consent']['score'] ?? 0;
        $scores[] = $results['privacy_policy']['score'] ?? 0;
        $scores[] = $results['scripts']['score'] ?? 0;
        $scores[] = $results['forms']['score'] ?? 0;

        $results['overall_score'] = round( array_sum( $scores ) / count( $scores ) );

        // Determine status
        $results['status'] = match ( true ) {
            $results['overall_score'] >= 90 => 'compliant',
            $results['overall_score'] >= 70 => 'minor_issues',
            $results['overall_score'] >= 50 => 'needs_attention',
            default                          => 'critical',
        };

        // Generate recommendations
        $results['recommendations'] = $this->generate_recommendations( $results );

        // Cache results
        set_transient( $cache_key, $results, self::CACHE_DURATION );

        return $results;
    }

    /**
     * Check cookie consent mechanism
     *
     * @return array
     */
    public function check_cookie_consent() {
        $home_url = home_url( '/' );
        $response = wp_remote_get( $home_url, [
            'timeout' => 10,
            'sslverify' => true,
        ] );

        if ( is_wp_error( $response ) ) {
            return [
                'detected'      => false,
                'plugin'        => null,
                'score'         => 0,
                'issues'        => ['Could not fetch homepage to check consent'],
            ];
        }

        $body = wp_remote_retrieve_body( $response );
        $issues = [];
        $detected_plugin = null;

        // Check for known consent plugins
        foreach ( self::CONSENT_PLUGINS as $plugin_key => $plugin_info ) {
            foreach ( $plugin_info['indicators'] as $indicator ) {
                if ( stripos( $body, $indicator ) !== false ) {
                    $detected_plugin = $plugin_info['name'];
                    break 2;
                }
            }
        }

        // Check for generic consent indicators
        $has_consent_ui = preg_match( '/(cookie|consent|gdpr|privacy).*(banner|notice|popup|modal)/i', $body );
        $has_accept_button = preg_match( '/(accept|agree|allow).*(cookie|all)/i', $body );
        $has_reject_option = preg_match( '/(reject|decline|deny|necessary only)/i', $body );
        $has_preferences = preg_match( '/(preferences|settings|customize|manage)/i', $body );

        // Check for pre-checked boxes (bad practice)
        $has_prechecked = preg_match( '/checked.*=.*["\']?checked/i', $body );

        // Score calculation
        $score = 0;
        if ( $detected_plugin || $has_consent_ui ) {
            $score += 40;
        } else {
            $issues[] = 'No cookie consent mechanism detected';
        }

        if ( $has_accept_button ) {
            $score += 20;
        }

        if ( $has_reject_option ) {
            $score += 20;
        } else {
            $issues[] = 'No clear reject/decline option visible';
        }

        if ( $has_preferences ) {
            $score += 20;
        } else {
            $issues[] = 'No cookie preferences/customization option';
        }

        if ( $has_prechecked ) {
            $score -= 20;
            $issues[] = 'Pre-checked consent boxes detected (GDPR violation)';
        }

        return [
            'detected'         => $detected_plugin !== null || $has_consent_ui,
            'plugin'           => $detected_plugin,
            'has_accept'       => (bool) $has_accept_button,
            'has_reject'       => (bool) $has_reject_option,
            'has_preferences'  => (bool) $has_preferences,
            'has_prechecked'   => (bool) $has_prechecked,
            'score'            => max( 0, min( 100, $score ) ),
            'issues'           => $issues,
        ];
    }

    /**
     * Check privacy policy page
     *
     * @return array
     */
    public function check_privacy_policy() {
        // Check WordPress privacy policy page setting
        $privacy_page_id = get_option( 'wp_page_for_privacy_policy' );
        $issues = [];
        $found_sections = [];

        if ( ! $privacy_page_id ) {
            return [
                'exists'         => false,
                'page_id'        => null,
                'url'            => null,
                'last_updated'   => null,
                'gdpr_sections'  => [],
                'ccpa_sections'  => [],
                'score'          => 0,
                'issues'         => ['No privacy policy page configured in WordPress'],
            ];
        }

        $page = get_post( $privacy_page_id );
        if ( ! $page || $page->post_status !== 'publish' ) {
            return [
                'exists'         => false,
                'page_id'        => $privacy_page_id,
                'url'            => null,
                'last_updated'   => null,
                'gdpr_sections'  => [],
                'ccpa_sections'  => [],
                'score'          => 0,
                'issues'         => ['Privacy policy page exists but is not published'],
            ];
        }

        $content = strtolower( wp_strip_all_tags( $page->post_content ) );
        $url = get_permalink( $privacy_page_id );

        // Check GDPR sections
        $gdpr_sections = [];
        foreach ( self::GDPR_REQUIRED_SECTIONS as $section_key => $section_info ) {
            $found = false;
            foreach ( $section_info['keywords'] as $keyword ) {
                if ( stripos( $content, $keyword ) !== false ) {
                    $found = true;
                    break;
                }
            }
            $gdpr_sections[ $section_key ] = [
                'found'    => $found,
                'required' => $section_info['required'],
            ];
            if ( ! $found && $section_info['required'] ) {
                $issues[] = "Missing GDPR section: {$section_key}";
            }
        }

        // Check CCPA sections
        $ccpa_sections = [];
        foreach ( self::CCPA_REQUIRED_SECTIONS as $section_key => $section_info ) {
            $found = false;
            foreach ( $section_info['keywords'] as $keyword ) {
                if ( stripos( $content, $keyword ) !== false ) {
                    $found = true;
                    break;
                }
            }
            $ccpa_sections[ $section_key ] = [
                'found'    => $found,
                'required' => $section_info['required'],
            ];
            if ( ! $found && $section_info['required'] ) {
                $issues[] = "Missing CCPA section: {$section_key}";
            }
        }

        // Check last updated
        $last_updated = $page->post_modified;
        $days_since_update = ( time() - strtotime( $last_updated ) ) / DAY_IN_SECONDS;

        if ( $days_since_update > 365 ) {
            $issues[] = 'Privacy policy not updated in over a year';
        }

        // Calculate score
        $gdpr_required = array_filter( $gdpr_sections, fn( $s ) => $s['required'] );
        $gdpr_found = array_filter( $gdpr_required, fn( $s ) => $s['found'] );
        $gdpr_score = count( $gdpr_required ) > 0 ? ( count( $gdpr_found ) / count( $gdpr_required ) ) * 50 : 0;

        $ccpa_required = array_filter( $ccpa_sections, fn( $s ) => $s['required'] );
        $ccpa_found = array_filter( $ccpa_required, fn( $s ) => $s['found'] );
        $ccpa_score = count( $ccpa_required ) > 0 ? ( count( $ccpa_found ) / count( $ccpa_required ) ) * 30 : 0;

        $freshness_score = $days_since_update <= 365 ? 20 : 10;

        return [
            'exists'         => true,
            'page_id'        => $privacy_page_id,
            'url'            => $url,
            'last_updated'   => $last_updated,
            'days_since_update' => round( $days_since_update ),
            'gdpr_sections'  => $gdpr_sections,
            'ccpa_sections'  => $ccpa_sections,
            'score'          => round( $gdpr_score + $ccpa_score + $freshness_score ),
            'issues'         => $issues,
        ];
    }

    /**
     * Audit third-party scripts
     *
     * @return array
     */
    public function audit_third_party_scripts() {
        $home_url = home_url( '/' );
        $response = wp_remote_get( $home_url, [
            'timeout' => 10,
            'sslverify' => true,
        ] );

        if ( is_wp_error( $response ) ) {
            return [
                'scripts'       => [],
                'by_category'   => [],
                'privacy_score' => 50,
                'score'         => 50,
                'issues'        => ['Could not fetch homepage to audit scripts'],
            ];
        }

        $body = wp_remote_retrieve_body( $response );
        $detected_scripts = [];
        $issues = [];

        // Find all script sources
        preg_match_all( '/src=["\']([^"\']+)["\']/', $body, $matches );
        $script_urls = $matches[1] ?? [];

        // Also check for inline script references
        foreach ( self::TRACKING_SCRIPTS as $domain => $info ) {
            if ( stripos( $body, $domain ) !== false ) {
                $detected_scripts[] = [
                    'domain'         => $domain,
                    'name'           => $info['name'],
                    'category'       => $info['category'],
                    'privacy_impact' => $info['privacy_impact'],
                ];
            }
        }

        // Remove duplicates
        $detected_scripts = array_unique( $detected_scripts, SORT_REGULAR );

        // Group by category
        $by_category = [];
        foreach ( $detected_scripts as $script ) {
            $category = $script['category'];
            if ( ! isset( $by_category[ $category ] ) ) {
                $by_category[ $category ] = [];
            }
            $by_category[ $category ][] = $script;
        }

        // Calculate privacy score
        $high_impact = count( array_filter( $detected_scripts, fn( $s ) => $s['privacy_impact'] === 'high' ) );
        $medium_impact = count( array_filter( $detected_scripts, fn( $s ) => $s['privacy_impact'] === 'medium' ) );

        $privacy_penalty = ( $high_impact * 15 ) + ( $medium_impact * 5 );
        $privacy_score = max( 0, 100 - $privacy_penalty );

        // Generate issues
        if ( $high_impact > 0 ) {
            $issues[] = "{$high_impact} high privacy impact scripts detected";
        }
        if ( isset( $by_category['advertising'] ) && count( $by_category['advertising'] ) > 0 ) {
            $issues[] = 'Advertising trackers require explicit consent';
        }

        return [
            'scripts'        => $detected_scripts,
            'by_category'    => $by_category,
            'total_count'    => count( $detected_scripts ),
            'high_impact'    => $high_impact,
            'medium_impact'  => $medium_impact,
            'privacy_score'  => $privacy_score,
            'score'          => $privacy_score,
            'issues'         => $issues,
        ];
    }

    /**
     * Check form consent mechanisms
     *
     * @return array
     */
    public function check_form_consent() {
        // Check for common form plugins and their consent mechanisms
        $has_cf7 = is_plugin_active( 'contact-form-7/wp-contact-form-7.php' );
        $has_wpforms = is_plugin_active( 'wpforms-lite/wpforms.php' ) || is_plugin_active( 'wpforms/wpforms.php' );
        $has_gravity = is_plugin_active( 'gravityforms/gravityforms.php' );
        $has_ninja = is_plugin_active( 'ninja-forms/ninja-forms.php' );

        $forms_detected = [];
        $issues = [];

        if ( $has_cf7 ) {
            $forms_detected[] = 'Contact Form 7';
        }
        if ( $has_wpforms ) {
            $forms_detected[] = 'WPForms';
        }
        if ( $has_gravity ) {
            $forms_detected[] = 'Gravity Forms';
        }
        if ( $has_ninja ) {
            $forms_detected[] = 'Ninja Forms';
        }

        // Check for comment form
        if ( get_option( 'default_comment_status' ) === 'open' ) {
            $forms_detected[] = 'WordPress Comments';
        }

        // Check for WooCommerce
        if ( is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
            $forms_detected[] = 'WooCommerce Checkout';
        }

        // Score based on form count (assuming each needs consent)
        $form_count = count( $forms_detected );
        $score = $form_count === 0 ? 100 : max( 50, 100 - ( $form_count * 10 ) );

        if ( $form_count > 0 ) {
            $issues[] = 'Ensure all forms have proper consent checkboxes';
            $issues[] = 'Review form data handling and retention policies';
        }

        return [
            'forms_detected' => $forms_detected,
            'form_count'     => $form_count,
            'score'          => $score,
            'issues'         => $issues,
        ];
    }

    /**
     * Generate recommendations based on scan results
     *
     * @param array $results Scan results
     * @return array
     */
    private function generate_recommendations( array $results ) {
        $recommendations = [];

        // Cookie consent recommendations
        if ( ! $results['cookie_consent']['detected'] ) {
            $recommendations[] = [
                'priority' => 'critical',
                'category' => 'cookie_consent',
                'title'    => __( 'Install Cookie Consent Plugin', 'prorank-seo' ),
                'message'  => __( 'No cookie consent mechanism detected. Install a GDPR-compliant cookie consent plugin like CookieYes, Complianz, or Cookiebot.', 'prorank-seo' ),
                'link'     => 'https://wordpress.org/plugins/search/cookie+consent/',
            ];
        } elseif ( ! $results['cookie_consent']['has_reject'] ) {
            $recommendations[] = [
                'priority' => 'high',
                'category' => 'cookie_consent',
                'title'    => __( 'Add Reject Option', 'prorank-seo' ),
                'message'  => __( 'Your cookie consent should have a clear "Reject" or "Necessary Only" option that is equally prominent as the Accept button.', 'prorank-seo' ),
            ];
        }

        // Privacy policy recommendations
        if ( ! $results['privacy_policy']['exists'] ) {
            $recommendations[] = [
                'priority' => 'critical',
                'category' => 'privacy_policy',
                'title'    => __( 'Create Privacy Policy', 'prorank-seo' ),
                'message'  => __( 'No privacy policy page configured. Go to Settings > Privacy to create or assign one.', 'prorank-seo' ),
                'link'     => admin_url( 'options-privacy.php' ),
            ];
        } else {
            $missing_gdpr = array_filter(
                $results['privacy_policy']['gdpr_sections'] ?? [],
                fn( $s ) => $s['required'] && ! $s['found']
            );
            if ( ! empty( $missing_gdpr ) ) {
                $recommendations[] = [
                    'priority' => 'high',
                    'category' => 'privacy_policy',
                    'title'    => __( 'Update Privacy Policy for GDPR', 'prorank-seo' ),
                    'message'  => sprintf(
/* translators: %1$: value */
                        __( 'Missing GDPR required sections: %1$s', 'prorank-seo' ),
                        implode( ', ', array_keys( $missing_gdpr ) )
                    ),
                    'link'     => get_edit_post_link( $results['privacy_policy']['page_id'] ),
                ];
            }
        }

        // Script recommendations
        if ( ( $results['scripts']['high_impact'] ?? 0 ) > 0 ) {
            $recommendations[] = [
                'priority' => 'high',
                'category' => 'scripts',
                'title'    => __( 'Review High-Impact Tracking Scripts', 'prorank-seo' ),
                'message'  => __( 'High privacy impact scripts detected. Ensure these only load after user consent.', 'prorank-seo' ),
            ];
        }

        if ( isset( $results['scripts']['by_category']['advertising'] ) ) {
            $recommendations[] = [
                'priority' => 'medium',
                'category' => 'scripts',
                'title'    => __( 'Advertising Scripts Require Consent', 'prorank-seo' ),
                'message'  => __( 'Advertising/marketing scripts must only load after explicit user consent under GDPR.', 'prorank-seo' ),
            ];
        }

        return $recommendations;
    }

    /**
     * Get compliance summary for dashboard
     *
     * @return array
     */
    public function get_summary() {
        $scan = $this->run_compliance_scan();

        return [
            'score'           => $scan['overall_score'],
            'status'          => $scan['status'],
            'status_label'    => $this->get_status_label( $scan['status'] ),
            'cookie_consent'  => $scan['cookie_consent']['detected'],
            'privacy_policy'  => $scan['privacy_policy']['exists'],
            'high_impact_scripts' => $scan['scripts']['high_impact'] ?? 0,
            'critical_issues' => count( array_filter(
                $scan['recommendations'],
                fn( $r ) => $r['priority'] === 'critical'
            ) ),
            'last_scan'       => $scan['timestamp'],
        ];
    }

    /**
     * Get status label
     *
     * @param string $status Status key
     * @return string
     */
    private function get_status_label( string $status ) {
        return match ( $status ) {
            'compliant'       => __( 'Compliant', 'prorank-seo' ),
            'minor_issues'    => __( 'Minor Issues', 'prorank-seo' ),
            'needs_attention' => __( 'Needs Attention', 'prorank-seo' ),
            'critical'        => __( 'Critical Issues', 'prorank-seo' ),
            default           => __( 'Unknown', 'prorank-seo' ),
        };
    }

    /**
     * Clear compliance scan cache
     *
     * @return bool
     */
    public function clear_cache() {
        return delete_transient( self::CACHE_PREFIX . 'full_scan' );
    }
}
