<?php

namespace modules\selfserve\traits;
require_once WD . '/modules/selfserve/helpers/selfserve_lane_relay.php';
require_once WD . '/modules/selfserve/classes/selfserve_lane.php';

use classes\shelly;
use modules\selfserve\helpers\selfserve_lane_log_action;
use modules\selfserve\helpers\selfserve_lane_relay;
use modules\selfserve\helpers\selfserve_lane_state;
use modules\selfserve\helpers\selfserve_lane_status;
use modules\shelly\helpers\shelly_device_switch;
use modules\shelly\helpers\shelly_request_body_get_states;

trait selfserve_lane_relay_controller_t
{
    /**
     * Turn on the lane relay
     * @param selfserve_lane_relay $relay The relay to turn on (MACHINE)
     * @parm int|null $duration The duration in seconds to keep the relay on (optional)
     * @return bool True if the relay was successfully turned on
     * @throws \Exception If an invalid relay is specified or if the lane is not in a state to turn on the relay
     */
    public function turnOnRelay(selfserve_lane_relay $relay, ?int $duration = null): bool
    {
        // Require department lane object
        if (empty($this->department_lane)) throw new \Exception("Department lane object not found for lane ID {$this->id}");
        // Check lane status
        if ($this->status->equals(selfserve_lane_status::CLOSED)) throw new \Exception("Cannot turn on relay on CLOSED lane");
        if ($this->status->equals(selfserve_lane_status::MAINTENANCE)) throw new \Exception("Cannot turn on relay on MAINTENANCE lane");
        if ($this->status->equals(selfserve_lane_status::FAULT)) throw new \Exception("Cannot turn on relay on FAULT lane");
        // Get the relay ID based on the relay type
        $relay_id = match ($relay) {
            selfserve_lane_relay::MACHINE => $this->department_lane->relay_machine_id->value(),
            default => throw new \Exception("Invalid relay specified, must be MACHINE"),
        };
        // Make sure relay ID is valid
        if (empty($relay_id)) {
            throw new \Exception("Invalid relay ID for relay {$relay->name}");
        }
        $shelly = new shelly();
        $shelly->requireModuleEnabled();
        $shelly->requireValidSecretKey();
        $parameters = new shelly_request_body_get_states();
        $parameters->ids = [$relay_id];
        $parameters->select = ['status'];
        $result = $shelly->sendPostRequest('/v2/devices/api/get', (array)$parameters);
        // Wait 1 second
        sleep(1);
        // Format the result
        $result = array_map(function ($device) {
            return (new shelly_device_switch())->populate($device);
        }, $result);
        // Turn on the switch
        foreach ($result as $device) {
            if ($duration !== null) $device->toggle_after = $duration; // Set the duration to turn off the relay (if specified)
            $device->switch(true);
        }
        return true;
    }

    /**
     * Turn off the lane relay
     * @param selfserve_lane_relay $relay The relay to turn off (MACHINE)
     * @return bool True if the relay was successfully turned off
     * @throws \Exception If an invalid relay is specified or if the lane is not in a state to turn off the relay
     */
    public function turnOffRelay(selfserve_lane_relay $relay): bool
    {
        // Require department lane object
        if (empty($this->department_lane)) throw new \Exception("Department lane object not found for lane ID {$this->id}");
        // Check lane status
        if ($this->status->equals(selfserve_lane_status::CLOSED)) throw new \Exception("Cannot turn off relay on CLOSED lane");
        if ($this->status->equals(selfserve_lane_status::MAINTENANCE)) throw new \Exception("Cannot turn off relay on MAINTENANCE lane");
        if ($this->status->equals(selfserve_lane_status::FAULT)) throw new \Exception("Cannot turn off relay on FAULT lane");
        // Get the relay ID based on the relay type
        $relay_id = match ($relay) {
            selfserve_lane_relay::MACHINE => $this->department_lane->relay_machine_id->value(),
            default => throw new \Exception("Invalid relay specified, must be MACHINE"),
        };
        // Make sure relay ID is valid
        if (empty($relay_id)) {
            throw new \Exception("Invalid relay ID for relay {$relay->name}");
        }
        $shelly = new shelly();
        $shelly->requireModuleEnabled();
        $shelly->requireValidSecretKey();
        $parameters = new shelly_request_body_get_states();
        $parameters->ids = [$relay_id];
        $parameters->select = ['status'];
        $result = $shelly->sendPostRequest('/v2/devices/api/get', (array)$parameters);
        // Wait 1 second
        sleep(1);
        // Format the result
        $result = array_map(function ($device) {
            return (new shelly_device_switch())->populate($device);
        }, $result);
        // Turn off the switch
        foreach ($result as $device) {
            $device->switch(false);
        }
        return true;
    }
}