<?php

namespace Modules\Consultation\Repository;

use Entity\Model\AoFour;
use Helpers\QueryBuilder\AbsRepository;

class AoEvent extends AbsRepository
{
    
    public function rqInsertEventAO(string $id, string $codeEvent, string $message = '', string $codeFou = '', string $typeFG = '', int $idQr = 0) : void
    {
        $req = "INSERT INTO AO_EVENT (NO_AO, NUM_ORD, DTE, HEURE, UTIL, CODE, COMMENTAIRE, CODE_FOU, TYPE_FG, ID_QR) VALUES (:id, (select
                case when NUM_ORDRE is NULL then '1' else NUM_ORDRE+1 end as NUM_ORDRE
                from (select MAX(NUM_ORD) NUM_ORDRE from AO_EVENT with (nolock) where NO_AO='$id') test),
                :date, :heure, :user, :codeEvent, :message, :codeFou, :typeFG, :idQr)";
        
        $arrayReq = [
            ':id' => $id,
            ':date' => date('Ymd'),
            ':heure' => date('His'),
            ':user' => $_SESSION["Session_Login"] ?? '',
            ':codeEvent' => $codeEvent,
            ':message' => $message,
            ':codeFou' => $codeFou,
            ':typeFG' => $typeFG,
            ':idQr' => (int) $idQr,
        ];
        
        $data = $this->pdo->prepare($req);
        $data->execute($arrayReq);
        
        /* Si on envoi la consultation ou l'accord de confidentialité est remplis (ACS) alors on met a jours AO_FOUR.EVE_IMP avec le code evenement */
        if (($codeEvent == 'ENV' || $codeEvent == 'ACR') && $codeFou) {
            $idEvent = $this->getLastOrder($id, $codeEvent);
            
            $aoDaRep = new AoFour($this->pdo);
            $aoDaRep->update([
                'EVE_IMP' => $idEvent['MAX_NUM_ORDRE'],
            ], ['NO_AO' => $id, 'CODE_FOU' => $codeFou, 'TYPE_FG' => $typeFG]);
        }
    }
    
    /**
     * @return array<mixed>
     */
    public function getLastOrder(string $idAo, ?string $codeEvent = null) : ?array
    {
        $req = "select MAX(NUM_ORD) MAX_NUM_ORDRE from AO_EVENT with (nolock) where NO_AO = :idAo ";
        $arrayReq[':idAo'] = $idAo;
        
        if ($codeEvent) {
            $req .= " and CODE = :codeEve ";
            
            $arrayReq[':codeEve'] = $codeEvent;
        }
        
        $data = $this->pdo->prepare($req);
        $data->execute($arrayReq);
        
        return $data->fetch();
    }

    /**
    * @return array<mixed>
    */
    public function getLastDate(string $idAo, string $idFrs, string $typeFG, string $codeEvent, ?string $commentaire = null) : array
    {
        $req = "select MAX(CONCAT(DTE, HEURE)) AS DTE from AO_EVENT with (nolock) where NO_AO = :idAo and CODE = :codeEve and CODE_FOU = :codeFou and TYPE_FG = :typeFG ";
        
        $arrayReq[':idAo'] = $idAo;
        $arrayReq[':codeEve'] = $codeEvent;
        $arrayReq[':codeFou'] = $idFrs;
        $arrayReq[':typeFG'] = $typeFG;
        
        if ($commentaire) {
            $req .= " and COMMENTAIRE = :commentaire";
            
            $arrayReq[':commentaire'] = $commentaire;
        }
        
        $data = $this->pdo->prepare($req);
        $data->execute($arrayReq);
        
        return $data->fetch();
    }
    
    /**
    * @return array<mixed>
    */
    public function getNameCreate(string $id) : array
    {
        $req = "select UTIL, NOM from AO_EVENT with(nolock)
                left join HASTUTIL with(nolock) on HASTUTIL.CODE = UTIL 
                where NO_AO=:id and AO_EVENT.CODE=:codeEve";
        
        $arrayReq = [
            ':id' => $id,
            ':codeEve' => 'CRE',
        ];
        
        $data = $this->pdo->prepare($req);
        $data->execute($arrayReq);
        
        return $data->fetch();
    }
    
    /**
     * @return string[][]
     */
    public function listEventType()
    {
        $param = [];
        return $this->fetchAssocAll(
            "SELECT *, " . $this->selectTrad('SUIAODAT.LIBELLE', 'label_trad') . " 
            FROM SUIAODAT with(nolock)
            " . $this->joinTrad('SUIAODAT.LIBELLE', $param),
            $param
        );
    }

    /**
     * @param array<mixed> $param
     */
    private function getMainRequest(array &$param) :string
    {
        return "SELECT 
                AO_EVENT.*,
                Auteur.NOM as Auteur_NOM,
                Signataire.NOM as Signataire_NOM,
                " . $this->selectTrad('SUIAODAT.LIBELLE') . ",
                FOURNISS.RS,
                ISNULL(origin.QUEST, AO_FOUR_QR.QUEST) QUEST,
                ISNULL(origin.REP, AO_FOUR_QR.REP) REP
            FROM AO_EVENT with (nolock) 
            LEFT JOIN SUIAODAT with (nolock) ON SUIAODAT.CODE_SAO = AO_EVENT.CODE
            " . $this->joinTrad('SUIAODAT.LIBELLE', $param) . "
            left join HASTUTIL as Auteur with (nolock) on Auteur.CODE = AO_EVENT.UTIL
            left join HASTUTIL as Signataire with (nolock) on Signataire.CODE = AO_EVENT.SIGNAT
            left join AO_FOUR_QR with (nolock) 
                        on AO_FOUR_QR.NO_AO = AO_EVENT.NO_AO 
                        and AO_FOUR_QR.TYPE_FG = AO_EVENT.TYPE_FG 
                        and AO_FOUR_QR.CODE_FOU = AO_EVENT.CODE_FOU 
                        and AO_FOUR_QR.ID_QR = AO_EVENT.ID_QR
            left join AO_FOUR_QR origin with (nolock) on AO_FOUR_QR.ORIGIN_TYPE_FG = origin.TYPE_FG 
                                                    and AO_FOUR_QR.ORIGIN_CODE_FOU = origin.CODE_FOU 
                                                    and AO_FOUR_QR.ORIGIN_ID_QR = origin.ID_QR
                                                    and AO_FOUR_QR.NO_AO = origin.NO_AO
            left join FOURNISS with (nolock) 
                on FOURNISS.CODE = AO_EVENT.CODE_FOU
            where AO_EVENT.NO_AO = :idAO";
    }

    /**
    * @param array<string> $post
    * @return array<mixed>
    */
    public function getListeEvent(string $idAO, array $post, ?string $codeFrs = null, ?string $typeFG = null, ?string $idQr = null) : array
    {
        $arrayReq = [];
        $req = $this->getMainRequest($arrayReq);
        $arrayReq += [':idAO' => $idAO];
        
        if (isset($post['filter_HEURE']) && $post['filter_HEURE'] != '') {
            $post['filter_HEURE'] = str_replace(':', '', $post['filter_HEURE']);
        }

        if ($codeFrs && $typeFG && $idQr) {
            $req .= " and AO_EVENT.CODE_FOU = :codeFrs and AO_EVENT.TYPE_FG = :typeFG and (AO_EVENT.ID_QR = :idQr or AO_EVENT.ID_QR = 0) ";
            $arrayReq[':codeFrs'] = $codeFrs;
            $arrayReq[':typeFG'] = $typeFG;
            $arrayReq[':idQr'] = $idQr;
        }
        
        return $this->fetchAssocAll(
            $this->applyFilter($req, $arrayReq, $post),
            $arrayReq
        );
    }

    /**
    * @param array<string> $post
    */
    public function export(string $idAO, array $post) :\PDOStatement
    {
        $arrayReq = [];
        $req = $this->getMainRequest($arrayReq);
        $arrayReq += [':idAO' => $idAO];
        
        if (isset($post['filter_HEURE']) && $post['filter_HEURE'] != '') {
            $post['filter_HEURE'] = str_replace(':', '', $post['filter_HEURE']);
        }
        
        return $this->createStatement(
            $this->applyFilter($req, $arrayReq, $post),
            $arrayReq
        );
    }
    
    public function rqInsertEvent(
        string $id,
        string $codeEvent,
        string $message = '',
        string $typeFou = '',
        string $fournissId = ''
    ) : void {
        $req = "INSERT INTO AO_EVENT (NO_AO, NUM_ORD, DTE, HEURE, UTIL, CODE, COMMENTAIRE, TYPE_FG, CODE_FOU) 
            VALUES (:id, (
                SELECT COALESCE(MAX(AO_EVENT.NUM_ORD)+1, 1) 
                FROM AO_EVENT with (nolock) 
                WHERE NO_AO = :id_0
            ),:date, :heure, :user, :codeEvent, :message, :TYPE_FG, :CODE_FOU)";
        
        $arrayReq = [
            ':id' => $id,
            ':id_0' => $id,
            ':date' => date('Ymd'),
            ':heure' => date('His'),
            ':user' => $_SESSION["Session_Login"],
            ':codeEvent' => $codeEvent,
            ':message' => $message,
            ':TYPE_FG' => $typeFou,
            ':CODE_FOU' => $fournissId,
        ];
        
        $data = $this->pdo->prepare($req);
        $data->execute($arrayReq);
    }

    public function insertEntity(
        string $commandeId,
        string $commandeAvnId,
        string $code,
        string $userCode,
        string $memoId
    ) :void {
        $param = [
            'NO_CDE' => $commandeId,
            'AVNT' => $commandeAvnId,
            'DTE' => date('Ymd'),
            'HEURE' => date('His'),
            'CODE' => $code,
            'UTIL' => $userCode,
            'NM_COMME' => $memoId,
            'HAPLUS' => 0x54,
        ];
        $req = 'INSERT INTO CA_EVENT('
            . implode(
                ',',
                array_merge(
                    array_keys($param),
                    ['NUM_ORD']
                )
            )
            . ') VALUES ('
            . implode(
                ',',
                array_merge(
                    array_map(function ($k) {
                        return ':' . $k;
                    }, array_keys($param)),
                    ['(SELECT COALESCE(MAX(CA_EVENT.NUM_ORD)+1, 1) 
                        FROM CA_EVENT with (nolock) WHERE NO_CDE=:numCde)']
                )
            )
            . ')';

        $param += [
            'numCde' => $commandeId,
        ];

        $stmt = $this->pdo->prepare($req);
        foreach ($param as $k => $v) {
            $stmt->bindValue($k, $v, is_int($v) ? \PDO::PARAM_INT : \PDO::PARAM_STR);
        }
        $stmt->execute();
    }
}
