<?php
namespace WPUltimateSecurity\UltimateSecurity\Presentation\API\Controllers;

use WP_REST_Response;
use WP_REST_Request;
use WPUltimateSecurity\UltimateSecurity\Modules\Authentication\TwoFactor\Services\TrustedDeviceService;
use WPUltimateSecurity\UltimateSecurity\Support\Exceptions\ValidationException;
use WPUltimateSecurity\UltimateSecurity\Support\Exceptions\AuthenticationException;

/**
 * Trusted Devices REST API Controller
 *
 * Handles REST API endpoints for managing trusted devices
 */
class TrustedDevicesController
{
    /**
     * Get list of trusted devices for the current user
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function get_user_devices(WP_REST_Request $request)
    {
        try {
            $user_id = get_current_user_id();

            if (!$user_id) {
                throw AuthenticationException::sessionExpired();
            }

            $devices = TrustedDeviceService::get_user_devices($user_id);
            $formatted_devices = self::format_devices_for_response($devices);

            return new WP_REST_Response([
                'success' => true,
                'data' => [
                    'devices' => $formatted_devices,
                    'total' => count($formatted_devices),
                    'settings' => TrustedDeviceService::get_settings(),
                ],
            ], 200);
        } catch (AuthenticationException $e) {
            return $e->toRestResponse();
        }
    }

    /**
     * Get all trusted devices (admin view)
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function get_all_devices(WP_REST_Request $request)
    {
        $args = [
            'page' => $request->get_param('page') ?? 1,
            'per_page' => $request->get_param('per_page') ?? 20,
            'orderby' => $request->get_param('orderby') ?? 'created_at',
            'order' => $request->get_param('order') ?? 'DESC',
            'user_id' => $request->get_param('user_id') ?? null,
            'include_revoked' => $request->get_param('include_revoked') === 'true',
            'include_expired' => $request->get_param('include_expired') === 'true',
        ];

        $result = TrustedDeviceService::get_all_devices($args);
        $formatted_devices = self::format_devices_for_response($result['devices'], true);

        return new WP_REST_Response([
            'success' => true,
            'data' => [
                'devices' => $formatted_devices,
                'total' => $result['total'],
                'pages' => $result['pages'],
                'current_page' => (int) $args['page'],
            ],
        ], 200);
    }

    /**
     * Get trusted devices statistics
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function get_statistics(WP_REST_Request $request)
    {
        $stats = TrustedDeviceService::get_statistics();
        $settings = TrustedDeviceService::get_settings();

        return new WP_REST_Response([
            'success' => true,
            'data' => [
                'statistics' => $stats,
                'settings' => $settings,
                'is_enabled' => TrustedDeviceService::is_enabled(),
            ],
        ], 200);
    }

    /**
     * Revoke a trusted device for current user
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function revoke_device(WP_REST_Request $request)
    {
        try {
            $user_id = get_current_user_id();
            $device_id = $request->get_param('id');

            if (!$user_id) {
                throw AuthenticationException::sessionExpired();
            }

            if (!$device_id) {
                throw ValidationException::required('id');
            }

            // Allow admins to revoke any device
            $owner_id = current_user_can('manage_options') ? null : $user_id;

            $result = TrustedDeviceService::revoke_device($device_id, $owner_id);

            if ($result) {
                return new WP_REST_Response([
                    'success' => true,
                    'message' => __('Device revoked successfully.', 'ultimate-security'),
                ], 200);
            }

            throw AuthenticationException::permissionDenied('revoke_device', $user_id);
        } catch (AuthenticationException $e) {
            return $e->toRestResponse();
        } catch (ValidationException $e) {
            return $e->toRestResponse();
        }
    }

    /**
     * Revoke all devices for current user
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function revoke_all_devices(WP_REST_Request $request)
    {
        try {
            $user_id = get_current_user_id();
            $target_user_id = $request->get_param('user_id');

            if (!$user_id) {
                throw AuthenticationException::sessionExpired();
            }

            // If target_user_id is specified, check admin permissions
            if ($target_user_id && $target_user_id != $user_id) {
                if (!current_user_can('manage_options')) {
                    throw AuthenticationException::permissionDenied('manage_options', $user_id);
                }
                $user_id = $target_user_id;
            }

            $count = TrustedDeviceService::revoke_all_user_devices($user_id);

            // Clear the cookie for the current user
            if ($user_id == get_current_user_id()) {
                TrustedDeviceService::clear_device_cookie();
            }

            return new WP_REST_Response([
                'success' => true,
                'message' => sprintf(
                    /* translators: %d: Number of devices revoked */
                    __('%d device(s) revoked successfully.', 'ultimate-security'),
                    $count
                ),
                'count' => $count,
            ], 200);
        } catch (AuthenticationException $e) {
            return $e->toRestResponse();
        }
    }

    /**
     * Delete a trusted device permanently (admin only)
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function delete_device(WP_REST_Request $request)
    {
        try {
            $device_id = $request->get_param('id');

            if (!$device_id) {
                throw ValidationException::required('id');
            }

            $result = TrustedDeviceService::delete_device($device_id);

            if ($result) {
                return new WP_REST_Response([
                    'success' => true,
                    'message' => __('Device deleted successfully.', 'ultimate-security'),
                ], 200);
            }

            return new WP_REST_Response([
                'success' => false,
                'error_message' => __('Failed to delete device.', 'ultimate-security'),
            ], 400);
        } catch (ValidationException $e) {
            return $e->toRestResponse();
        }
    }

    /**
     * Cleanup expired devices (admin only)
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function cleanup_devices(WP_REST_Request $request)
    {
        $days_old = $request->get_param('days_old') ?? 30;
        $count = TrustedDeviceService::cleanup_expired_devices($days_old);

        return new WP_REST_Response([
            'success' => true,
            'message' => sprintf(
                /* translators: %d: Number of devices cleaned up */
                __('%d expired/revoked device(s) cleaned up.', 'ultimate-security'),
                $count
            ),
            'count' => $count,
        ], 200);
    }

    /**
     * Get trusted devices settings
     *
     * @param WP_REST_Request $request Request object
     * @return WP_REST_Response
     */
    public static function get_settings(WP_REST_Request $request)
    {
        $settings = TrustedDeviceService::get_settings();
        $stats = TrustedDeviceService::get_statistics();

        return new WP_REST_Response([
            'success' => true,
            'data' => [
                'settings' => $settings,
                'statistics' => $stats,
            ],
        ], 200);
    }

    /**
     * Format devices for API response
     *
     * @param array $devices List of devices
     * @param bool $include_user_info Include user information
     * @return array Formatted devices
     */
    private static function format_devices_for_response($devices, $include_user_info = false)
    {
        $formatted = [];

        foreach ($devices as $device) {
            $item = [
                'id' => (int) $device->id,
                'device_name' => $device->device_name,
                'browser' => $device->browser,
                'browser_version' => $device->browser_version,
                'os' => $device->os,
                'os_version' => $device->os_version,
                'device_type' => $device->device_type,
                'ip_address' => $device->ip_address,
                'location' => $device->location,
                'last_used_at' => $device->last_used_at,
                'last_used_at_formatted' => $device->last_used_at
                    ? wp_date(get_option('date_format') . ' ' . get_option('time_format'), strtotime($device->last_used_at))
                    : __('Never', 'ultimate-security'),
                'expires_at' => $device->expires_at,
                'expires_at_formatted' => wp_date(get_option('date_format') . ' ' . get_option('time_format'), strtotime($device->expires_at)),
                'is_expired' => strtotime($device->expires_at) < time(),
                'is_revoked' => (bool) $device->is_revoked,
                'created_at' => $device->created_at,
                'created_at_formatted' => wp_date(get_option('date_format') . ' ' . get_option('time_format'), strtotime($device->created_at)),
                'status' => self::get_device_status($device),
            ];

            if ($include_user_info && isset($device->user_login)) {
                $item['user'] = [
                    'id' => (int) $device->user_id,
                    'login' => $device->user_login,
                    'email' => $device->user_email,
                    'display_name' => $device->display_name,
                ];
            }

            $formatted[] = $item;
        }

        return $formatted;
    }

    /**
     * Get device status label
     *
     * @param object $device Device object
     * @return string Status label
     */
    private static function get_device_status($device)
    {
        if ($device->is_revoked) {
            return 'revoked';
        }

        if (strtotime($device->expires_at) < time()) {
            return 'expired';
        }

        return 'active';
    }
}
