<?php
/**
 * GDPR Privacy Handler for Maple Carts.
 *
 * Integrates with WordPress and WooCommerce privacy tools.
 *
 * @package MapleCarts
 */

defined( 'ABSPATH' ) || exit;

/**
 * Privacy class.
 */
class Maple_Carts_Privacy {

    /**
     * Single instance.
     *
     * @var Maple_Carts_Privacy
     */
    private static $instance = null;

    /**
     * Get instance.
     *
     * @return Maple_Carts_Privacy
     */
    public static function instance() {
        if ( is_null( self::$instance ) ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Constructor.
     */
    private function __construct() {
        // WordPress Privacy hooks.
        add_action( 'admin_init', [ $this, 'add_privacy_policy_content' ] );
        add_filter( 'wp_privacy_personal_data_exporters', [ $this, 'register_data_exporter' ] );
        add_filter( 'wp_privacy_personal_data_erasers', [ $this, 'register_data_eraser' ] );

        // Checkout consent checkbox.
        if ( 'yes' === Maple_Carts::get_option( 'require_consent', 'no' ) ) {
            add_action( 'woocommerce_review_order_before_submit', [ $this, 'add_consent_checkbox' ] );
            add_action( 'woocommerce_checkout_process', [ $this, 'validate_consent_checkbox' ] );
        }

        // Data deletion request from unsubscribe.
        add_action( 'wp', [ $this, 'handle_data_deletion_request' ] );
    }

    /**
     * Add privacy policy suggested content.
     */
    public function add_privacy_policy_content() {
        if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
            return;
        }

        $content = $this->get_privacy_policy_content();
        wp_add_privacy_policy_content( 'Maple Carts', $content );
    }

    /**
     * Get privacy policy suggested content.
     *
     * @return string
     */
    private function get_privacy_policy_content() {
        $retention_days = Maple_Carts::get_option( 'delete_after_days', 90 );

        return sprintf(
            '<h2>%s</h2>
            <p>%s</p>
            <h3>%s</h3>
            <p>%s</p>
            <ul>
                <li>%s</li>
                <li>%s</li>
                <li>%s</li>
                <li>%s</li>
                <li>%s</li>
                <li>%s</li>
            </ul>
            <h3>%s</h3>
            <p>%s</p>
            <h3>%s</h3>
            <p>%s</p>
            <h3>%s</h3>
            <p>%s</p>
            <h3>%s</h3>
            <p>%s</p>',
            __( 'Abandoned Cart Recovery', 'maple-carts' ),
            __( 'We use abandoned cart recovery technology to help remind you about items left in your shopping cart. This section explains what data we collect and how we use it.', 'maple-carts' ),
            __( 'What data we collect', 'maple-carts' ),
            __( 'When you begin the checkout process, we may collect:', 'maple-carts' ),
            __( 'Email address', 'maple-carts' ),
            __( 'Name and phone number', 'maple-carts' ),
            __( 'Billing address', 'maple-carts' ),
            __( 'Cart contents and total', 'maple-carts' ),
            __( 'IP address', 'maple-carts' ),
            __( 'Browser information', 'maple-carts' ),
            __( 'Why we collect this data', 'maple-carts' ),
            __( 'We collect this data to send you reminder emails if you leave items in your cart without completing your purchase. These emails may include a discount code to encourage you to complete your order.', 'maple-carts' ),
            __( 'How long we retain your data', 'maple-carts' ),
            sprintf(
                /* translators: %d: number of days */
                __( 'Abandoned cart data is automatically deleted after %d days. You can request immediate deletion at any time.', 'maple-carts' ),
                $retention_days
            ),
            __( 'Your rights', 'maple-carts' ),
            __( 'You can unsubscribe from abandoned cart emails at any time by clicking the unsubscribe link in any email. You can also request a copy of your data or request deletion through our privacy tools.', 'maple-carts' ),
            __( 'Third-party sharing', 'maple-carts' ),
            __( 'We do not share your abandoned cart data with any third parties. Emails are sent through our own email system or your configured SMTP provider.', 'maple-carts' )
        );
    }

    /**
     * Register data exporter.
     *
     * @param array $exporters Existing exporters.
     * @return array
     */
    public function register_data_exporter( $exporters ) {
        $exporters['maple-carts'] = [
            'exporter_friendly_name' => __( 'Maple Carts Abandoned Cart Data', 'maple-carts' ),
            'callback'               => [ $this, 'export_personal_data' ],
        ];
        return $exporters;
    }

    /**
     * Register data eraser.
     *
     * @param array $erasers Existing erasers.
     * @return array
     */
    public function register_data_eraser( $erasers ) {
        $erasers['maple-carts'] = [
            'eraser_friendly_name' => __( 'Maple Carts Abandoned Cart Data', 'maple-carts' ),
            'callback'             => [ $this, 'erase_personal_data' ],
        ];
        return $erasers;
    }

    /**
     * Export personal data for a user.
     *
     * @param string $email_address Email address.
     * @param int    $page          Page number.
     * @return array
     */
    public function export_personal_data( $email_address, $page = 1 ) {
        global $wpdb;

        $export_items = [];
        $table        = $wpdb->prefix . MAPLE_CARTS_TABLE;
        $per_page     = 10;
        $offset       = ( $page - 1 ) * $per_page;

        $carts = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT * FROM {$table} WHERE email = %s LIMIT %d OFFSET %d",
                $email_address,
                $per_page,
                $offset
            )
        );

        foreach ( $carts as $cart ) {
            $cart_contents = maybe_unserialize( $cart->cart_contents );
            $product_names = [];
            
            if ( is_array( $cart_contents ) ) {
                foreach ( $cart_contents as $item ) {
                    $product_names[] = $item['name'] ?? 'Unknown Product';
                }
            }

            $data = [
                [
                    'name'  => __( 'Email', 'maple-carts' ),
                    'value' => $cart->email,
                ],
                [
                    'name'  => __( 'Name', 'maple-carts' ),
                    'value' => $cart->customer_name ?: __( 'Not provided', 'maple-carts' ),
                ],
                [
                    'name'  => __( 'Phone', 'maple-carts' ),
                    'value' => $cart->customer_phone ?: __( 'Not provided', 'maple-carts' ),
                ],
                [
                    'name'  => __( 'Cart Contents', 'maple-carts' ),
                    'value' => implode( ', ', $product_names ),
                ],
                [
                    'name'  => __( 'Cart Total', 'maple-carts' ),
                    'value' => wc_price( $cart->cart_total, [ 'currency' => $cart->currency ] ),
                ],
                [
                    'name'  => __( 'Status', 'maple-carts' ),
                    'value' => ucfirst( $cart->status ),
                ],
                [
                    'name'  => __( 'IP Address', 'maple-carts' ),
                    'value' => $cart->ip_address ?: __( 'Not recorded', 'maple-carts' ),
                ],
                [
                    'name'  => __( 'Created', 'maple-carts' ),
                    'value' => $cart->created_at,
                ],
                [
                    'name'  => __( 'Unsubscribed', 'maple-carts' ),
                    'value' => $cart->unsubscribed ? __( 'Yes', 'maple-carts' ) : __( 'No', 'maple-carts' ),
                ],
            ];

            // Add billing data if present.
            $billing_data = maybe_unserialize( $cart->billing_data );
            if ( ! empty( $billing_data ) ) {
                $address_parts = array_filter( [
                    $billing_data['address_1'] ?? '',
                    $billing_data['address_2'] ?? '',
                    $billing_data['city'] ?? '',
                    $billing_data['state'] ?? '',
                    $billing_data['postcode'] ?? '',
                    $billing_data['country'] ?? '',
                ] );

                if ( ! empty( $address_parts ) ) {
                    $data[] = [
                        'name'  => __( 'Billing Address', 'maple-carts' ),
                        'value' => implode( ', ', $address_parts ),
                    ];
                }
            }

            $export_items[] = [
                'group_id'          => 'maple-carts',
                'group_label'       => __( 'Abandoned Cart Data', 'maple-carts' ),
                'group_description' => __( 'Cart data collected during checkout.', 'maple-carts' ),
                'item_id'           => 'cart-' . $cart->id,
                'data'              => $data,
            ];
        }

        // Check if there are more records.
        $total = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM {$table} WHERE email = %s",
                $email_address
            )
        );

        $done = ( $page * $per_page ) >= $total;

        return [
            'data' => $export_items,
            'done' => $done,
        ];
    }

    /**
     * Erase personal data for a user.
     *
     * @param string $email_address Email address.
     * @param int    $page          Page number.
     * @return array
     */
    public function erase_personal_data( $email_address, $page = 1 ) {
        global $wpdb;

        $table      = $wpdb->prefix . MAPLE_CARTS_TABLE;
        $log_table  = $wpdb->prefix . MAPLE_CARTS_EMAIL_LOG_TABLE;
        $per_page   = 50;
        $items_removed  = 0;
        $items_retained = 0;

        // Get carts to delete.
        $carts = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT id FROM {$table} WHERE email = %s LIMIT %d",
                $email_address,
                $per_page
            )
        );

        foreach ( $carts as $cart ) {
            // Delete email logs first.
            $wpdb->delete( $log_table, [ 'cart_id' => $cart->id ] );
            
            // Delete cart.
            $deleted = $wpdb->delete( $table, [ 'id' => $cart->id ] );
            
            if ( $deleted ) {
                $items_removed++;
            } else {
                $items_retained++;
            }
        }

        // Check if there are more records.
        $remaining = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM {$table} WHERE email = %s",
                $email_address
            )
        );

        $done = ( $remaining == 0 );

        return [
            'items_removed'  => $items_removed,
            'items_retained' => $items_retained,
            'messages'       => [],
            'done'           => $done,
        ];
    }

    /**
     * Add consent checkbox to checkout.
     */
    public function add_consent_checkbox() {
        $consent_text = Maple_Carts::get_option( 
            'consent_text', 
            __( 'I agree to receive cart reminder emails if I don\'t complete my purchase.', 'maple-carts' )
        );

        woocommerce_form_field(
            'maple_carts_consent',
            [
                'type'     => 'checkbox',
                'class'    => [ 'form-row maple-carts-consent' ],
                'label'    => esc_html( $consent_text ),
                'required' => false,
            ]
        );
    }

    /**
     * Validate consent checkbox.
     */
    public function validate_consent_checkbox() {
        // If consent is required and not given, we don't track the cart.
        // This is handled in the tracking class.
    }

    /**
     * Check if user has given consent.
     *
     * @return bool
     */
    public static function has_consent() {
        // If consent is not required, always return true.
        if ( 'yes' !== Maple_Carts::get_option( 'require_consent', 'no' ) ) {
            return true;
        }

        // Check if consent checkbox was checked.
        if ( isset( $_POST['maple_carts_consent'] ) ) {
            return true;
        }

        // Check session for previous consent.
        if ( WC()->session && WC()->session->get( 'maple_carts_consent' ) ) {
            return true;
        }

        return false;
    }

    /**
     * Record consent.
     */
    public static function record_consent() {
        if ( WC()->session ) {
            WC()->session->set( 'maple_carts_consent', true );
            WC()->session->set( 'maple_carts_consent_time', current_time( 'mysql' ) );
        }
    }

    /**
     * Handle data deletion request from unsubscribe page.
     */
    public function handle_data_deletion_request() {
        if ( ! isset( $_GET['maple_delete_data'] ) ) {
            return;
        }

        $token = sanitize_text_field( wp_unslash( $_GET['maple_delete_data'] ) );
        
        // Verify signed token (same as unsubscribe).
        $tracking = Maple_Carts_Tracking::instance();
        $data     = $this->verify_deletion_token( $token );

        if ( ! $data || empty( $data['sid'] ) ) {
            wc_add_notice( __( 'This data deletion link has expired or is invalid.', 'maple-carts' ), 'error' );
            wp_safe_redirect( wc_get_page_permalink( 'shop' ) );
            exit;
        }

        $session_id = sanitize_text_field( $data['sid'] );
        $cart       = Maple_Carts_DB::get_cart_by_session( $session_id );

        if ( $cart ) {
            // Delete all data for this cart.
            Maple_Carts_DB::delete_cart( $cart->id );

            wc_add_notice( __( 'Your cart data has been permanently deleted.', 'maple-carts' ), 'success' );
        }

        wp_safe_redirect( wc_get_page_permalink( 'shop' ) );
        exit;
    }

    /**
     * Verify deletion token (reuses tracking token verification).
     *
     * @param string $token Token to verify.
     * @return array|false
     */
    private function verify_deletion_token( $token ) {
        $decoded = base64_decode( $token, true );
        if ( ! $decoded || strpos( $decoded, '|' ) === false ) {
            return false;
        }

        $parts = explode( '|', $decoded, 2 );
        if ( count( $parts ) !== 2 ) {
            return false;
        }

        list( $payload, $signature ) = $parts;
        
        // Verify HMAC signature.
        $secret             = wp_salt( 'auth' ) . 'maple_carts';
        $expected_signature = hash_hmac( 'sha256', $payload, $secret );
        
        if ( ! hash_equals( $expected_signature, $signature ) ) {
            return false;
        }

        $data = json_decode( $payload, true );
        if ( ! $data ) {
            return false;
        }

        // Token valid for 90 days.
        if ( isset( $data['t'] ) && ( time() - $data['t'] ) > ( 90 * DAY_IN_SECONDS ) ) {
            return false;
        }

        return $data;
    }

    /**
     * Generate data deletion URL.
     *
     * @param string $session_id Session ID.
     * @return string
     */
    public static function generate_deletion_url( $session_id ) {
        $data = [
            'sid' => $session_id,
            't'   => time(),
        ];
        
        $payload   = wp_json_encode( $data );
        $secret    = wp_salt( 'auth' ) . 'maple_carts';
        $signature = hash_hmac( 'sha256', $payload, $secret );
        $token     = base64_encode( $payload . '|' . $signature );

        return add_query_arg( 'maple_delete_data', $token, home_url() );
    }

    /**
     * Get anonymized data (for when full deletion isn't required).
     *
     * @param int $cart_id Cart ID.
     */
    public static function anonymize_cart( $cart_id ) {
        global $wpdb;
        $table = $wpdb->prefix . MAPLE_CARTS_TABLE;

        $wpdb->update(
            $table,
            [
                'email'          => 'deleted@anonymized.invalid',
                'customer_name'  => 'Anonymized',
                'customer_phone' => null,
                'billing_data'   => null,
                'ip_address'     => '0.0.0.0',
                'user_agent'     => null,
            ],
            [ 'id' => $cart_id ]
        );
    }
}
