<?php

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

class BS2FA_Privacy {
    protected static $registered = false;

    public static function register_hooks() {
        if (self::$registered) {
            return;
        }

        self::$registered = true;
        add_action('admin_init', [__CLASS__, 'add_privacy_policy_content']);
        add_filter('wp_privacy_personal_data_exporters', [__CLASS__, 'register_exporter']);
        add_filter('wp_privacy_personal_data_erasers', [__CLASS__, 'register_eraser']);
    }

    public static function add_privacy_policy_content() {
        if (!function_exists('wp_add_privacy_policy_content')) {
            return;
        }

        $content = '<p class="privacy-policy-tutorial">'
            . esc_html__('Suggested text for your site privacy policy when Brightery Secure 2FA is active.', 'brightery-secure-2fa')
            . '</p>'
            . '<strong class="privacy-policy-tutorial">'
            . esc_html__('Suggested text:', 'brightery-secure-2fa')
            . '</strong> '
            . esc_html__('When you sign in, this site may store account security data provided by Brightery Secure 2FA. That can include whether two-factor authentication is enabled, trusted-device records, passkey metadata, remaining backup-code count, security-event logs, and a limited recent login-context history based on local request data such as masked IP/network, country header, time, and browser user agent. Authenticator secrets are stored encrypted, backup codes are stored hashed, and passkey secrets are not stored in recoverable form. This information is used only to protect accounts, detect suspicious access, enforce required security policies, and help administrators audit account-security events.', 'brightery-secure-2fa');

        wp_add_privacy_policy_content(__('Brightery Secure 2FA', 'brightery-secure-2fa'), wp_kses_post(wpautop($content, false)));
    }

    public static function register_exporter($exporters) {
        $exporters['brightery-secure-2fa'] = [
            'exporter_friendly_name' => __('Brightery Secure 2FA', 'brightery-secure-2fa'),
            'callback'               => [__CLASS__, 'export_personal_data'],
        ];

        return $exporters;
    }

    public static function register_eraser($erasers) {
        $erasers['brightery-secure-2fa'] = [
            'eraser_friendly_name' => __('Brightery Secure 2FA', 'brightery-secure-2fa'),
            'callback'             => [__CLASS__, 'erase_personal_data'],
        ];

        return $erasers;
    }

    protected static function get_user_by_email($email_address) {
        $email_address = sanitize_email($email_address);
        if ($email_address === '') {
            return null;
        }

        $user = get_user_by('email', $email_address);
        return $user instanceof WP_User ? $user : null;
    }

    protected static function export_items_for_user(WP_User $user) {
        $user_id = (int) $user->ID;
        $items = [];
        $group_id = 'bs2fa-security';
        $group_label = __('Brightery Secure 2FA', 'brightery-secure-2fa');

        $summary_data = [
            [
                'name'  => __('WordPress user ID', 'brightery-secure-2fa'),
                'value' => (string) $user_id,
            ],
            [
                'name'  => __('Required by security policy', 'brightery-secure-2fa'),
                'value' => BS2FA_Helpers::user_has_required_role($user) ? __('Yes', 'brightery-secure-2fa') : __('No', 'brightery-secure-2fa'),
            ],
            [
                'name'  => __('Authenticator app enabled', 'brightery-secure-2fa'),
                'value' => BS2FA_Helpers::user_has_totp($user_id) ? __('Yes', 'brightery-secure-2fa') : __('No', 'brightery-secure-2fa'),
            ],
            [
                'name'  => __('Passkey count', 'brightery-secure-2fa'),
                'value' => (string) count(BS2FA_WebAuthn::get_credentials($user_id)),
            ],
            [
                'name'  => __('Trusted device count', 'brightery-secure-2fa'),
                'value' => (string) count(BS2FA_Trusted_Devices::get_devices($user_id)),
            ],
            [
                'name'  => __('Remaining backup code count', 'brightery-secure-2fa'),
                'value' => (string) BS2FA_Helpers::backup_codes_left($user_id),
            ],
        ];

        $items[] = [
            'group_id'    => $group_id,
            'group_label' => $group_label,
            'item_id'     => 'bs2fa-summary-' . $user_id,
            'data'        => $summary_data,
        ];

        foreach (BS2FA_Trusted_Devices::get_devices($user_id) as $index => $device) {
            $items[] = [
                'group_id'    => $group_id,
                'group_label' => $group_label,
                'item_id'     => 'bs2fa-trusted-device-' . $user_id . '-' . $index,
                'data'        => [
                    [
                        'name'  => __('Trusted device label', 'brightery-secure-2fa'),
                        'value' => (string) ($device['label'] ?? ''),
                    ],
                    [
                        'name'  => __('Added', 'brightery-secure-2fa'),
                        'value' => BS2FA_Helpers::format_time((int) ($device['added_at'] ?? 0)),
                    ],
                    [
                        'name'  => __('Last used', 'brightery-secure-2fa'),
                        'value' => BS2FA_Helpers::format_time((int) ($device['last_used_at'] ?? 0)),
                    ],
                    [
                        'name'  => __('Expires', 'brightery-secure-2fa'),
                        'value' => BS2FA_Helpers::format_time((int) ($device['expires_at'] ?? 0)),
                    ],
                    [
                        'name'  => __('Masked browser fingerprint', 'brightery-secure-2fa'),
                        'value' => !empty($device['ua_hash']) ? (string) $device['ua_hash'] : __('Unavailable', 'brightery-secure-2fa'),
                    ],
                ],
            ];
        }

        foreach (BS2FA_WebAuthn::get_credentials($user_id) as $index => $credential) {
            $items[] = [
                'group_id'    => $group_id,
                'group_label' => $group_label,
                'item_id'     => 'bs2fa-passkey-' . $user_id . '-' . $index,
                'data'        => [
                    [
                        'name'  => __('Passkey label', 'brightery-secure-2fa'),
                        'value' => (string) ($credential['label'] ?? ''),
                    ],
                    [
                        'name'  => __('Credential ID', 'brightery-secure-2fa'),
                        'value' => (string) ($credential['id'] ?? ''),
                    ],
                    [
                        'name'  => __('Added', 'brightery-secure-2fa'),
                        'value' => BS2FA_Helpers::format_time((int) ($credential['added_at'] ?? 0)),
                    ],
                    [
                        'name'  => __('Last used', 'brightery-secure-2fa'),
                        'value' => BS2FA_Helpers::format_time((int) ($credential['last_used_at'] ?? 0)),
                    ],
                    [
                        'name'  => __('Signature counter', 'brightery-secure-2fa'),
                        'value' => (string) (int) ($credential['sign_count'] ?? 0),
                    ],
                ],
            ];
        }

        foreach (BS2FA_Helpers::get_login_contexts($user_id) as $index => $context) {
            $items[] = [
                'group_id'    => $group_id,
                'group_label' => $group_label,
                'item_id'     => 'bs2fa-login-context-' . $user_id . '-' . $index,
                'data'        => [
                    [
                        'name'  => __('Recorded', 'brightery-secure-2fa'),
                        'value' => BS2FA_Helpers::format_time((int) ($context['time'] ?? 0)),
                    ],
                    [
                        'name'  => __('Masked IP', 'brightery-secure-2fa'),
                        'value' => (string) ($context['masked_ip'] ?? ''),
                    ],
                    [
                        'name'  => __('Network bucket', 'brightery-secure-2fa'),
                        'value' => (string) ($context['network'] ?? ''),
                    ],
                    [
                        'name'  => __('Country header', 'brightery-secure-2fa'),
                        'value' => (string) ($context['country'] ?? ''),
                    ],
                    [
                        'name'  => __('User agent', 'brightery-secure-2fa'),
                        'value' => (string) ($context['user_agent'] ?? ''),
                    ],
                ],
            ];
        }

        $logs = BS2FA_Logger::get_logs([
            'limit' => max(1, BS2FA_Logger::count_logs([])),
            'offset' => 0,
        ]);
        foreach ($logs as $index => $log) {
            if ((int) ($log['user_id'] ?? 0) !== $user_id && (string) ($log['username'] ?? '') !== (string) $user->user_login) {
                continue;
            }

            $items[] = [
                'group_id'    => $group_id,
                'group_label' => $group_label,
                'item_id'     => 'bs2fa-log-' . $user_id . '-' . $index,
                'data'        => [
                    [
                        'name'  => __('Time', 'brightery-secure-2fa'),
                        'value' => BS2FA_Helpers::format_time((int) ($log['time'] ?? 0)),
                    ],
                    [
                        'name'  => __('Level', 'brightery-secure-2fa'),
                        'value' => (string) ($log['level'] ?? ''),
                    ],
                    [
                        'name'  => __('Event', 'brightery-secure-2fa'),
                        'value' => (string) ($log['event'] ?? ''),
                    ],
                    [
                        'name'  => __('IP', 'brightery-secure-2fa'),
                        'value' => (string) ($log['ip'] ?? ''),
                    ],
                    [
                        'name'  => __('Details', 'brightery-secure-2fa'),
                        'value' => (string) ($log['details'] ?? ''),
                    ],
                ],
            ];
        }

        return $items;
    }

    public static function export_personal_data($email_address, $page = 1) {
        $user = self::get_user_by_email($email_address);
        if (!$user) {
            return [
                'data' => [],
                'done' => true,
            ];
        }

        $items = self::export_items_for_user($user);
        $page = max(1, (int) $page);
        $per_page = 25;
        $offset = ($page - 1) * $per_page;
        $data = array_slice($items, $offset, $per_page);

        return [
            'data' => $data,
            'done' => ($offset + $per_page) >= count($items),
        ];
    }

    public static function erase_personal_data($email_address, $page = 1) {
        $user = self::get_user_by_email($email_address);
        if (!$user) {
            return [
                'items_removed'  => false,
                'items_retained' => false,
                'messages'       => [],
                'done'           => true,
            ];
        }

        $user_id = (int) $user->ID;
        $removed = false;
        $retained = false;
        $messages = [];

        foreach ([
            'bs2fa_totp_secret',
            'bs2fa_pending_totp_secret',
            'bs2fa_backup_codes',
            'bs2fa_webauthn_credentials',
            'bs2fa_webauthn_register_challenge',
            'bs2fa_webauthn_register_challenge_time',
            'bs2fa_enrollment_started_at',
            'bs2fa_trusted_devices',
            'bs2fa_login_contexts',
        ] as $meta_key) {
            if (delete_user_meta($user_id, $meta_key)) {
                $removed = true;
            }
        }

        $logs = get_option('bs2fa_logs', []);
        if (is_array($logs) && !empty($logs)) {
            $changed = false;
            foreach ($logs as $index => $log) {
                $matches_user_id = (int) ($log['user_id'] ?? 0) === $user_id;
                $matches_username = !empty($log['username']) && (string) $log['username'] === (string) $user->user_login;
                if (!$matches_user_id && !$matches_username) {
                    continue;
                }

                $logs[$index]['user_id'] = 0;
                $logs[$index]['username'] = '';
                $logs[$index]['ip'] = '';
                $logs[$index]['details'] = __('Personal data erased by privacy request.', 'brightery-secure-2fa');
                $changed = true;
            }

            if ($changed) {
                update_option('bs2fa_logs', $logs, false);
                $removed = true;
            }
        }

        if (is_user_logged_in() && (int) get_current_user_id() === $user_id) {
            BS2FA_Trusted_Devices::clear_cookie();
            BS2FA_Helpers::clear_cookie('bs2fa_backup_codes_flash');
        }

        $messages[] = __('Brightery Secure 2FA erased stored account-security metadata and anonymized matching security logs for this user.', 'brightery-secure-2fa');

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