<?php

namespace objects;

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

class department_time_bookings_types_o extends db
{
    use db_object_t;

    public object_property $department; // The department id
    public object_property $name; // The name of the booking type
    public object_property $product; // The product id
    public object_property $description; // The description of the booking type
    public object_property $duration; // The duration of the booking type (in minutes)
    public object_property $deleted_at; // The deleted at timestamp

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

    /**
     * Convert the object to an array
     * @throws Exception If the object is not selected
     * @throws Exception If the object is not found
     */
    public function asArray(): array
    {
        self::requireSelected();
        return [
            'id' => (int)$this->id,
            'department' => (int)$this->department->value(),
            'name' => $this->name->value(),
            'product' => (int)$this->product->value(),
            'description' => $this->description->value(),
            'duration' => (int)$this->duration->value(),
        ];
    }

    /**
     * Add a new object to the database
     * @param int $department_id The department id
     * @param string|null $name The name of the booking type
     * @param int $product The product id
     * @param null|string $description The description of the booking type
     * @param int $duration The duration of the booking type (in minutes)
     * @return void
     * @throws Exception If the object was not created successfully
     */
    public function add(
        int     $department_id,
        ?string $name = null,
        int     $product = 0,
        ?string $description = null,
        int     $duration = 0
    ): void
    {

        $tmp_id = self::add_object([
            'department' => (int)$department_id,
            'name' => $name,
            'product' => (int)$product,
            'description' => $description,
            'duration' => (int)$duration,
        ]);
        $this->id = $tmp_id;
        self::getObjectProperties();
        self::objectChanged();
    }

    public function getObjectProperties(): void
    {
        $this->department = new object_property($this->table, $this->id, 'department', 'int', true);
        $this->name = new object_property($this->table, $this->id, 'name', 'string', true);
        $this->product = new object_property($this->table, $this->id, 'product', 'int', true);
        $this->description = new object_property($this->table, $this->id, 'description', 'string', true);
        $this->duration = new object_property($this->table, $this->id, 'duration', 'int', true);
        $this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'int', true);
    }

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

    /**
     * Get the duration of a booking type by its ID
     * @param int $id The ID of the booking type
     * @return int The duration of the booking type in minutes
     * @throws Exception If the object could not be selected
     */
    public function getDurationById(int $id): int
    {
        self::select((int)$id);
        return (int)$this->duration->value();
    }

    /**
     * @throws Exception
     */
    public function getName(): string
    {
        self::requireSelected();
        // Check if the type has a name set
        $type_name = $this->name->value();
        if (!empty($type_name)) {
            return $type_name;
        }
        // If the type does not have a name set, return the product name
        return self::getProduct()->name->value();
    }

    /**
     * @throws Exception
     */
    public function getProduct(): \objects\products_o
    {
        self::requireSelected();
        $product = new \objects\products_o();
        $product->select((int)$this->product->value());
        if (!$product->exists()) {
            throw new Exception('Product not found');
        }
        return $product;
    }
}