<?php

class Pinned_items_model extends Cf_Model
{
    public const TABLE = 'pinned_items';

    public const INVENTORY_TYPE = 'inventory';
    public const CLASS_TYPE = 'class';
    public const VARIABLE_TYPE = 'variable';

    private $types = [];

    private $username;
    public function __construct()
    {
        $this->types = [self::CLASS_TYPE, self::INVENTORY_TYPE, self::VARIABLE_TYPE];

        $this->load->model(['advancedreports_model']);
    }

    public function add(string $user, string $type, string $name)
    {
        $data = [
            'username' => $user,
            'type' => $type,
            'name' => $name,
        ];

        $this->db->insert(self::TABLE, $data);
        return $this->db->insert_id();
    }

    public function delete($user, $id)
    {
        $this->db->delete(self::TABLE, ['id' => $id, 'username' => $user]);
    }

    public function getItemsWithValues($user, $hostkey, InventoryAPIService $inventoryService)
    {
        $this->username = $user;
        $items = $this->getItems($user);

        $groupedItems = [
            self::INVENTORY_TYPE => [],
            self::CLASS_TYPE => [],
            self::VARIABLE_TYPE => [],
        ];

        foreach ($items as $item) {
            $groupedItems[$item['type']][] = ['name' => $item['name'], 'id' => $item['id']];
        }

        foreach ($this->types as $type) {
            if (isset($groupedItems[$type]) && !empty($groupedItems[$type])) {
                switch ($type) {
                    case self::CLASS_TYPE:
                        $this->setClassValues($groupedItems[$type], $hostkey);
                        break;
                    case self::VARIABLE_TYPE:
                        $this->setVariableValues($groupedItems[$type], $hostkey);
                        break;
                    case self::INVENTORY_TYPE:
                        $this->setInventoryValues($groupedItems[$type], $hostkey, $inventoryService);
                }
            }
        }

        return $groupedItems;
    }

    public function getItems($user)
    {
        return $this->db->where('username', $user)->get(self::TABLE)->result_array();
    }

    private function setClassValues(array &$data, $hostkey)
    {
        $result = $this->advancedreports_model->getClassesByHostkey(
            $this->username,
            $hostkey,
            array_column($data, 'name'),
        );

        if (isset($result['rows']) && !empty($result['rows'])) {
            $values = array_map(function ($item) {
                return $item[0];
            }, $result['rows']);

            $data = array_map(function ($item) use ($values) {
                $item['value'] = in_array($item['name'], $values);
                return $item;
            }, $data);
        }
    }

    private function setVariableValues(array &$data, $hostkey)
    {
        $result = $this->advancedreports_model->getVariablesByHostkey(
            $this->username,
            $hostkey,
            array_column($data, 'name'),
        );
        if (isset($result['rows']) && !empty($result['rows'])) {
            foreach ($data as $index => $item) {
                $key = array_search($item['name'], array_column($result['rows'], '0'));
                $data[$index]['value'] = is_int($key) ? $result['rows'][$key][1] : null;
            }
        }
    }

    private function setInventoryValues(array &$data, $hostkey, InventoryAPIService $service)
    {
        $result = json_decode(
            $service->getData([
                'select' => array_column($data, 'name'),
                'filter' => ['hostkey' => ['=' => $hostkey]],
                'limit' => -1,
            ]),
            JSON_OBJECT_AS_ARRAY,
        );

        if (isset($result['rows']) && !empty($result['rows'])) {
            foreach ($data as $index => $item) {
                $data[$index]['value'] = $result['rows'][0][$index];
            }
        }
    }
}
