<?php

namespace Modules\Signature\Repository;

use Entity\Model\Hastutil;
use Helpers\Outil\Roles;
use Helpers\QueryBuilder\AbsRepository;

class BaPSignRepository extends AbsRepository
{
    private int $nivConf;

    private function getNivConf(): int
    {
        if ($_SESSION["Session_Login"] == 'OXAUSER') {
            $this->nivConf = 99;
        } else {
            /** @phpstan-ignore-next-line */
            if (!isset($this->nivConf)) {
                $hastutil      = new Hastutil($this->pdo);
                $infoUser      = $hastutil->find($_SESSION["Session_Login"]);
                $this->nivConf = (int) $infoUser['NIV_CONF'];
            }
        }
        return $this->nivConf;
    }

    /**
     * Load:
     * - Facture.Fournisseur
     * - Facture.Societe
     * @param string|null $userId
     * @param array<mixed> $post
     * @return array<mixed>[]
     */
    public function listToBeSign($userId = null, array $post = []): array
    {
        $req = "SELECT 
                    FAC_ENT.NUM_FACT as 'NUM_FACT',
                    FAC_ENT.TYPE as 'TYPE',
                    FAC_ENT.DEVISE as 'DEVISE',
                    FAC_ENT.FACT_FOU as 'FACT_FOU',
                    FAC_ENT.DATE_ENR as 'DATE_ENR',
                    FAC_ENT.DATE_FAFO as 'DATE_FAFO',
                    FAC_ENT.TOTAL_HT as 'TOTAL_HT',
                    FAC_ENT.TOTAL_TTC as 'TOTAL_TTC',
                    FAC_ENT.FIC_LAD as 'FIC_LAD',
                    FAC_ENT.LIB_COMPT,
                    FAC_ENT.TYPE_URL_LAD as 'TYPE_URL_LAD',
                    FAC_ENT.AFF_TMP as 'AFF_TMP',
                    FAC_ENT.LITIGE as 'LITIGE',
                    FAC_ENT.BON_A_PAY,
                    FAC_ENT.ACOMPTE,
                    FOURNISS.CODE as 'CODE',
                    FOURNISS.CODE as 'CODE_FOUR',
                    FOURNISS.RS as 'RS',
                    SOCIETE.CODE_STE as 'CODE_STE',
                    SOCIETE.RAIS_SOC as 'RAIS_SOC',
                    SIG_BAP.SIGNAT,
                    (select COUNT(*) from FAC_PIJO with (nolock) where NO_FAC = FAC_ENT.NUM_FACT) NB_PIJO

                FROM SIG_BAP with(nolock)
                LEFT JOIN FAC_ENT with(nolock) ON SIG_BAP.NO_FAC = FAC_ENT.NUM_FACT
                LEFT JOIN FOURNISS with(nolock) ON FOURNISS.CODE = FAC_ENT.CODE_FOUR
                JOIN SOCIETE with(nolock) ON SOCIETE.CODE_STE = FAC_ENT.CODE_STE
                WHERE SIG_BAP.SIGNAT = :userId 
                AND SIG_BAP.SIGNABLE = 0x54 
                AND SIG_BAP.BAP_BAS = 0x54 
                AND FAC_ENT.ATT_SIG = 0x54
                AND FAC_ENT.ANNULE = 'F'
                AND FAC_ENT.REFUSEE_FE = 'F'
                AND SIG_BAP.INFORME	= 0x46
                " . Roles::getClauseSocieteOuvert('SOCIETE') . "
                AND NOT EXISTS (
                    SELECT CA_ENTET.NO_CDE
                    FROM FAC_LIG with (nolock)
                    JOIN CA_ENTET with (nolock) ON CA_ENTET.NO_CDE = FAC_LIG.NUM_CDE
                    JOIN TYPDOC with (nolock) 
                        ON CA_ENTET.TYP_DOC = TYPDOC.TYPE 
                        AND TYPDOC.NIV_CONF > :nivConf
                    WHERE FAC_LIG.NUM_FACT = FAC_ENT.NUM_FACT
                )";

        $param = [
            ':userId'  => $userId ?? $_SESSION["Session_Login"],
            ':nivConf' => $this->getNivConf(),
        ];

        $req .= Roles::getClausePerimetreSociete('FAC_ENT.CODE_STE', $param);

        if (isset($post['filter_Fourniss']) && $post['filter_Fourniss'] != '') {
            $req   .= ' and UPPER(FOURNISS.CODE) = :filter_Fourniss_0 '
                . ' OR UPPER(FOURNISS.RS) = :filter_Fourniss_1 ';
            $param += [
                'filter_Fourniss_0' => $post['filter_Fourniss'],
                'filter_Fourniss_1' => $post['filter_Fourniss'],
            ];
            unset($post['filter_Fourniss']);
        }

        $oldPost = [];

        if (isset($post['filter_Societe']) && $post['filter_Societe'] != '') {
            $req   .= ' and UPPER(SOCIETE.CODE_STE) = :filter_Societe_0 '
                . ' OR UPPER(SOCIETE.RAIS_SOC) = :filter_Societe_1 ';
            $param += [
                'filter_Societe_0' => $post['filter_Societe'],
                'filter_Societe_1' => $post['filter_Societe'],
            ];
            $oldPost['filter_Fourniss']  = $post['filter_Fourniss'];
            unset($post['filter_Societe']);
        }

        // Filtrage sur les types de facture suite implémentation facture d'acompte
        if (isset($post['filter_TYPE']) && $post['filter_TYPE'] != '') {
            if (\in_array($post['filter_TYPE'], ['F', 'A'])) {
                $req               .= " AND FAC_ENT.TYPE = :TYPE AND FAC_ENT.ACOMPTE = 0x46 ";
                $arrayReq[':TYPE']  = $post['TYPE'];
            } else {
                // TYPE == 'C'
                $req .= " AND FAC_ENT.TYPE = 'F' AND FAC_ENT.ACOMPTE = 0x54 ";
            }
            $oldPost['filter_Societe'] = $post['filter_Societe'];
            unset($post['filter_TYPE']);
        }

        $whereArray    = \Helpers\Filter\FilterTable::splitFilter($post, 0, 0, 1);
        $filtreAvance  = new \Helpers\Filter\FiltreAvance\Generator($post);
        $req          .= $filtreAvance->generateSql(1);
        $filtreAvance->pushArray($param);

        if (count($whereArray) > 0) {
            $req .= $whereArray[0] . ' ' . $whereArray['tri'];

            if (count($whereArray[1]) != 0) {
                $param = array_merge($param, $whereArray[1]);
            }
        }

        $post += $oldPost;

        $paginatorGestion = new \Helpers\Pagination\PaginatorGestion();
        $paginatorGestion->injecterSqlCount($req, $post, $param, $this->pdo);

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

    /**
     * signataireAttendu
     *
     * @param  int $bap
     * @return array<mixed>
     */
    public function signataireAttendu(int $bap)
    {
        $req = "select * from SIG_BAP with (nolock)
                left join HASTUTIL with (nolock) on HASTUTIL.CODE = SIG_BAP.SIGNAT
                where NO_FAC = :bap";

        $arrayReq[':bap'] = $bap;

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

    /**
     * @param string $code
     * @return array<mixed> $array
     */
    public function listeSignat($code)
    {
        $req = "SELECT * FROM SIG_BAP  WITH (NOLOCK) 
                LEFT JOIN HASTUTIL  WITH (NOLOCK) ON HASTUTIL.CODE = SIG_BAP.SIGNAT
                WHERE NO_FAC = :value
                ORDER BY ORDRE";

        $arrayReq[':value'] = $code;

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

    /**
     *
     * @param  int $numFac
     * @return array<mixed>
     */
    public function getCommentaireSignataire(int $numFac)
    {
        $req = "select HASTUTIL.NOM, HASTUTIL.CODE, CONTMEMO
                from FA_EVENT with (nolock)
                left join MEMOS with (nolock) on MEMOS.NODEMEMO = FA_EVENT.NM_COMME
                left join HASTUTIL with (nolock) on HASTUTIL.CODE = FA_EVENT.UTIL
                where FA_EVENT.CODE_EVE = 'SIB' AND NUM_FACT = :numFac and CONTMEMO != ''
                order by NUM_ORD";

        $arrayReq[':numFac'] = $numFac;

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