<?php

namespace modules\shelly\helpers;

use classes\shelly;
use Exception;

/**
 * @class shelly_device_switch
 * @description
 * @docs https://shelly-api-docs.shelly.cloud/cloud-control-api/communication-v2#control-a-switch
 */
class shelly_device_switch extends shelly_device_state
{
    /** @var callable|null */
    private $request_sender = null;

    /**
     * @var boolean $on
     * @description The output state
     * @values true | false
     */
    public bool $on;
    /**
     * @var int $channel
     * @description The channel number
     * @values 0 | 1 | 2 | 3
     * @default 0
     */
    public int $channel = 0;
    /**
     * @var int $toggle_after
     * @description After how many seconds, the state should be set to opposite the value of "on"
     * @values 1
     */
    public int $toggle_after = 1;

    /**
     * Send a request to the shelly API to switch the output
     * @param bool $on
     * @param bool|null $skip_toggle_after Whether to prevent the toggle_after parameter from being sent (if null, will use the value of $this->toggle_after)
     * @return array|object|null
     * @throws Exception
     */
    public function switch(bool $on, ?bool $skip_toggle_after = false): array|object|null
    {
        $parameters = [
            'id' => (string)$this->id,
            'channel' => (int)$this->channel,
            'on' => $on,
            ...($skip_toggle_after ? [] : ['toggle_after' => (int)$this->toggle_after]),
        ];
        return $this->sendShellySwitchRequest($parameters);
    }

    /**
     * @throws Exception
     */
    protected function sendShellySwitchRequest(array $parameters): array|object|null
    {
        if (is_callable($this->request_sender)) {
            $sender = $this->request_sender;
            return $sender($parameters);
        }
        return (new shelly())->sendPostRequest('/v2/devices/api/set/switch', $parameters);
    }

    /**
     * @throws Exception
     */
    public function getStatus(): array|object|null
    {
        $parameters = [
            'id' => (string)$this->id,
            'channel' => (int)$this->channel,
        ];
        return $this->sendShellySwitchRequest($parameters);
    }

    public function setRequestSender(callable $sender): self
    {
        $this->request_sender = $sender;
        return $this;
    }
}
