<?php

namespace objects;

use classes\department_relay_config;
use classes\db;
use classes\object_property;
use classes\selfserve;
use Exception;
use traits\db_object_t;

class department_relays_o extends db
{
    use db_object_t;

    public object_property $department; // The department id
    public object_property $relay_id; // The Shelly relay id
    public object_property $name; // The name of the relay
    public object_property $type; // The type of relay (e.g. 'SWITCH', 'TRIGGER')
    public object_property $config; // A JSON with the relay config, including any relevant parameters (e.g. for a trigger what should happen, and the trigger webhook token)
    public object_property $created_at;
    public object_property $updated_at;
    public object_property $deleted_at;


    public function structure(): void
    {
        $this->setTable('department_relays');
    }

    /**
     * Add a relay
     * @param departments_o $department The department for the relay
     * @param string $relay_id The Shelly relay id
     * @param string $name The name of the relay
     * @param string $type The type of relay (e.g. 'SWITCH', 'TRIGGER')
     * @param department_relay_config $config A JSON with the relay config, including any relevant parameters (e.g. for a trigger what should happen, and the trigger webhook token)
     * @return department_relays_o
     * @throws Exception If the object was not created successfully
     */
    public function add(departments_o $department, string $relay_id, string $name, string $type, department_relay_config $config): department_relays_o
    {
        global /** @var db $db */ $db;
        // Sanitize the input
        $department->requireSelected();
        $relay_id = trim($db->escape_string($relay_id));
        if (empty($relay_id)) {
            throw new Exception('Relay ID cannot be empty');
        }
        $name = trim($db->escape_string($name));
        if (empty($name)) {
            throw new Exception('Relay name cannot be empty');
        }
        $type = trim($db->escape_string($type));
        if (empty($type)) {
            throw new Exception('Relay type cannot be empty');
        }
        $config->validate($type);
        // Add the object
        $tmp_id = self::add_object([
            'department' => (int)$department->id,
            'relay_id' => $relay_id,
            'name' => $name,
            'type' => $type,
            'config' => (array)$config->toArray(),
        ]);
        $this->id = $tmp_id;
        self::getObjectProperties();
        self::objectChanged();
        return $this;
    }


    public function getObjectProperties(): void
    {
        $this->department = new object_property($this->table, $this->id, 'department', 'int', false);
        $this->relay_id = new object_property($this->table, $this->id, 'relay_id', 'string', false);
        $this->name = new object_property($this->table, $this->id, 'name', 'string', false);
        $this->type = new object_property($this->table, $this->id, 'type', 'string', false);
        $this->config = new object_property($this->table, $this->id, 'config', 'json', false);
        $this->created_at = new object_property($this->table, $this->id, 'created_at', 'timestamp', false);
        $this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'timestamp', false);
        $this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'timestamp', false);
    }

    public function objectChanged(): void
    {
        //TODO: Add cache invalidation
    }

    /**
     * Get the relay as an array
     * @return array The relay as an array
     * @throws Exception If the object is not valid or selected.
     */
    public function asArray(): array
    {
        $this->requireSelected();
        return [
            'id' => (int)$this->id,
            'department' => (int)$this->department->value(),
            'relay_id' => (string)$this->relay_id->value(),
            'name' => (string)$this->name->value(),
            'type' => (string)$this->type->value(),
            'config' => (array)$this->config->value(),
            'created_at' => (string)$this->created_at->value(),
            'updated_at' => (string)$this->updated_at->value(),
        ];
    }

    /**
     * @throws Exception
     * @return department_relays_o[]
     */
    public function getDepartmentRelays(int $department_id): array
    {
        $relays = [];
        $department_relays = self::getFieldsWhere(
            [
                'department' => $department_id,
                'deleted_at' => null,
            ],
            [
                'id',
            ],
        );

        foreach ($department_relays as $department_relay) {
            $relays[] = (new department_relays_o())->select((int)$department_relay['id']);
        }

        return $relays;
    }

}