<?php

/**
 * Create User Session Command
 *
 * @package _121Digital\Connect
 */

namespace _121Digital\Connect\Commands\Users;

use _121Digital\Connect\Commands\CommandBase;

/**
 * Command to create an authentication session with a one-time access code.
 */
class CreateSession extends CommandBase
{
    /**
     * Execute the command to create an authentication session.
     *
     * @return array An associative array with the result of the command execution.
     */
    public function execute(): array
    {
        $username = $this->getArg('username');

        if (empty($username)) {
            return $this->error('Username is required.');
        }

        if (!username_exists($username)) {
            return $this->error('User does not exist.');
        }

        $accessCode = $this->generateAccessCode(25);
        $sessionCode = $this->generatePendingSessionCode();

        update_option('sc_login_' . $sessionCode . '_token', $accessCode);
        update_option('sc_login_' . $sessionCode . '_username', $username);

        return $this->success('Access code generated successfully.', [
            'username' => $username,
            'access_code' => $accessCode,
            'session_code' => $sessionCode,
        ]);
    }

    /**
     * Generate a one-time use access code.
     *
     * @param int $length The length of the access code.
     * @return string The generated access code.
     */
    private function generateAccessCode(int $length): string
    {
        $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $charactersLength = strlen($characters);
        $accessCode = '';

        for ($i = 0; $i < $length; $i++) {
            $index = random_int(0, $charactersLength - 1);
            $accessCode .= $characters[$index];
        }

        return $accessCode;
    }

    /**
     * Generate a pending session code.
     *
     * @param int $length The length of the session code.
     * @return string The generated session code.
     */
    private function generatePendingSessionCode(int $length = 4): string
    {
        $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $charactersLength = strlen($characters);
        $sessionCode = '';

        for ($i = 0; $i < $length; $i++) {
            $index = random_int(0, $charactersLength - 1);
            $sessionCode .= $characters[$index];
        }

        return $sessionCode;
    }
}
