<?php

namespace Modules\Stock\TwigExtension;

use Entity\Model\Codgest;
use Entity\Model\Sectimpu;
use Exception;
use Helpers\Trad\ITrad;
use Modules\Stock\Enum\ImputationEnum;
use PDO;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use stdClass;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
use Helpers\Outil\Sql;

class ImputationExtension extends AbstractExtension
{

    private PDO $pdo;
    private ITrad $trad;

    /**
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function __construct(ContainerInterface $contenaire)
    {
        $this->pdo = $contenaire->get(PDO::class);
        $this->trad = $contenaire->get(ITrad::class);
    }

    public function getFunctions(): array
    {
        return [
            new TwigFunction('has_codgest', [$this, 'hasCodgest']),
            new TwigFunction('imputation_param_zoom', [$this, 'getImputationParamZoom']),
            new TwigFunction('imputation_param_validator', [$this, 'getImputationParamValidator']),
        ];
    }

    /**
     * @throws Exception
     */
    public function getImputationParamZoom(?stdClass $configAxeImp, string $codeSteInputId, string $imputation): string
    {
        $siCodeSteParam = $configAxeImp?->SectImp?->isSecto ?
            ",'CODE_STE' : $('#'+CSS.escape('".$codeSteInputId."')).val(),'codeSte' : $('#'+CSS.escape('".$codeSteInputId."')).val()"
            :" ";

        $scaCodeSteparam = $configAxeImp?->SousCompteAna?->isSecto ?
            ",'CODE_STE' : $('#'+CSS.escape('".$codeSteInputId."')).val(),'codeSte' : $('#'+CSS.escape('".$codeSteInputId."')).val()"
            :" ";

        $cdcCodeSteParam = $configAxeImp?->CodeCompl?->isSecto ?
            ",'CODE_STE' : $('#'+CSS.escape('".$codeSteInputId."')).val(),'codeSte' : $('#'+CSS.escape('".$codeSteInputId."')).val()"
            :" ";

        return match (ImputationEnum::tryFrom($imputation)) {
            ImputationEnum::SI => "{'si_valide' : '1'".$siCodeSteParam."}",
            ImputationEnum::SCA => "{'sca_valide' : '1'".$scaCodeSteparam."}",
            ImputationEnum::CDC => "{'cdc_valide' : '1'".$cdcCodeSteParam."}",
        };
    }

    /**
     * @throws Exception
     */
    public function getImputationParamValidator(?stdClass $configAxeImp, string $codeSteInputId, string $imputation, bool $isObligatoire = false): string
    {
        $null = $isObligatoire ? "false" : "true";
        $siPost = $configAxeImp?->SectImp?->isSecto ? ",'post' : {'filter_egal_CODE_STE': $('#'+CSS.escape('".$codeSteInputId."')).val() }":"";
        $scaPost = $configAxeImp?->SousCompteAna?->isSecto ? ",'post' : {'filter_egal_CODE_STE': $('#'+CSS.escape('".$codeSteInputId."')).val() }":"";
        $cdcPost = $configAxeImp?->CodeCompl?->isSecto ? ",'post' : {'filter_egal_CODE_STE': $('#'+CSS.escape('".$codeSteInputId."')).val() }":"";

        return match (ImputationEnum::tryFrom($imputation)) {
            ImputationEnum::SI => "{'entity' : 'Sectimpu','nomChamp' : '" . $this->trad->t('Section imputation') . "', 'null' : " . $null . $siPost."}",
            ImputationEnum::CDC => "{'entity' : 'codeComp','nomChamp' : '" . $this->trad->t('Code complémentaire') . "', 'null' : " . $null . $cdcPost."}",
            ImputationEnum::SCA => "{'entity' : 'Sscptana','nomChamp' : '" . $this->trad->t('Sous-compte d\\\'analyse') . "', 'null' : " . $null . $scaPost . "}",
        };
    }

    /**
     * @param string $codeSte
     * @param null|string $codeSi
     * @return bool
     * @throws Exception
     */
    public function hasCodgest(string $codeSte, ?string $codeSi): bool
    {
        if (!$codeSi) {
            return true;
        }

        return Sql::toBool((new Sectimpu($this->pdo))->find(['CODE_STE' => $codeSte, 'CODE_SI' => $codeSi], ['SICODG'])['SICODG']);
    }
}
