<?php

namespace Modules\Stock\Repository;

use Exception;
use Helpers\Outil\Roles;
use Helpers\Pagination\PaginatorGestion;
use Helpers\QueryBuilder\AbsRepository;
use Modules\Stock\Enum\TypeEnteteEnum;
use Modules\Stock\Interface\EnteteRepoInterface;
use Modules\Stock\Service\RepoService;
use Modules\Stock\Trait\Repo\EnteteRepoTrait;
use Modules\Stock\Trait\Repo\ImputationRepoTrait;

class MouvementRepo extends AbsRepository implements EnteteRepoInterface
{
    use EnteteRepoTrait;
    use ImputationRepoTrait;

    /**
     * @param array<string,mixed> $post
     * @return array<int,array<string,mixed>>
     * @throws Exception
     */
    public function listMouvements(array $post) : array
    {
        $arrayReq = [];

        $siSectorisationJoinValue = $this->getImputationSectoJoinValue('SISECTOR', "SM.CODE_STE");

        $requete = "SELECT * FROM (
                        SELECT DISTINCT 
                            SM.*,
                            SA.DESIGN AS DESIGN,
                            SA.UNITE_ACH AS UNITE_ACH,
                            SM.QTE_MVT * SM.PU AS VAL_UNIT,
                            SA.SSFAM AS SSFAM,
                            SECT.LIBELLE AS SI_LIBELLE,
                            CDC.LIBELLE AS CDC_LIBELLE,
                            SCA.LIBELLE AS SCA_LIBELLE,
                            CGE.LIB_GES AS CGE_LIBELLE,
                            SA.UNITE_STK AS UNITE_STK,
                            STO.DESIGN AS STO_DESIGN
                        FROM SMOUVEME SM with (nolock)
                        LEFT JOIN SARTICLE SA ON SM.CODE_ART = SA.CODE_ART
                        LEFT JOIN SECTIMPU SECT ON SM.SECTIMP = SECT.CODE_SI AND SECT.CODE_STE = ".$siSectorisationJoinValue."
                        LEFT JOIN CODECOMP CDC ON SM.CODE_COMP = CDC.CODE_CDC AND CDC.CODE_STE = ".$this->getImputationSectoJoinValue('CDCSECTO', "SM.CODE_STE")."
                        LEFT JOIN SSCPTANA SCA ON SM.SSCPTEANA = SCA.CODE_SCA AND SCA.CODE_STE = ".$this->getImputationSectoJoinValue('SCASECTO', "SM.CODE_STE")."
                        LEFT JOIN CODGEST CGE ON SM.CODGES = CGE.CODE_AFF AND CGE.CODE_SI = SM.SECTIMP AND CGE.CODE_STE = ".$siSectorisationJoinValue."
                        LEFT JOIN SSITESTO STO ON SM.SITE = STO.SITE
                        WHERE 1=1 ".Roles::getClausePerimetreSociete('SM.CODE_STE', $arrayReq)."
                    ) AS SM WHERE 1=1 ";

        $parameters =  (new RepoService())->buildQuery($post, $requete, $arrayReq, 'SMOUVEME');

        $paginatorGestion = new PaginatorGestion();
        $paginatorGestion->injecterSqlCount($requete, $parameters, $arrayReq, $this->pdo);

        return $this->fetchAssocAll($requete, $arrayReq);
    }


    /**
     * @param int $noMvt
     * @return array<string,mixed>|null
     */
    public function findFromNoMvt(int $noMvt): ?array
    {
        $siSectorisationJoinValue = $this->getImputationSectoJoinValue('SISECTOR', "SM.CODE_STE");

        $requete = "SELECT DISTINCT
                        SM.TYPE_MVT AS TYPE_MVT,
                        SM.TYPE_ENT AS TYPE_ENT,
                        SM.NO_ENT AS NO_ENT,
                        SM.NO_LIG AS NO_LIG,
                        SA.SSFAM AS SSFAM,
                        SI.LIBELLE AS SI_LIBELLE,
                        SM.SECTIMP AS SECTIMP,
                        CG.LIB_GES AS CG_LIBELLE,
                        SM.CODGES AS CODGES,
                        SM.TIERS AS TIERS,
                        CC.LIBELLE AS CDC_LIBELLE,
                        SM.CODE_COMP AS CODE_COMP,
                        SM.QTE_MVT AS QTE_MVT,
                        SM.QTEMVTCOR AS QTEMVTCOR,
                        SM.PU AS PU,
                        SM.PUNMVTCOR AS PUNMVTCOR,
                        SM.DEVISE AS DEVISE,
                        SA.UNITE_ACH AS UNITE_ACH,
                        SM.SSCPTEANA AS SSCPTEANA,
                        SCA.LIBELLE AS SCA_LIBELLE,
                        T.RS AS TIERS_LIBELLE,
                        SSF.DESIGNAT AS SSF_DESIGNAT
                    FROM SMOUVEME SM
                    LEFT JOIN SARTICLE SA ON SM.CODE_ART = SA.CODE_ART
                    LEFT JOIN SECTIMPU SI ON SM.SECTIMP = SI.CODE_SI AND SI.CODE_STE = ".$siSectorisationJoinValue."
                    LEFT JOIN SSCPTANA SCA ON SM.SSCPTEANA = SCA.CODE_SCA AND SCA.CODE_STE = ".$this->getImputationSectoJoinValue('SCASECTO', "SM.CODE_STE")."
                    LEFT JOIN CODGEST CG ON SM.CODGES = CG.CODE_AFF AND CG.CODE_SI = SM.SECTIMP AND CG.CODE_STE = ".$siSectorisationJoinValue."
                    LEFT JOIN CODECOMP CC ON SM.CODE_COMP = CC.CODE_CDC AND CC.CODE_STE = ".$this->getImputationSectoJoinValue('CDCSECTO', "SM.CODE_STE")."
                    LEFT JOIN TIERS T ON SM.TIERS = T.CODE
                    LEFT JOIN SSFAMILL SSF ON SA.SSFAM = SSF.CODE_SFA
                    WHERE SM.NO_MVT=:noMvt";

        return $this->fetchAssocOne($requete, [':noMvt' => $noMvt]);
    }

    /**
     * @param array<string,string> $post
     * @return array<int,array<string,string|int>>
     * @throws Exception
     */
    public function listMouvementsExport(array $post, string $listeSelect): array
    {
        $arrayReq = [];
        $req = "SELECT DISTINCT " . $listeSelect . " FROM SMOUVEME SM with (nolock) WHERE 1=1 "
            .Roles::getClausePerimetreSociete('SM.CODE_STE', $arrayReq);

        (new RepoService())->buildQuery($post, $req, $arrayReq, 'SMOUVEME');

        return $this->fetchAssocAll($req, $arrayReq);
    }

    /**
     * @param TypeEnteteEnum $typeEntete1
     * @param TypeEnteteEnum $typeEntete2
     * @param string $codeArt
     * @param string $site
     * @return array<string,mixed>|null
     */
    public function getLastMouvement(TypeEnteteEnum $typeEntete1, TypeEnteteEnum $typeEntete2, string $codeArt, string $site): ?array
    {
        $requete = "SELECT TOP 1
                        NO_ENT,
                        DTE_MVT,
                        SUM(QTE_MVT) AS SUM_QTE
                    FROM SMOUVEME
                    WHERE (TYPE_ENT=:typeEntete1 OR TYPE_ENT=:typeEntete2) AND CODE_ART=:codeArt AND SITE=:site
                    GROUP BY NO_ENT, DTE_MVT
                    ORDER BY DTE_MVT DESC;";

        $arrayReq = [
            ':typeEntete1' => $typeEntete1->name,
            ':typeEntete2' => $typeEntete2->name,
            ':codeArt' => $codeArt,
            ':site' => $site
        ];

        $requete = $this->pdo->prepare($requete);
        $requete->execute($arrayReq);
        $result = $requete->fetchAll($this->pdo::FETCH_ASSOC);

        if (empty($result)) {
            return null;
        }

        return $result[0];
    }
}
