<?php

namespace objects;

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

class department_categories_o extends db
{
    use db_object_t;

    public object_property $department_id;
    public object_property $category_id;
    public object_property $created_at;
    public object_property $updated_at;
    public object_property $deleted_at;


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

    /**
     * Add a department category, and set this object to the new object
     * @param int $department_id
     * @param int $category_id
     * @return void
     * @throws Exception If the object was not created successfully
     */
    public function add(int $department_id, int $category_id): void
    {
        // Make sure we don't add the same department category twice
        if (count(self::getFieldsWhere(
                [
                    'department_id' => $department_id,
                    'category_id' => $category_id,
                    'deleted_at' => null
                ], ['id'])) > 0) {
            throw new Exception('Department category already exists');
        }
        $tmp_id = self::add_object([
            'department_id' => $department_id,
            'category_id' => $category_id
        ]);
        $this->id = $tmp_id;
        self::getObjectProperties();
        self::objectChanged();
    }

    public function getObjectProperties(): void
    {
        $this->department_id = new object_property($this->table, $this->id, 'department_id', 'int', false);
        $this->category_id = new object_property($this->table, $this->id, 'category_id', 'int', false);
        $this->created_at = new object_property($this->table, $this->id, 'created_at', 'string', false);
        $this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'string', false);
        $this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'string', false);
    }

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

    /**
     * Get the categories for a department
     * @param int $department_id
     * @return array The categories for the department
     */
    public function getCategoriesForDepartment(int $department_id, $parseFunction = null): array
    {
        $category_ids = self::getFieldsWhere(
            [
                'department_id' => $department_id,
                'deleted_at' => null
            ],
            ['id', 'category_id']
        );
        $categories = [];
        foreach ( $category_ids as $category_id ) {
            $tmp = (new department_categories_o())->select($category_id['id'])->asArray();
            $tmp['category'] = (new categories_o())->select($tmp['category_id']);
            $categories[] = $tmp;

        }
        if ($parseFunction) {
            $tmp = [];
            foreach ( $categories as $category ) {
                $tmp[] = $parseFunction($category);
            }
            $categories = $tmp;
        }
        return $categories;

    }

    public function asArray(): array
    {
        return [
            'id' => (int)$this->id,
            'department_id' => (int)$this->department_id->value(),
            'category_id' => (int)$this->category_id->value(),
            'created_at' => (string)$this->created_at->value(),
            'updated_at' => (string)$this->updated_at->value(),
            'deleted_at' => (string)$this->deleted_at->value()
        ];
    }

    /**
     * @throws Exception
     * @returns department_categories_o[] Array of department category objects for a department
     */
    public function getDepartmentCategoryObjects(int $department): array
    {
        $department_categories = self::getFieldsWhere(
            [
                'department_id' => $department,
                'deleted_at' => null
            ],
            ['id']
        );
        /** @var department_categories_o[] $objects */
        $objects = [];
        foreach ( $department_categories as $department_category ) {
            $objects[] = (new department_categories_o())->select((int)$department_category['id']);
        }
        return $objects;
    }

    /**
     * Get the category associated with this department category
     * @return categories_o The category object
     * @throws Exception If the category does not exist
     */
    public function getCategory(): categories_o
    {
        self::requireSelected();
        return (new categories_o())->select($this->category_id->value());
    }

}