<?php

namespace domain\Producer\Producer;

use common\helpers\Souke;
use common\helpers\Password;
use common\helpers\Upload;
use common\helpers\Url;
use domain\User\User\User;
use domain\User\UserProducer\UserProducer;
use domain\User\UserProducer\UserProducerBuilder;
use domain\User\UserProducer\UserProducerRepository;
use domain\_\AbstractBuilder;

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;
        $this->initSponsorshipCode($producer);

        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, bool $bookmark = true, bool $newsletter = true): UserProducer
    {
        $userProducer = $this->userProducerBuilder->createUserProducerIfNotExist($user, $producer, $bookmark, $newsletter);

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

        $this->update($userProducer);

        return $userProducer;
    }

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

        $this->update($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
        );
    }

    public function savePrivateKeysStripe(Producer $producer)
    {
        $this->savePrivateKeyApiStripe($producer);
        $this->savePrivateKeyEndpointStripe($producer);

        $producer->option_stripe_private_key = '';
        $producer->option_stripe_endpoint_secret = '';

        $producer->save();
    }

    public function initOptionsDatesBeforeSave(Producer $producer): void
    {
        $this->initOptionsDatesBeforeSaveByField($producer, 'option_dashboard_date_start');
        $this->initOptionsDatesBeforeSaveByField($producer, 'option_dashboard_date_end');
        $this->initOptionsDatesBeforeSaveByField($producer, 'option_leave_period_start');
        $this->initOptionsDatesBeforeSaveByField($producer, 'option_leave_period_end');
    }

    public function initOptionsDatesDisplay(Producer $producer): void
    {
        $this->initOptionsDatesDisplayByField($producer, 'option_dashboard_date_start');
        $this->initOptionsDatesDisplayByField($producer, 'option_dashboard_date_end');
        $this->initOptionsDatesDisplayByField($producer, 'option_leave_period_start');
        $this->initOptionsDatesDisplayByField($producer, 'option_leave_period_end');
    }

    private function initOptionsDatesBeforeSaveByField(Producer $producer, string $field): void
    {
        if ($producer->$field && strlen($producer->$field)) {
            $producer->$field = date(
                'Y-m-d',
                strtotime(str_replace('/', '-', $producer->$field))
            );
        }
    }

    private function initOptionsDatesDisplayByField(Producer $producer, string $field): void
    {
        if (strlen($producer->$field)) {
            $producer->$field = date('d/m/Y', strtotime($producer->$field));
        }
    }

    public function processUploadImage(Producer $producer, string $name, string $filenameOld = null, bool $deleteImage = false)
    {
        Upload::uploadFile($producer, $name.'File', $name, $filenameOld);
        if ($deleteImage) {
            $producer->$name = '';
            $producer->save();
        }
    }

    public function initSponsorshipCode(Producer $producer): self
    {
        $producer->setSponsorshipCode(Password::generate());
        return $this;
    }
}