<?php

declare(strict_types=1);

class EMS_MQTT_Device extends IPSModule
{
    public function Create()
    {
        parent::Create();

        // Device-ID
        $this->RegisterPropertyString("DeviceID", "");

        // 6 editable values (response payload)
        $this->RegisterVariableFloat("PowerProduction", "Power Production", "", 10);
        $this->EnableAction("PowerProduction");

        $this->RegisterVariableFloat("StateOfCharge", "State of Charge", "", 20);
        $this->EnableAction("StateOfCharge");

        $this->RegisterVariableBoolean("IsRunning", "Is Running", "", 30);
        $this->EnableAction("IsRunning");

        $this->RegisterVariableBoolean("IsReady", "Is Ready", "", 40);
        $this->EnableAction("IsReady");

        $this->RegisterVariableInteger("MinSOC", "Min SOC", "", 50);
        $this->EnableAction("MinSOC");

        $this->RegisterVariableInteger("MaxSOC", "Max SOC", "", 60);
        $this->EnableAction("MaxSOC");

        // Remote-Control incoming (read-only)
        $this->RegisterVariableFloat("RC_PowerSetpoint", "RC Power Setpoint", "", 70);
        $this->RegisterVariableString("RC_Strategy", "RC Strategy", "", 80);

        // Parent MQTT Splitter
        $this->ConnectParent('{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}');
    }

    public function ApplyChanges()
    {
        parent::ApplyChanges();

        $this->ConnectParent('{F7A0DD2E-7684-95C0-64C2-D2A9DC47577B}');

        $device = $this->ReadPropertyString("DeviceID");

        // Subscribes
        $topics = [
            "feedback-request/" . $device,
            "remote-control-request/" . $device
        ];

        foreach ($topics as $t) {
            $this->SendDataToParent(json_encode([
                "DataID" => "{043E0F88-B2B0-4DF4-B1A6-64FB1C385D3C}",
                "PacketType" => 8, // SUBSCRIBE
                "Topic" => $t
            ]));
        }
    }

    // ---------------------------------------------------------------------
    // ACTION HANDLER
    // ---------------------------------------------------------------------
    public function RequestAction($Ident, $Value)
    {
        SetValue($this->GetIDForIdent($Ident), $Value);
    }

    // ---------------------------------------------------------------------
    // RECEIVE FROM MQTT
    // ---------------------------------------------------------------------
    public function ReceiveData($JSONString)
    {
        $data = json_decode($JSONString);
        if (!isset($data->Topic) || !isset($data->Payload)) {
            return;
        }

        $topic  = $data->Topic;
        $payload = $data->Payload;

        $deviceID = $this->ReadPropertyString("DeviceID");

        // Topics
        $feedbackReq  = "feedback-request/" . $deviceID;
        $remoteReq    = "remote-control-request/" . $deviceID;

        if ($topic === $feedbackReq) {
            $this->HandleFeedbackRequest();
        }

        if ($topic === $remoteReq) {
            $this->HandleRemoteControlRequest($payload);
        }
    }

    // ---------------------------------------------------------------------
    // HANDLE FEEDBACK REQUEST -> SEND STATE JSON
    // ---------------------------------------------------------------------
    private function HandleFeedbackRequest()
    {
        $response = [
            "power_production" => GetValue($this->GetIDForIdent("PowerProduction")),
            "state_of_charge"  => GetValue($this->GetIDForIdent("StateOfCharge")),
            "is_running"       => GetValue($this->GetIDForIdent("IsRunning")),
            "is_ready"         => GetValue($this->GetIDForIdent("IsReady")),
            "min_soc"          => GetValue($this->GetIDForIdent("MinSOC")),
            "max_soc"          => GetValue($this->GetIDForIdent("MaxSOC"))
        ];

        $topic = "feedback-response/" . $this->ReadPropertyString("DeviceID");

        $this->SendToMQTT($topic, json_encode($response));
    }

    // ---------------------------------------------------------------------
    // HANDLE REMOTE CONTROL REQUEST
    // payload:
    // { "power_setpoint": 150, "strategy": "activation" }
    // ---------------------------------------------------------------------
    private function HandleRemoteControlRequest(string $payload)
    {
        $data = json_decode($payload, true);
        if (!is_array($data)) {
            return;
        }

        // Write values to variables
        if (isset($data["power_setpoint"])) {
            SetValue($this->GetIDForIdent("RC_PowerSetpoint"), $data["power_setpoint"]);
        }

        if (isset($data["strategy"])) {
            SetValue($this->GetIDForIdent("RC_Strategy"), $data["strategy"]);
        }

        // Respond with same JSON
        $topic = "remote-control-response/" . $this->ReadPropertyString("DeviceID");
        $this->SendToMQTT($topic, json_encode($data));
    }

    // ---------------------------------------------------------------------
    // MQTT SEND HELPERS
    // ---------------------------------------------------------------------
    private function SendToMQTT(string $topic, string $payload)
    {
        $this->SendDataToParent(json_encode([
            "DataID"  => "{043E0F88-B2B0-4DF4-B1A6-64FB1C385D3C}",
            "PacketType" => 3,
            "QualityOfService" => 0,
            "Retain" => false,
            "Topic" => $topic,
            "Payload" => $payload
        ]));
    }

    // ---------------------------------------------------------------------
    // CONFIG FORM
    // ---------------------------------------------------------------------
    public function GetConfigurationForm()
    {
        return json_encode([
            "elements" => [
                [
                    "type" => "ValidationTextBox",
                    "name" => "DeviceID",
                    "caption" => "Device ID"
                ]
            ]
        ]);
    }
}
?>