<?php

namespace common\logic\Producer\Producer\Service;

use common\helpers\Opendistrib;
use common\helpers\Password;
use common\logic\AbstractBuilder;
use common\logic\Producer\Producer\Model\Producer;
use common\logic\Producer\Producer\Repository\ProducerRepository;
use common\logic\User\User\Model\User;
use common\logic\User\UserProducer\Model\UserProducer;
use common\logic\User\UserProducer\Service\UserProducerBuilder;
use common\logic\User\UserProducer\Repository\UserProducerRepository;
use common\helpers\Url;

class ProducerBuilder extends AbstractBuilder
{
    protected ProducerRepository $producerRepository;
    protected UserProducerRepository $userProducerRepository;
    protected UserProducerBuilder $userProducerBuilder;
    protected ProducerSolver $producerSolver;

    public function loadDependencies(): void
    {
        $this->producerRepository = $this->loadService(ProducerRepository::class);
        $this->userProducerRepository = $this->loadService(UserProducerRepository::class);
        $this->userProducerBuilder = $this->loadService(UserProducerBuilder::class);
        $this->producerSolver = $this->loadService(ProducerSolver::class);
    }

    public function instanciateProducer(): Producer
    {
        $producer = new Producer();
        $producer->order_deadline = Producer::ORDER_DEADLINE_DEFAULT;
        $producer->order_delay = Producer::ORDER_DELAY_DEFAULT;

        return $producer;
    }

    public function initProducer(Producer $producer): void
    {
        $this->initProducerSlug($producer);
        $this->initProducerCode($producer);
    }

    public function initProducerSlug(Producer $producer): void
    {
        $cptSlug = 0 ;
        do {
            $slug = Url::slugify($producer->name) ;
            if($cptSlug) {
                $slug .= $cptSlug ;
            }
            $producer->slug = $slug ;
            $cptSlug ++ ;
        } while($this->producerRepository->findOneProducerBySlug($producer->slug)) ;
    }

    public function initProducerCode(Producer $producer): void
    {
        $producer->code = Password::generate();
    }

    /**
     * Lie un utilisateur à un producteur.
     */
    public function addUser(User $user, Producer $producer, int $bookmark = 1): UserProducer
    {
        $userProducer =  $this->userProducerBuilder->createUserProducerIfNotExist($user, $producer, $bookmark);

        if (!$userProducer->getActive()) {
            $userProducer->setActive(1);
        }

        $this->saveUpdate($userProducer);

        return $userProducer;
    }

    public function updateOpendistribVersion(Producer $producer): void
    {
        $versionsArray = Opendistrib::getVersions();
        $producer->latest_version_opendistrib = reset($versionsArray);

        $this->saveUpdate($producer);
    }

    public function savePrivateKeyStripe($filename, $value)
    {
        if (strlen($value) > 0) {
            $handle = fopen($filename, "w");
            fwrite($handle, $value);
            fclose($handle);
        }
    }

    public function savePrivateKeyApiStripe(Producer $producer): void
    {
        $this->savePrivateKeyStripe(
            $this->producerSolver->getFilenamePrivateKeyApiStripe($producer),
            $producer->option_stripe_private_key
        );
    }

    public function savePrivateKeyEndpointStripe(Producer $producer): void
    {
        $this->savePrivateKeyStripe(
            $this->producerSolver->getFilenamePrivateKeyEndpointStripe($producer),
            $producer->option_stripe_endpoint_secret
        );
    }
}