<?php

namespace Entity\Model;

use Helpers\Outil\Sql;
use Helpers\QueryBuilder\QueryBuilder;
use Helpers\Trad\ITrad;

class Docatt extends QueryBuilder
{
    protected string $table = 'DOC_ATT with (nolock)';
    protected string $primaryKey = '';
    protected array $primKey = ['NO_DA', 'COD_ENR', 'NO_ORDRE'];

    public function getArchitecture(ITrad $trad)
    {
        return [
            'NO_ORDRE'              => ['nomChamp'  => $trad->t('Numéro d\'ordre')],
            'TYPE_PJ'               => ['nomChamp'  => $trad->t('Type de PJ')],
            'TITRE'                 => ['nomChamp'  => $trad->t('Titre du document')],
            'COPIE'                 => ['nomChamp'  => $trad->t('Copie ?'), 'type' => 'RADIO'],
            'DT_PARUT'              => ['nomChamp'  => $trad->t('Date de parution'), 'type' => 'DATE'],
            'DT_VALID'              => ['nomChamp'  => $trad->t('Date de validité'), 'type' => 'DATE'],
            'COD_ENR'               => ['nomChamp'  => $trad->t('Code enregistrement')],
            'AUTEUR'                => ['nomChamp'  => $trad->t('Auteur')],
            'CENTRE'                => ['nomChamp'  => $trad->t('Centre')],
            'NOM_ORI'               => ['nomChamp'  => $trad->t('Nom original du fichier')],
            'TYPE_FT'               => ['nomChamp'  => $trad->t('Type de document rattaché')],
            'CODE_FOU'              => ['nomChamp'  => $trad->t('Code fournisseur')],
            'NPRELANCE'             => ['nomChamp'  => $trad->t('Ne pas relancer ?'), 'type' => 'RADIO'],
            'PJ_CDE'                => ['nomChamp'  => $trad->t('Ajoutée PJ des commandes ?'), 'type' => 'RADIO'],
            'GERE_PAR_PARTENAIRE'   => ['nomChamp'  => $trad->t('Géré par un partenaire ?'), 'type' => 'RADIO'],
            'DOC_INUTILE'           => ['nomChamp'  => $trad->t('Document inutile ?'), 'type' => 'RADIO'],
            'CODE_CAT'              => ['nomChamp'  => $trad->t('Code de la catégorie')],
            'DTE_DERNREL'           => ['nomChamp'  => $trad->t('Date de dernière relance'), 'type' => 'DATE'],
            'CONTRATCDE'            => ['nomChamp'  => $trad->t('Contrat de commande'), 'type' => 'RADIO'],
        ];
    }

    /**
     * Insert a DocAtt and create an Export Event (if the App parameters allow it)
     * This function should always be used when creating a DocAtt for a Fourniss
     * @param array<mixed> $typeDocCanva Entity LstDoc
     * @param array<mixed> $docAtt Entity DocAtt
     * @return void
     */
    public function insertForFourniss(array $typeDocCanva, array $docAtt) :void
    {
        $inTransac = $this->pdo->inTransaction();
        if (!$inTransac) {
            $this->pdo->beginTransaction();
        }

        // $docAtt = $this->insertOutput($docAtt);
        if (empty($docAtt['NO_ORDRE'])) {
            $stmnt = $this->pdo->prepare(
                "SELECT COALESCE( MAX(NO_ORDRE) + 1, 1) as NO_ORDRE
                FROM DOC_ATT
                WHERE COD_ENR = :parentId AND NO_DA = :noDa"
            );
            $stmnt->execute([
                ':parentId' => $docAtt['COD_ENR'],
                ':noDa' => $docAtt['NO_DA']
            ]);
            $docAtt['NO_ORDRE'] = $stmnt->fetch()['NO_ORDRE'];
        }
        $this->insert($docAtt);

        // Case : Evenement interface export active (and Document is new)
        if ((new Paravrac($this->pdo))->getFlag('INT_EVT', 'DOC_ATT')
            && (new ParamDico($this->pdo))->isTypeDocExportable($typeDocCanva)
        ) {
            // Create Evenement interface export
            (new XtEve($this->pdo))->insertDocAttEvent(
                $docAtt['COD_ENR'],
                $docAtt['NO_ORDRE']
            );
        }

        if (!$inTransac) {
            $this->pdo->commit();
        }
    }

    /**
     * @param array<mixed> $entity
     * @return void
     */
    protected function setAutoincrementExpr(array &$entity) :void
    {
        if (empty($entity['NO_ORDRE'])) {
            $entity['NO_ORDRE'] = [
                'expr' =>
                    "SELECT COALESCE( MAX(NO_ORDRE) + 1, 1)
                    FROM DOC_ATT
                    WHERE COD_ENR = :parentId AND NO_DA = :noDa",
                'param' => [
                    ':parentId' => $entity['COD_ENR'],
                    ':noDa' => $entity['NO_DA']
                ],
            ];
        }
    }

    // TODO : factorize with other QueryBuilder
    // Cascade delete MEMOS
    public function delete($id, bool $transaction = true)
    {
        
        $param = [];
        $this->pdo->prepare(
            "DELETE MEMOS FROM MEMOS 
            JOIN DOC_ATT ON DOC_ATT.NM_COMM = MEMOS.NODEMEMO
            WHERE " . $this->getDeleteWhere($id, $param)
        )
        ->execute($param);

        $res = parent::delete($id);

        return $res;
    }

    /**
     * @param array<mixed> $entity
     */
    public static function getCodeEnr(string $type, array $entity) :string
    {
        return match ($type) {
            'SSTOCKLO' => str_pad($entity['SITE'], 7, ' ') . $entity['CODE_ART'],
            'ARTFOURN' => str_pad($entity['CODE_ART'], 13, ' ') . $entity['FOU'],
            'ARTGF' => str_pad($entity['CODE_ART'], 13, ' ') . $entity['CODE_GF'],
            // TODO : ...
            default => throw new \Exception('Invalid type "'.$type.'"'),
        };
    }

    /**
     * Decode doc id into its component (see Docatt:getCodeEnr)
     * @return array<mixed>
     */
    public static function decodeCodeEnr(string $type, string $docId)
    {
        return match ($type) {
            // TODO : reverse 'SSTOCKLO' => str_pad($entity['SITE'], 7, ' ') . $entity['CODE_ART'],
            'ARTFOURN' => [
                'CODE_ART' => trim(substr($docId, 0, 13)),
                'FOU' => substr($docId, 13),
            ],
            'ARTGF' => [
                'CODE_ART' => trim(substr($docId, 0, 13)),
                'CODE_GF' => substr($docId, 13),
            ],
            // TODO : ...
            default => throw new \Exception('Invalid type "'.$type.'"'),
        };
    }
}
