<?php

namespace apexl\Io\services;

use apexl\ClassEngine\EngineSingleton;
use apexl\Io\includes\Hook;
use apexl\Io\modules\user\services\currentUser;

class globalData extends EngineSingleton {

    protected $data;

    public function addData(string $key, $data, $merge = TRUE, $getData = FALSE){
        if($merge) {
            if(isset($this->data[$key]) && is_array($this->data[$key])) {
                $this->data[$key] = array_merge($this->data[$key], $data);
            } else {
                $this->data[$key] = $data;
            }
        } else {
            $this->data[$key] = $data;
        }
        if($getData) {
            //when we add data, we need to load it to store. Initial load should ignore hook calls to prevent infinate loops.
            Hook::disable();
            $this->getData();
            Hook::enable();
            //Now that we have default entity data, reload with the hooks.
            $this->getData(null, true);
        }
    }

    /**
     * Function to allow is to flat replace the data object. Useful if a middleware wants to replace all data in certain situations
     * @param $data
     */
    public function replaceData($data){
        $this->data = $data;
    }

    public function getData($key = null, $reload = FALSE){
        if(!$reload && $key && isset($this->data[$key]) && !empty($this->data[$key])){
            return $this->data[$key];
        }
        $this->processEntities();
        $safeData = $this->data;
        unset($safeData['entities']);
        //allow us to force a reload and return the key
        if($key){
            return $this->data[$key] ?? null;
        }
        return $safeData;
    }

    protected function processEntities(){
        if(!empty($this->data['entities'])) {
            foreach ($this->data['entities'] as $key => $entity){
                $merge = $entity['merge'] ?? TRUE;
                //we need to make sure we dont try to perform an access check on ourselves.
                $skipAccessCheck = FALSE;
                if($key == "user"){
                    $skipAccessCheck = TRUE;
                }
                $entity['entity']->load($entity['id'], $skipAccessCheck);
                $this->addData($key, (object) $entity['entity']->getData(), $merge);
                $this->addData('entities', ['user' => ['entity' => $entity['entity'], 'id' => $entity['entity']->id]]);
            }
        }
    }
}