<?php
/**
 * WordPress privacy exporter and eraser integration.
 */
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class YATOON_Privacy {
    public static function init() {
        add_filter( 'wp_privacy_personal_data_exporters', array( __CLASS__, 'register_exporter' ) );
        add_filter( 'wp_privacy_personal_data_erasers', array( __CLASS__, 'register_eraser' ) );
    }

    public static function register_exporter( $exporters ) {
        $exporters['yatoon-booking-system'] = array(
            'exporter_friendly_name' => __( 'Yatoon Booking data', 'yatoon-booking-system' ),
            'callback'               => array( __CLASS__, 'export_personal_data' ),
        );
        return $exporters;
    }

    public static function register_eraser( $erasers ) {
        $erasers['yatoon-booking-system'] = array(
            'eraser_friendly_name' => __( 'Yatoon Booking data', 'yatoon-booking-system' ),
            'callback'             => array( __CLASS__, 'erase_personal_data' ),
        );
        return $erasers;
    }

    public static function export_personal_data( $email_address, $page = 1 ) {
        global $wpdb;
        $email    = sanitize_email( $email_address );
        $page     = max( 1, absint( $page ) );
        $per_page = 100;
        $offset   = ( $page - 1 ) * $per_page;
        $data     = array();
        if ( ! $email ) {
            return array( 'data' => array(), 'done' => true );
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- GDPR export runs once per manually-approved request and must always read live data; caching personal data by e-mail here would be a privacy anti-pattern.
        $bookings = $wpdb->get_results( $wpdb->prepare(
            "SELECT id, customer_name, customer_email, customer_phone, start_time, end_time, status, total_price, payment_status, notes, created_at
             FROM {$wpdb->prefix}yatoon_bookings
             WHERE customer_email = %s
             ORDER BY id ASC
             LIMIT %d OFFSET %d",
            $email,
            $per_page,
            $offset
        ), ARRAY_A );

        foreach ( (array) $bookings as $booking ) {
            $item_data = array();
            foreach ( $booking as $key => $value ) {
                $item_data[] = array(
                    'name'  => ucwords( str_replace( '_', ' ', $key ) ),
                    'value' => (string) $value,
                );
            }
            $data[] = array(
                'group_id'    => 'yatoon-bookings',
                'group_label' => __( 'Yatoon bookings', 'yatoon-booking-system' ),
                'item_id'     => 'booking-' . absint( $booking['id'] ),
                'data'        => $item_data,
            );
        }

        if ( 1 === $page ) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Same as above: GDPR export must reflect live data, not a cached copy.
            $client = $wpdb->get_row( $wpdb->prepare(
                "SELECT id, customer_name, customer_email, customer_phone, allergies, preferences, notes, tags, created_at, updated_at
                 FROM {$wpdb->prefix}yatoon_clients
                 WHERE customer_email = %s
                 ORDER BY updated_at DESC
                 LIMIT 1",
                $email
            ), ARRAY_A );
            if ( $client ) {
                $client_data = array();
                foreach ( $client as $key => $value ) {
                    $client_data[] = array(
                        'name'  => ucwords( str_replace( '_', ' ', $key ) ),
                        'value' => (string) $value,
                    );
                }
                $data[] = array(
                    'group_id'    => 'yatoon-client-profile',
                    'group_label' => __( 'Yatoon client profile', 'yatoon-booking-system' ),
                    'item_id'     => 'client-' . absint( $client['id'] ),
                    'data'        => $client_data,
                );
            }
        }

        return array(
            'data' => $data,
            'done' => count( $bookings ) < $per_page,
        );
    }

    public static function erase_personal_data( $email_address, $page = 1 ) {
        global $wpdb;
        $email = sanitize_email( $email_address );
        if ( ! $email ) {
            return array(
                'items_removed'  => false,
                'items_retained' => false,
                'messages'       => array( __( 'A valid email address is required.', 'yatoon-booking-system' ) ),
                'done'           => true,
            );
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- GDPR erasure must act on the current live rows; a stale cached list of attachment IDs could leave personal files undeleted.
        $attachment_ids = $wpdb->get_col( $wpdb->prepare(
            "SELECT design_attachment_id FROM {$wpdb->prefix}yatoon_bookings
             WHERE customer_email = %s AND design_attachment_id IS NOT NULL",
            $email
        ) );
        foreach ( array_map( 'absint', (array) $attachment_ids ) as $attachment_id ) {
            if ( $attachment_id ) {
                wp_delete_attachment( $attachment_id, true );
            }
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Write query for GDPR erasure; caching does not apply to an UPDATE, and this must never be served from a stale cache.
        $updated = $wpdb->query( $wpdb->prepare(
            "UPDATE {$wpdb->prefix}yatoon_bookings
             SET customer_name = %s, customer_email = '', customer_phone = '', notes = '',
                 design_attachment_id = NULL, design_image_url = NULL, design_upload_token = NULL
             WHERE customer_email = %s",
            __( 'Removed customer', 'yatoon-booking-system' ),
            $email
        ) );
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- $wpdb->delete() is the documented WordPress API for row deletion; caching is not applicable to a delete operation.
        $deleted = $wpdb->delete(
            $wpdb->prefix . 'yatoon_clients',
            array( 'customer_email' => $email ),
            array( '%s' )
        );

        return array(
            'items_removed'  => (bool) ( $updated || $deleted || $attachment_ids ),
            'items_retained' => (bool) $updated,
            'messages'       => $updated
                ? array( __( 'Personal details were removed. Anonymous appointment and financial records were retained for business reporting.', 'yatoon-booking-system' ) )
                : array(),
            'done'           => true,
        );
    }
}
