<?php

namespace common\logic\Document\Document\Service;

use common\logic\AbstractGenerator;
use common\logic\Document\Document\Model\Document;
use common\logic\Document\Document\Model\DocumentInterface;
use common\logic\Producer\Producer\Service\ProducerSolver;
use common\logic\User\User\Model\User;
use common\logic\User\User\Service\UserSolver;

class DocumentReferenceGenerator extends AbstractGenerator
{
    protected DocumentSolver $documentSolver;
    protected ProducerSolver $producerSolver;
    protected UserSolver $userSolver;

    public function loadDependencies(): void
    {
        $this->documentSolver = $this->loadService(DocumentSolver::class);
        $this->producerSolver = $this->loadService(ProducerSolver::class);
        $this->userSolver = $this->loadService(UserSolver::class);
    }

    public function generateReference(DocumentInterface $document): void
    {
        $class = $this->documentSolver->getClass($document);
        $classComplete = $this->documentSolver->getClass($document, true);
        $classLower = strtolower($class);
        if ($classLower == 'deliverynote') {
            $classLower = 'delivery_note';
        }

        $prefix = $this->producerSolver->getConfig('document_' . $classLower . '_prefix');
        $oneDocumentExist = $classComplete::searchOne(['status' => Document::STATUS_VALID], ['orderby' => 'reference_number DESC']);

        if ($oneDocumentExist) {
            $referenceNumberDocumentExist = $oneDocumentExist->reference_number;
            $referenceNumber = $referenceNumberDocumentExist + 1;
            $reference = $this->buildReference($prefix, $referenceNumber, $document);
        } else {
            $firstReference = $this->producerSolver->getConfig('document_' . $classLower . '_first_reference');
            if (strlen($firstReference) > 0) {
                $referenceNumber = (int) filter_var(str_replace('-', '', $firstReference), FILTER_SANITIZE_NUMBER_INT);
                $reference = $firstReference;
            } else {
                $referenceNumber = 1;
                $reference = $this->buildReference($prefix, 1, $document);
            }
        }

        $document->reference = $reference;
        $document->reference_number = $referenceNumber;
    }

    public function buildReference(string $prefix, int $referenceNumber, DocumentInterface $document)
    {
        $prefix = $this->replaceKeywords($prefix, $document);
        return $prefix . $this->strPadReference($referenceNumber);
    }

    public function replaceKeywords(string $prefix, DocumentInterface $document): string
    {
        $prefix = str_replace('[ANNEE]', date('Y'), $prefix);
        $prefix = str_replace('[CLIENT]', strtoupper($this->getMainName($document->user)), $prefix);

        return $prefix;
    }

    public function strPadReference(int $referenceNumber): string
    {
        return str_pad($referenceNumber, 5, '0', STR_PAD_LEFT);
    }

    private function getMainName(User $user): string
    {
        if($this->userSolver->isTypeLegalPerson($user) && strlen($user->name_legal_person)) {
            return $user->name_legal_person;
        }
        else {
            return $user->lastname;
        }
    }

}