<?php

namespace common\logic\PointSale\PointSale\Service;

use common\logic\AbstractBuilder;
use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\PointSale\UserPointSale\Model\UserPointSale;
use common\logic\PointSale\UserPointSale\Repository\UserPointSaleRepository;
use common\logic\PointSale\UserPointSale\Service\UserPointSaleBuilder;
use common\logic\Producer\Producer\Model\Producer;
use common\logic\User\User\Model\User;
use common\logic\User\User\Repository\UserRepository;

class PointSaleBuilder extends AbstractBuilder
{
    protected UserPointSaleBuilder $userPointSaleBuilder;
    protected UserRepository $userRepository;
    protected UserPointSaleRepository $userPointSaleRepository;

    public function loadDependencies(): void
    {
        $this->userPointSaleBuilder = $this->loadService(UserPointSaleBuilder::class);
        $this->userRepository = $this->loadService(UserRepository::class);
        $this->userPointSaleRepository = $this->loadService(UserPointSaleRepository::class);
    }

    public function instanciatePointSale(): PointSale
    {
        $pointSale = new PointSale();

        $pointSale->button_generate_delivery_note_point_sale = true;
        $pointSale->button_generate_delivery_note_each_user = true;

        return $pointSale;
    }

    public function createPointSale(): PointSale
    {
        $pointSale = $this->instanciatePointSale();
        $this->saveCreate($pointSale);

        return $pointSale;
    }

    // resetPointProductions
    public function resetPointSalePointProductions(Producer $producer): void
    {
        PointSale::updateAll(
            ['point_production' => 0],
            ['id_producer' => $producer->id]
        );
    }

    /**
     * Traite la mise à jour de l'attribut 'point_production'.
     */
    // processPointProduction
    // updatePointProduction
    public function updatePointSalePointProduction(PointSale $pointSale): void
    {
        if ($pointSale->point_production) {
            $this->resetPointSalePointProductions($pointSale->producer);
            $pointSale->point_production = 1;
            $this->saveUpdate($pointSale);
        }
    }

    /**
     * Traite les accès restreints d'un point de vente.
     */
    public function processRestrictedAccess(PointSale $pointSale): void
    {
        $this->userPointSaleBuilder->deleteUserPointSalesByPointSale($pointSale);

        if (is_array($pointSale->users) && count($pointSale->users)) {
            foreach ($pointSale->users as $key => $val) {
                $user = $this->userRepository->findOneUserById($val);
                if ($user) {
                    $this->userPointSaleBuilder->createUserPointSale($user, $pointSale, $pointSale->users_comment[$val]);
                }
            }
        }
    }

    /**
     * Lie un utilisateur au point de vente.
     */
    // linkUser
    public function addUser(User $user, PointSale $pointSale): UserPointSale
    {
        return $this->userPointSaleBuilder->createUserPointSaleIfNotExist($user, $pointSale);
    }
}