<?php

namespace onespace\tools\activeApi\models\onehealth;

use onespace\tools\activeApi\components\clients\OneHealthClient;
use Override;
use yii\web\NotFoundHttpException;

/**
 * @property integer $id
 * @property string $guid
 * @property integer $serial
 * @property integer $type_id
 * @property integer $site_id
 * @property integer $person_id
 * @property string $property_id
 * @property integer $state
 * @property string $first_seen
 * @property string $last_seen
 * @property integer $last_gateway_seen
 * @property array $extra
 * @property integer $battery_voltage
 * @property string $created_at
 * @property string $updated_at
 */
class Button extends \onespace\tools\activeApi\models\BaseActiveApiModel {
    public const int STATE_UNASSIGNED = 10;
    public const int STATE_ASSIGNED   = 20;

    public const int TYPE_BUTTON_ROLE_NOT_SET = 0;
    public const int TYPE_PATIENT_BUTTON      = 1;
    public const int TYPE_MONITORED_BUTTON    = 2;
    public const int TYPE_STAFF_BUTTON        = 3;
    public const int TYPE_PERSONAL_BUTTON     = 4;

    public $id;
    public $guid;
    public $serial;
    public $type_id;
    public $site_id;
    public $person_id;
    public $property_id;
    public $state;
    public $first_seen;
    public $last_seen;
    public $last_gateway_seen;
    public $extra;
    public $battery_voltage;
    public $created_at;
    public $updated_at;

    public function client(): OneHealthClient {
        return new OneHealthClient();
    }

    public function primaryKey(): string {
        return 'id';
    }

    public function baseEndpoints(): array {
        return [
            'v1' => 'api/v1/active/button',
        ];
    }

    /**
     * {@inheritdoc}
     */
    #[Override]
    public function rules() {
        return [
            [['person_id', 'property_id', 'first_seen', 'last_seen', 'last_gateway_seen', 'extra'], 'default', 'value' => null],
            [['state'], 'default', 'value' => 1],
            [['battery_voltage'], 'default', 'value' => 0],
            [[
                // 'guid', // Set automatically
                'serial',
                'type_id',
                'site_id',
            ], 'required'],
            [['serial', 'type_id', 'site_id', 'person_id', 'state', 'last_gateway_seen', 'battery_voltage'], 'integer'],
            [['first_seen', 'last_seen', 'extra'], 'safe'],
            [['guid', 'property_id'], 'string', 'max' => 36],
            // [['guid'], 'unique'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    #[Override]
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'guid' => 'Guid',
            'serial' => 'Serial',
            'type_id' => 'Type ID',
            'site_id' => 'Site ID',
            'person_id' => 'Person ID',
            'property_id' => 'Property ID',
            'state' => 'State',
            'first_seen' => 'First Seen',
            'last_seen' => 'Last Seen',
            'last_gateway_seen' => 'Last Gateway Seen',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
            'extra' => 'Extra',
            'battery_voltage' => 'Battery Voltage',
        ];
    }

    /**
     * {@inheritdoc}
     */
    #[Override]
    public function attributeHints() {
        return [
            'guid' => 'The unique external ID for this device',
            'serial' => 'The hardware serial for the button',
            'type_id' => 'The type of button this is',
            'site_id' => 'FK: Site',
            'person_id' => 'FK: People, the person to whom this button is assigned',
            'property_id' => 'Where (if anywhere) the button is assigned',
            'state' => 'Enum: 1=Unassigned, 2=Assigned',
            'first_seen' => 'When this device first checked in',
            'last_seen' => 'When this device last checked in',
            'last_gateway_seen' => 'FK: Health Gateway, where the device was last seen',
            'created_at' => 'When this record was created',
            'updated_at' => 'When this record was last updated',
            'extra' => 'Any extra information',
            'battery_voltage' => 'The last recorded battery voltage. Divide by 1000 to get voltage',
        ];
    }

    public static function findById(int $id): static {
        $model = self::findOne(['id' => $id]);
        if ($model === null) {
            throw new NotFoundHttpException("Button not found");
        }
        return $model;
    }

    public static function findByGuid(string $guid): static {
        $model = self::findOne(['guid' => $guid]);
        if ($model === null) {
            throw new NotFoundHttpException("Button not found");
        }
        return $model;
    }

    public static function findBySerial(int $id): static {
        $model = self::findOne(['serial' => $id]);
        if ($model === null) {
            throw new NotFoundHttpException("Button not found");
        }
        return $model;
    }

    /**
     * Returns the current battery voltage in volts
     *
     * - Greater than 3.05v - `Full`
     * - Between 2.9v and 3.05v - `Healthy`
     * - Less Than 2.9v - `Low`
     */
    public function voltage(): float {
        return $this->battery_voltage / 1000;
    }

    public function batteryFull(): bool {
        return $this->voltage() > 3.05;
    }

    public function batteryHealthy(): bool {
        $voltage = $this->voltage();
        return $voltage >= 2.9 && $voltage <= 3.05;
    }

    public function batteryLow(): bool {
        return $this->voltage() < 2.9;
    }
}
