<?php
/**
 * HVAC Test User Factory
 *
 * Provides functionality for creating test users with specific roles and personas
 * for the HVAC Events testing framework.
 *
 * @package HVAC_Events_Tests
 */

class HVAC_Test_User_Factory {
    /**
     * @var array Stored test users for cleanup
     */
    private $created_users = [];

    /**
     * @var array Predefined personas with their roles and attributes
     */
    private $personas = [
        'basic_trainer' => [
            'roles' => ['hvac_trainer'],
            'capabilities' => [],
            'meta' => [
                'company_name' => 'Test HVAC Training Co.',
                'phone' => '555-0123',
                'website' => 'https://example.com'
            ]
        ],
        'advanced_trainer' => [
            'roles' => ['hvac_trainer', 'community_events_maker'],
            'capabilities' => ['publish_community_events', 'edit_community_events'],
            'meta' => [
                'company_name' => 'Advanced HVAC Solutions',
                'phone' => '555-0124',
                'website' => 'https://advanced-example.com'
            ]
        ],
        'admin_trainer' => [
            'roles' => ['hvac_trainer', 'administrator'],
            'capabilities' => [],
            'meta' => [
                'company_name' => 'Admin HVAC Training',
                'phone' => '555-0125',
                'website' => 'https://admin-example.com'
            ]
        ]
    ];

    /**
     * Creates a new user with specified roles
     *
     * @param string $username The username
     * @param array  $roles    Array of role slugs to assign
     * @param array  $meta     Optional user meta data
     * @return int|WP_Error The user ID or WP_Error on failure
     */
    public function create_user($username, $roles = [], $meta = []) {
        $user_data = [
            'user_login' => $username,
            'user_pass'  => wp_generate_password(),
            'user_email' => $username . '@example.com',
            'role'       => empty($roles) ? 'subscriber' : array_shift($roles)
        ];

        $user_id = wp_insert_user($user_data);

        if (is_wp_error($user_id)) {
            return $user_id;
        }

        // Add additional roles
        $user = new WP_User($user_id);
        foreach ($roles as $role) {
            $user->add_role($role);
        }

        // Add meta data
        foreach ($meta as $key => $value) {
            update_user_meta($user_id, $key, $value);
        }

        $this->created_users[] = $user_id;
        return $user_id;
    }

    /**
     * Creates a user with a predefined persona
     *
     * @param string $username The username
     * @param string $persona  The persona key
     * @return int|WP_Error The user ID or WP_Error on failure
     */
    public function create_user_with_persona($username, $persona) {
        if (!isset($this->personas[$persona])) {
            return new WP_Error(
                'invalid_persona',
                sprintf('Invalid persona: %s', $persona)
            );
        }

        $persona_data = $this->personas[$persona];
        $user_id = $this->create_user(
            $username,
            $persona_data['roles'],
            $persona_data['meta']
        );

        if (is_wp_error($user_id)) {
            return $user_id;
        }

        // Add any additional capabilities
        if (!empty($persona_data['capabilities'])) {
            $user = new WP_User($user_id);
            foreach ($persona_data['capabilities'] as $cap) {
                $user->add_cap($cap);
            }
        }

        return $user_id;
    }

    /**
     * Validates if a user has all required roles
     *
     * @param int   $user_id The user ID
     * @param array $roles   Array of role slugs to verify
     * @return bool True if user has all roles, false otherwise
     */
    public function validate_user_roles($user_id, $roles) {
        $user = new WP_User($user_id);
        foreach ($roles as $role) {
            if (!in_array($role, (array) $user->roles)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Cleans up all users created by this factory
     */
    public function cleanup() {
        foreach ($this->created_users as $user_id) {
            wp_delete_user($user_id, true);
        }
        $this->created_users = [];
    }

    /**
     * Gets all available persona keys
     *
     * @return array Array of persona keys
     */
    public function get_available_personas() {
        return array_keys($this->personas);
    }

    /**
     * Gets persona configuration
     *
     * @param string $persona The persona key
     * @return array|null The persona configuration or null if not found
     */
    public function get_persona_config($persona) {
        return isset($this->personas[$persona]) ? $this->personas[$persona] : null;
    }

    /**
     * Adds a new custom persona
     *
     * @param string $key    The persona key
     * @param array  $config The persona configuration
     * @return bool True if added successfully, false if key already exists
     */
    public function add_persona($key, $config) {
        if (isset($this->personas[$key])) {
            return false;
        }

        $this->personas[$key] = $config;
        return true;
    }
}