<?php

namespace Modules\DemandeAchat\Controller;

use Entity\Model\Acccadre;
use Entity\Model\Contfour;
use Entity\Model\ContGF;
use Entity\Model\CtcCtr;
use Entity\Model\Fourniss;
use Entity\Model\TyEvtStp;
use GuzzleHttp\Psr7\Response;
use Helpers\ExportTo\Outils;
use Helpers\Outil\Roles;
use Modules\DemandeAchat\Outil\FormArray;
use Modules\DemandeAchat\Service\GestionDemandeAchatService;
use Modules\DemandeAchat\Service\ModificationDemandeAchatService;
use Modules\DemandeAchat\Validator\CreationValidator;
use Modules\GlobalApplication\Repository\LicenceOxalys;
use Modules\TermeDePaiement\Service\TermeDePaiementService;
use Skeleton\Controller\Controller;
use Helpers\Ariane\Ariane;
use Helpers\Outil\Sql;
use Helpers\Trad\Trad;
use Helpers\Trad\ITrad;
use Entity\Model\Langues;
use Entity\Model\Pays;
use Entity\Model\TpEnt;
use Entity\Model\TpEvt;
use Entity\Model\DaEntet;
use Helpers\CaracCompl\CaracCompl;
use Helpers\ChampsSupplementaire\ChampSupp;
use Modules\DemandeAchat\Repository\DemandeAchat;
use Modules\Ajax\Repository\Listes;
use Modules\Consultation\Repository\Reponse;
use Modules\DemandeAchat\Repository\Clause;
use Modules\DemandeAchat\Service\CreationDemandeAchatService;
use SebastianBergmann\Type\FalseType;

class ModificationDemandeAchatController extends Controller
{
    private ModificationDemandeAchatService $service;
    private DemandeAchat $repository;
    private Listes $listes;
    /**
     * trad
     *
     * @var ITrad
     */
    private $trad;

    public function init(): void
    {
        $this->service = new ModificationDemandeAchatService($this->pdo);

        $this->repository = new DemandeAchat(
            $this->pdo,
        );

        $this->listes = new Listes(
            $this->pdo
        );

        $this->trad = $this->getTranslationService();
    }

    public function indexAction(
        LicenceOxalys $licenceOxalys,
        TpEnt $tpEnt,
        TpEvt $tpEvt,
        TyEvtStp $tyEvtStp,
        DaEntet $daEntet,
        DemandeAchat $demandeAchatRepo,
        Clause $clauseRepo,
        TermeDePaiementService $termeDePaiementService,
        CreationDemandeAchatService $creationDemandeAchatService
    ): string {
        $post              = $this->request->getParsedBody();
        $purchaseRequestId = $this->request->getAttribute('idDA');
        $mode              = $this->request->getAttribute('mode');
        $onglet            = $this->request->getAttribute('onglet');
        $trad              = $this->getTranslationService();
        $queryParams       = $this->request->getQueryParams();

        // On va chercher les infos de la DA en BDD
        $demandeAchat = $this->repository
            ->demandeAchatEntete($purchaseRequestId);
        if ($demandeAchat) {
            $demandeAchat['NOCDISDA'] = sql::boolSql($demandeAchat['NOCDISDA']);
        }

        $newLine    = [];
        $lineParams = [];
        $lineCs     = [];
        $param      = [];

        if ($mode == 'Creation') {
            // init de la première ligne de la DA et de l'entête de DA
            $this->service
                ->initNewLineAndParams($purchaseRequestId, $newLine, $lineParams, $lineCs);
            $this->service
                ->initHeadingAndParams($demandeAchat, $param);
        } else {
            // si on n'est pas en modification d'une DA nouvellement créée, on veut récupérer les paramètres sans changer les valeurs de la DA
            $tmpPurchaseRequest = $demandeAchat;
            $this->service
                ->initHeadingAndParams($tmpPurchaseRequest, $param);
        }

        /* Listes des lignes et des clauses */
        $listeLigne  = $this->repository
            ->listeLigneDemandeAchat($purchaseRequestId);
        $listeClause = $clauseRepo
            ->listeClause($purchaseRequestId);

        /* VALUE SELECT */
        $formArray = FormArray::getFormArrays(
            $this->getTranslationService(),
        );

        $transport = $creationDemandeAchatService
            ->getTransportOptions();

        $listeCondPaie = $this->listes
            ->ConditionPaiement($post);
        foreach ($listeCondPaie as $value) {
            $condPaie[$value['CODE_CDP']] = $value['LIBELLE'];
        }

        $listeModePaie = $this->listes
            ->modePaiement($post);
        foreach ($listeModePaie as $value) {
            $modePaie[$value['CODE_MDP']] = $value['LIBELLE'];
        }

        $listeModeLiv = $this->listes
            ->modeLivraison($post);
        foreach ($listeModeLiv as $value) {
            $modeLiv[$value['CODE_MDL']] = $value['LIBELLE'];
        }

        // termes de paiement DA
        $purchaseRequest = $demandeAchatRepo->demandeAchatEntete($purchaseRequestId);

        $devise   = $daEntet->find(['NO_DA' => $purchaseRequestId], ['DEVISE'])['DEVISE'] ?? '';
        $daStatut = $demandeAchatRepo->getDaStatut($purchaseRequestId);
        // On vérifie que la DA n'est ni terminé, ni refusé
        $canEdit       = !in_array($daStatut['ETAT'] ?? '', ['R', 'T']);
        $notValidateDa = !in_array($daStatut['ETAT'] ?? '', ['ao_pending', 'consult_terminer', 'a_commander', 'T', 'R']);
        $titreTP       = Trad::strBuild(
            $trad->t('Liste des termes de paiement de la demande d\'achat : @1@'),
            $purchaseRequestId
        );

        $nbrFourn = $demandeAchatRepo->nbrFournisseur($purchaseRequestId);
        $NO_DA    = 'DA_ENTET';

        if ($licenceOxalys->termPaieActive()) {
            $strategy = $termeDePaiementService->getStrategy('DemandeAchat', '');

            $tps                = $tpEnt->findAll(['NUM_CDE' => $purchaseRequestId, 'TYPEOBJ' => 'DA_ENTET']);
            $evts               = $tpEvt->findAll(['NUM_CDE' => $purchaseRequestId, 'TYPEOBJ' => 'DA_ENTET']);
            if (count($evts) > 0) {
                $mapTypeEvent = array_column(
                    $tyEvtStp->findAll([
                        'CODE_EVT' => array_column($evts, 'EVENEMENT'),
                    ]),
                    null,
                    'CODE_EVT'
                );
                foreach ($evts as &$evt) {
                    $type = $mapTypeEvent[$evt['EVENEMENT']];
                    if (!empty($type['LIB_EVT'])) {
                        $evt['LIB_EVT'] = $trad->t($type['LIB_EVT']); // TODO: shoud be done in SQL
                    }
                }
            }
            $verifPourcTpGlobal = $strategy->verifPourcTP($purchaseRequestId, $tps, $evts);
        }

        $titre    = $this->trad->t('Modification demande d\'achat');
        $titreH2  = $this->trad->t('Modification de la demande d\'achat') . $this->trad->colon() . $purchaseRequestId;
        $texteBtn = $this->trad->t('Modification');

        Ariane::generate(1, $titre);
        if (!$demandeAchat) {
            $demandeAchat = [];
        }
        $cc      = new CaracCompl($this->pdo, $newLine['CODE_ART'] ?? '', $newLine['SSFAM'] ?? '');
        $listeCC = $cc->getCCDocc('DA', $purchaseRequestId, $newLine['NO_PO'] ?? 0, '0');

        return $this->renderer->render('@DemandeAchat/Modification/edit', [
            'menuActive' => 'CollecteBesoins',
            'menuLeft' => 'GestionDemandeAchat',
            'idDA' => $purchaseRequestId,
            'da' => array_merge($demandeAchat, $post),
            'ligneDA' => $listeLigne ?? [],
            'newLine' => $newLine,
            'initCC' => false,
            'CC_typeDoc' => 'DA',
            'CC_idDoc' => $purchaseRequestId,
            'CC_idLigne' => $newLine['NO_PO'] ?? 0,
            'listeCC' => $listeCC,
            'ligneClause' => $listeClause,
            'param' => $param,
            'lineParam' => $lineParams,
            'lineCs' => $lineCs,
            'idLigneCS' => ChampSupp::autoCompletCodeEnr($purchaseRequestId, $newLine['NO_PO'] ?? '0', 'DA_LIGNE'),
            'onglet' => $onglet,
            'mode' => $mode,
            'h1' => $this->trad->t('Demandes d\'achat'),
            'titreH2' => $titreH2,
            'texteBtn' => $texteBtn,
            'ongletFicheDA' => true,
            'tabPays' => $this->_getCountryTab(),
            'tabLangues' => $creationDemandeAchatService->getLanguages(),
            'tabTransport' => $transport,
            'tabCondPaie' => $condPaie ?? [],
            'tabModePaie' => $modePaie ?? [],
            'tabModeLiv' => $modeLiv ?? [],
            'typeChiffExec' => $formArray['typeChiffExec'],
            'tabTypeMarchePublic' => $formArray['tabTypeMarchePublic'],
            'tabPeriodicite' => $formArray['tabPeriodicite'],
            'tabPeriode' => $formArray['tabPeriode'],
            'tabJoursAppli' => $formArray['tabJoursAppli'],
            'tabTypeDate' => $formArray['tabTypeDate'],
            'ModeModif' => $mode != 'Creation', // pour la modification des CS non modifiables
            'NO_DA' => $NO_DA,
            'post' => $post,
            'tps' => $tps ?? [],
            'titreTP' => $titreTP,
            'devise' => $devise,
            'titre' => $titre,
            'nbrFourn' => $nbrFourn ?? 0,
            'daEntet' => $purchaseRequest ?? [],
            'canEdit' => $canEdit,
            'notValidateDa' => $notValidateDa,
            'verifPourcTp' => $verifPourcTpGlobal ?? [],
            'queryParams' => $queryParams,
            'licenceOxalys' => $licenceOxalys,
            'hasTp' => (bool) $tpEnt->find(['NUM_CDE' => $purchaseRequestId, 'TYPEOBJ' => 'DA_ENTET'])
        ]);
    }

    /**
     * ajaxEditFrameworkAgreementAction
     *
     * @return Response
     */
    public function ajaxEditFrameworkAgreementAction(): Response
    {
        $post  = $this->request->getParsedBody();
        $param = [];

        $this->service->initAcdAndParams($post, $param);
        $cs = $this->service->initHeadingCs('FOURNISS', $post['FOU'], $post['NO_DA']);

        return $this->createJsonResponse(
            [
                'html' => $this->renderer->render('@DemandeAchat/Modification/_supplier', [
                    'param' => $param,
                    'da' => $post,
                    'tabPays' => $this->_getCountryTab(),
                ]),
                'cs' => $cs,
            ],
            200
        );
    }

    /**
     * ajaxEditSupplierAction
     *
     * @return Response
     */
    public function ajaxEditSupplierAction(): Response
    {
        $post  = $this->request->getParsedBody();
        $param = [];

        $this->service->initSupplierAndParams($post, $param);
        $cs = $this->service->initHeadingCs('FOURNISS', $post['FOU'], $post['NO_DA']);

        return $this->createJsonResponse(
            [
                'html' => $this->renderer->render('@DemandeAchat/Modification/_supplier', [
                    'param' => $param,
                    'da' => $post,
                    'tabPays' => $this->_getCountryTab(),
                ]),
                'cs' => $cs,
            ],
            200
        );
    }

    /**
     * ajaxEditDeliveryAction
     *
     * @return Response
     */
    public function ajaxEditDeliveryAction(): Response
    {
        $post  = $this->request->getParsedBody();
        $param = [];

        $this->service->initDeliveryAndParams($post, $param);
        $cs        = $this->service->initHeadingCs('CENTRE', $post['CTR_LIV'], $post['NO_DA']);
        $transport = (new CreationDemandeAchatService($this->pdo, $this->getTranslationService()))
            ->getTransportOptions();

        return $this->createJsonResponse(
            [
                'html' => $this->renderer->render('@DemandeAchat/Modification/_delivery', [
                    'param' => $param,
                    'da' => $post,
                    'tabTransport' => (new CreationDemandeAchatService($this->pdo, $this->getTranslationService()))
                        ->getTransportOptions(),
                    'tabPays' => $this->_getCountryTab(),
                ]),
                'cs' => $cs,
            ],
            200
        );
    }

    /**
     * ajaxEditRequestorAction
     *
     * @return Response
     */
    public function ajaxEditRequestorAction(): Response
    {
        $post = $this->request->getParsedBody();

        $cs = $this->service->initHeadingCs('HASTUTIL', $post['NO_DEM'], $post['NO_DA']);

        return $this->createJsonResponse(
            [
                'cs' => $cs,
            ],
            200
        );
    }

    public function ajaxValueContactFrsAction(): Response
    {
        $post  = $this->request->getParsedBody();
        $param = [];

        if ($post['IND_FOU'] !== '') {
            $contact = (new Contfour($this->pdo))
                ->find(['CODE_FOU' => $post['FOU'], 'IND_FOU' => $post['IND_FOU']]);

            $post['IND_FOU']  = $contact['IND_FOU'];
            $post['CTCT_FOU'] = $contact['NOM'];

            $post['EMA_CTCT'] = $contact['EMAIL'] ?? '';
            $post['TEL_CTCT'] = $contact['TEL'] ?? '';
            $post['FAX_CTCT'] = $contact['FAX'] ?? '';
            $post['POR_CTCT'] = $contact['TELPORT'] ?? '';
        }

        $param = [];
        // on déclare variable temporaire ici pour ne pas modifier les valeurs du post dans l'init des params
        $purchaseRequest = $post;

        $this->service->initSupplierAndParams($purchaseRequest, $param);
        $cs = $this->service->initHeadingCs('FOURNISS', $post['FOU'], $post['NO_DA']);

        return $this->createJsonResponse(
            [
                'html' => $this->renderer->render('@DemandeAchat/Modification/_supplier', [
                    'param' => $param,
                    'da' => $post,
                    'tabPays' => $this->_getCountryTab(),
                ]),
                'cs' => $cs,
            ],
            200
        );
    }

    public function ajaxValueAdresseFrsAction(): Response
    {
        $post = $this->request->getParsedBody();

        if ($post['COD_ADR_FOU'] !== '') {
            $adresse = (new Listes($this->pdo))
                ->adresseFournisseur([
                    'filter_egal_CODE' => $post['FOU'],
                    'filter_egal_COD_ADR' => $post['COD_ADR_FOU']
                ])[0];

            $post['COD_ADR_FOU'] = $adresse['COD_ADR'];
            $post['ADRFOU']      = $adresse['ADRESSE'];
            $post['VILLEFOU']    = $adresse['VILLE1'];
            $post['CPFOU']       = $adresse['CPOSTAL'];
            $post['PAYSFOU']     = $adresse['CODPAYS'];
        }

        $param           = [];
        $purchaseRequest = $post;

        $this->service->initSupplierAndParams($purchaseRequest, $param);
        $cs = $this->service->initHeadingCs('FOURNISS', $post['FOU'], $post['NO_DA']);

        return $this->createJsonResponse(
            [
                'html' => $this->renderer->render('@DemandeAchat/Modification/_supplier', [
                    'param' => $param,
                    'da' => $post,
                    'tabPays' => $this->_getCountryTab(),
                ]),
                'cs' => $cs,
            ],
            200
        );
    }

    public function ajaxValueContactCentreAction(): Response
    {
        $post = $this->request->getParsedBody();

        if ($post['CTC_IND'] !== '') {
            $contact = (new CtcCtr($this->pdo))
                ->find([
                    'COD_CTR' => $post['CTR_LIV'],
                    'CTC_IND' => $post['CTC_IND']
                ]);

            $post['NMCTC1L'] = $contact['CTC_NOM'];
            $post['FTCTC1L'] = $contact['CTC_FCT'];
            $post['MLCTC1L'] = $contact['CTC_MAIL'];
            $post['TLCTC1L'] = $contact['CTC_TEL'];
            $post['PRCTC1L'] = $contact['CTC_GSM'];
            $post['FXCTC1L'] = $contact['CTC_FAX'];
        } else {
            $post['NMCTC1L'] = '';
            $post['FTCTC1L'] = '';
            $post['MLCTC1L'] = '';
            $post['TLCTC1L'] = '';
            $post['PRCTC1L'] = '';
            $post['FXCTC1L'] = '';
        }
        // TODO voir si on garde ça ?
        if (($post['CTC_IND2'] ?? '') !== '') {
            $contact = (new CtcCtr($this->pdo))
                ->find([
                    'COD_CTR' => $post['CTR_LIV'],
                    'CTC_IND' => $post['CTC_IND2']
                ]);

            $post['NMCTC2L'] = $contact['CTC_NOM'];
            $post['FTCTC2L'] = $contact['CTC_FCT'];
            $post['MLCTC2L'] = $contact['CTC_MAIL'];
            $post['TLCTC2L'] = $contact['CTC_TEL'];
            $post['PRCTC2L'] = $contact['CTC_GSM'];
            $post['FXCTC2L'] = $contact['CTC_FAX'];
        } else {
            $post['NMCTC2L'] = '';
            $post['FTCTC2L'] = '';
            $post['MLCTC2L'] = '';
            $post['TLCTC2L'] = '';
            $post['PRCTC2L'] = '';
            $post['FXCTC2L'] = '';
        }

        $param           = [];
        $purchaseRequest = $post;

        $this->service->initDeliveryAndParams($purchaseRequest, $param);
        $cs = $this->service->initHeadingCs('CENTRE', $post['CTR_LIV'], $post['NO_DA']);

        return $this->createJsonResponse(
            [
                'html' => $this->renderer->render('@DemandeAchat/Modification/_delivery', [
                    'param' => $param,
                    'da' => $post,
                    'tabTransport' => (new CreationDemandeAchatService($this->pdo, $this->getTranslationService()))
                        ->getTransportOptions(),
                    'tabPays' => $this->_getCountryTab(),
                ]),
                'cs' => $cs,
            ],
            200
        );
    }


    public function ajaxValueAdresseLivAction(): Response
    {
        $post = $this->request->getParsedBody();

        if ($post['COD_ADR_LIV'] !== '') {
            $liste   = new Listes($this->pdo);
            $adresse = $liste->adresseCentre(['filter_egal_CODE_CTR' => $post['CTR_LIV'], 'filter_egal_COD_ADR' => $post['COD_ADR_LIV']])[0];

            $post['COD_ADR_LIV'] = $adresse['COD_ADR'];
            $post['ADRLIV']      = $adresse['ADRESSE'];
            $post['VILLELIV']    = $adresse['VILLE1'];
            $post['CPLIV']       = $adresse['CPOSTAL'];
            $post['PAYSLIV']     = $adresse['CODPAYS'];
        }

        $param           = [];
        $purchaseRequest = $post;

        $this->service->initDeliveryAndParams($purchaseRequest, $param);
        $cs = $this->service->initHeadingCs('CENTRE', $post['CTR_LIV'], $post['NO_DA']);

        return $this->createJsonResponse(
            [
                'html' => $this->renderer->render('@DemandeAchat/Modification/_delivery', [
                    'param' => $param,
                    'da' => $post,
                    'tabTransport' => (new CreationDemandeAchatService($this->pdo, $this->getTranslationService()))
                        ->getTransportOptions(),
                    'tabPays' => $this->_getCountryTab(),
                ]),
                'cs' => $cs,
            ],
            200
        );
    }

    public function editMassImputationAction(): string
    {
        $idDa = $this->request->getAttribute('idDa');

        // On va chercher les infos de la DA en BDD
        $demandeAchat = $this->repository
            ->demandeAchatEntete($idDa);
        if ($demandeAchat) {
            $demandeAchat['NOCDISDA'] = sql::boolSql($demandeAchat['NOCDISDA']);
        }

        $listeLigne = $this->repository
            ->listeLigneDemandeAchat($idDa);

        $newLine    = [];
        $lineParams = [];
        $lineCs     = [];

        $this->service
            ->initNewLineAndParams($idDa, $newLine, $lineParams, $lineCs);

        $h2 = $this->trad->t('Modification de la demande d\'achat') . $this->trad->colon() . $idDa;

        return $this->renderer->render('@DemandeAchat/Modification/mass/editMassImputation', [
            'menuActive' => 'CollecteBesoins',
            'menuLeft' => 'DemandeAchat.GestionDemandeAchat.index',
            'origine' => 'modifImput',
            'h2' => $h2,
            'idDa' => $idDa,
            'param' => $lineParams,
            'demandeAchat' => $demandeAchat,
            'ligneCde' => $listeLigne,
        ]);
    }

    public function validationDetailAction()
    {
        $post              = $this->request->getParsedBody();
        $purchaseRequestId = $this->request->getAttribute('idDA');
        $validator         = new CreationValidator(
            $this->pdo,
            $this->trad,
        );

        $validator->validateEditFormEntet($purchaseRequestId, $post);

        if (!$validator->isValid()) {
            if ($validator->getError() != '') {
                return $this->renderer->render('@popup-erreur/ErreurCreation', [
                    'ErreurValid' => $validator->getError(),
                    'titrePopup' => $this->trad->t('Erreur lors de la validation')
                ]);
            }

            if (!isset($post['confirm'])) {
                return $this->createJsonResponse(
                    [
                        'type' => 'confirm',
                        'popupHtml' => $this->renderer->render('@popup-erreur/simpleWarning', [
                            'content' => $validator->getErrorNonBloquant(),
                        ]),
                    ],
                    400
                );
            }
        }

        $update = $this->service->updatePurchaseRequestHeading($purchaseRequestId, $post);

        if ($update) {
            return $this->createJsonResponse(
                [
                    'statut' => 'O',
                    'path' => $this->router->generateUri('DemandeAchat.GestionDemandeAchat.index')
                ],
                443
            );
        }

        return $this->renderer->render('@popup-erreur/erreurAlerteEtAvertissement', [
            'params' => [
                'statut' => 'E',
                'alerte' => $this->trad->t("Erreur lors de l'exécution de l'opération.")
            ],
            'titrePopup' => $this->trad->t("Erreur"),
        ]);
    }

    /**
     * _getCountryTab
     *
     * @return array<mixed>
     */
    private function _getCountryTab(): array
    {
        return (new Pays($this->pdo))->listChoice();
    }
}
