<?php

namespace common\logic\Setting;

use common\logic\AbstractBuilder;
use common\logic\Producer\Producer\Model\Producer;
use yii\base\ErrorException;

class SettingBuilder extends AbstractBuilder
{
    protected SettingDefinition $settingDefinition;
    protected SettingRepository $settingRepository;

    public function loadDependencies(): void
    {
        $this->settingDefinition = $this->loadService(SettingDefinition::class);
        $this->settingRepository = $this->loadService(SettingRepository::class);
    }

    public function instanciateSetting(
        string $name,
        Producer $producer = null
    ): Setting
    {
        $setting = new Setting();
        $setting->name = $name;
        $setting->populateProducer($producer);
        $this->initDefaultValue($setting);

        return $setting;
    }

    public function createSetting(
        string $name,
        Producer $producer = null
    ): Setting
    {
        if($producer) {
            $setting = $this->settingRepository->findOneProducerSettingByName($name);
        }
        else {
            $setting = $this->settingRepository->findOneAdminSettingByName($name);
        }

        if(!$setting) {
            $setting = $this->instanciateSetting($name);
            $this->create($setting);
        }

        return $setting;
    }

    public function initValue(Setting $setting, $value)
    {
        $settingDetail = $this->settingDefinition->getSettingDetailByName($setting->name);
        $type = $settingDetail->getType();
        if(in_array($type, ['string', 'text', 'date', 'integer', 'float', 'double', 'boolean'])) {
            $setting->$type = $value;
        }
        else {
            throw new ErrorException("Le type de donnée du SettingDetail n'est pas reconnu.");
        }
    }

    public function initDefaultValue(Setting $setting)
    {
        $settingDetail = $this->settingDefinition->getSettingDetailByName($setting->name);
        if($settingDetail->getDefaultValue()) {
            $this->initValue($setting, $settingDetail->getDefaultValue());
        }
    }

    public function updateValue(Setting $setting, $value): void
    {
        $this->initValue($setting, $value);
        $this->update($setting);
    }

    public function updateDefaultValueByName(Setting $setting)
    {
        $this->initDefaultValue($setting);
        $this->update($setting);
    }
}