<?php

namespace common\logic\Document\Document\Service;

use common\logic\AbstractBuilder;
use common\logic\Document\Document\Model\Document;
use common\logic\Document\Document\Model\DocumentInterface;
use common\logic\Document\Document\Repository\DocumentRepository;
use common\logic\Producer\Producer\Repository\ProducerRepository;

class DocumentBuilder extends AbstractBuilder
{
    protected DocumentSolver $documentSolver;
    protected DocumentRepository $documentRepository;
    protected ProducerRepository $producerRepository;

    public function loadDependencies(): void
    {
        $this->documentSolver = $this->loadService(DocumentSolver::class);
        $this->documentRepository = $this->loadService(DocumentRepository::class);
        $this->producerRepository = $this->loadService(ProducerRepository::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->producerRepository->getConfig('document_' . $classLower . '_prefix');
        $oneDocumentExist = $classComplete::searchOne(['status' => Document::STATUS_VALID], ['orderby' => 'reference DESC']);

        if ($oneDocumentExist) {
            $referenceDocument = $oneDocumentExist->reference;
            $pattern = '#([A-Z]+)?([0-9]+)#';
            preg_match($pattern, $referenceDocument, $matches, PREG_OFFSET_CAPTURE);
            $sizeNumReference = strlen($matches[2][0]);
            $numReference = ((int)$matches[2][0]) + 1;
            $numReference = str_pad($numReference, $sizeNumReference, '0', STR_PAD_LEFT);

            $reference = $prefix . $numReference;
        } else {
            $firstReference = $this->producerRepository->getConfig('document_' . $classLower . '_first_reference');

            if (strlen($firstReference) > 0) {
                $reference = $firstReference;
            } else {
                $reference = $prefix . '00001';
            }
        }

        $document->reference = $reference;
    }

    public function changeStatus(DocumentInterface $document, string $status): void
    {
        $document->status = $status;

        if ($status == Document::STATUS_VALID) {
            $this->generateReference($document);
        }
    }

    public function initTaxCalculationMethod(DocumentInterface $document): void
    {
        $producerTaxCalculationMethod = $this->producerRepository->getConfig('option_tax_calculation_method');

        if ($producerTaxCalculationMethod) {
            $document->tax_calculation_method = $producerTaxCalculationMethod;
        } else {
            $document->tax_calculation_method = Document::TAX_CALCULATION_METHOD_DEFAULT;
        }
    }
}