<?php
namespace Modules\Commande\Controller;

use Entity\Model\Parametr;
use Entity\Model\Paravrac;
use Helpers\Ariane\Ariane;
use Helpers\Outil\ArrayHelper;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Modules\Commande\MenuContextuel\WorkflowExpMenuContextuel;
use Modules\Commande\Repository\WorkflowCommandeRepo;
use Skeleton\Controller\Controller;

class WorkflowController extends Controller
{

    public function summaryAction() : string
    {

        $commandeId = $this->request->getAttribute('commandeId');

        Ariane::generate(1, $this->getTranslationService()->t('Visualisation du workflow'));
        ariane::setFocus($commandeId);

        $state =
            (new WorkflowCommandeRepo($this->pdo))
                ->getWorkflowState($commandeId);
        $paramtr = new Parametr($this->pdo);
        $paravrac = new Paravrac($this->pdo);
        $listItem = [
            ['id' => 'DEBUT', 'status' => 'T'],
        ];

        if ($state['hasDemAchat']) {
            $listItem[] = [
                'id' => 'DA',
                'status' => ($state['hasDemAchatInvalid'] ? 'C' : 'T')
            ];

            if ($paramtr->isSignDemAchatActive()
                //si la DA est du type "exécution" ou bien que la signature sur les DA chiffrages est activé
                && ($state['hasDemAchatExec']
                    || Sql::toBool($paravrac->getForSig('NOTSIGDACHIF'))
                )
            ) {
                $status = 'N'; // statut est "non commencé"
                // Si une DA au moins a été refusé, le statut de l'objet Signature DA est refusé
                if ($state['hasDemAchatRefus']) {
                    $status = 'R';
                // Si toutes les DA sont traité alors le statut de l'objet Signature DA est traité
                } elseif (! $state['hasDemAchatUnsigned']) {
                    $status = 'T';
                // Si toutes les DA ont été validée alors le statut est "commencé"
                } elseif (! $state['hasDemAchatInvalid']) {
                    $status = 'C';
                }
                
                $listItem[] = [
                    'id' => 'DA_APPRO',
                    'status' => $status,
                ];
            }
        }

        $listItem[] = [
            'id' => 'CDE',
            'status' => ($state['DTE_VALID'] == '00000000' ? 'C' : 'T')
        ];
        
        if ($paramtr->isSignCommandeActive()) {
            $status = 'T';
            // Si la commande a été refusée
            if (Sql::toBool($state['REFUSEE'])) {
                $status = 'R';
            // Sinon, si la commande n'a pas été validée
            } elseif ('00000000' == $state['DTE_VALID']) {
                $status = 'N';
            // Sinon, si la commande n'est pas encore signée
            } elseif (! Sql::toBool($state['SIGNEE'])) {
                $status = 'C';
            }
            $listItem[] = [
                'id' => 'CDE_APPRO',
                'status' => $status,
            ];
        }

        $statusCdeEnvoie = 'N';
        if (in_array($state['ETAT_CDE'], ['E','S'])) {
            $statusCdeEnvoie =
                $state['DTE_VALID'] != '00000000' ? 'T' : 'C';
        } elseif ($state['ETAT_CDE'] == 'Z') {// Gestion des commandes annulées
            if ($state['hasEventIMA']) {
                $statusCdeEnvoie = 'T';
            } elseif ($state['hasEventEnvoi']) {
                $statusCdeEnvoie = 'C';
            }
        }
        $listItem[] = [
            'id' => 'CDE_ENVOIE',
            'status' => $statusCdeEnvoie
        ];

        $status = 'C';
        if ($state['ETAT_CDE'] == 'S') {
            $status = 'T';
        } elseif (! $state['hasBonRecep']
            && ! $state['hasFacLigneNonRecept']
        ) {
            $status = 'N';
        }
            
        $listItem[] = [
            'id' => 'BR',
            'status' => $status,
        ];

        $statusExp = null;
        if (roles::droitsUtilisateur($this->pdo, 'HA_EXP_VIS') && Sql::toBool($state['CDE_EXP'])) {
            $statusExp = 'T';
            if (! $state['hasExp']) {
                $statusExp = 'N';
            } elseif ($state['hasExpNonArrive']) {
                $statusExp = 'C';
            }
            $listItem[] = [
                'id' => 'EXP',
                'status' => $statusExp,
            ];
        }

        if (Roles::droitsUtilisateur($this->pdo, 'HA_FA_VISU')) {
            $statusFacture = 'T';
            // Si aucune facture n'existe alors le statut est "non commencé"
            if (! $state['hasFacture']) {
                $statusFacture = 'N';
            // S'il existe au moins une facture et (une commande non soldée financièrement ou une expédition non soldée)
            // ou bien si la commande n'a pas été envoyée alors le statut est commencé
            } elseif ($state['hasExpNonSold']
                || empty(trim($state['ETAT_FIN']))
                || $statusCdeEnvoie != 'T'
                || !in_array($statusExp, [null, 'T'])
            ) {
                $statusFacture = 'C';
            }
                
            $listItem[] = [
                'id' => 'FAC',
                'status' => $statusFacture,
            ];

            // APPRO BAP
            if ($paravrac->isSignBapActive()) {
                $status = 'T';
                if (! $state['hasBap']) {
                    $status = 'N';
                } elseif ($state['hasBapNonValide'] || $statusFacture != 'T') {
                    $status = 'C';
                }

                $listItem[] = [
                    'id' => 'FAC_APPRO',
                    'status' => $status,
                ];

                if ($status == 'T') {
                    $listItem[] = [
                        'id' => 'FIN',
                        'status' => 'T',
                    ];
                }
            } else {
                if ($statusFacture == 'T') {
                    $listItem[] = [
                        'id' => 'FIN',
                        'status' => $status,
                    ];
                }
            }
        }

        return $this->renderer->render('@Commande/Workflow/workflowDetail', [
            'commande' => $state,
            'listWorfowItem' => $listItem,
        ]);
    }

    public function detailAction() : string
    {
        return $this->detailActionProcess(
            $this->request->getAttribute('commandeId'),
            $this->request->getAttribute('workflowId')
        );
    }

    protected function detailActionProcess(string $commandeId, string $workflowId) :string
    {
        
        if ($workflowId == 'DA') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailDemAchat', [
                'listItem' =>
                    (new WorkflowCommandeRepo($this->pdo))
                        ->listAssociatedDemAchatWithListEvent($commandeId),
                'hasImprValoDa' => roles::droitsUtilisateur($this->pdo, 'HA_DA_IMP'),
                'hasImprNonValoDa' => roles::droitsUtilisateur($this->pdo, 'HA_DA_IMPN'),
            ]);
        }

        if ($workflowId == 'DA_APPRO') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailDemAchatAppro', [
                'listItem' =>
                    (new WorkflowCommandeRepo($this->pdo))
                        ->listAssociatedDemAchatApproWithListEvent($commandeId),
                'hasImprValoDa' => roles::droitsUtilisateur($this->pdo, 'HA_DA_IMP'),
                'hasImprNonValoDa' => roles::droitsUtilisateur($this->pdo, 'HA_DA_IMPN'),
            ]);
        }

        if ($workflowId == 'CDE') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailCommande', [
                'listItem' => [
                    (new WorkflowCommandeRepo($this->pdo))
                        ->getCommandeWithListEvent($commandeId),
                ],
                'hasImprCde' => Roles::droitsUtilisateur($this->pdo, 'HA_CA_IMIN'),
            ]);
        }
        if ($workflowId == 'CDE_APPRO') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailCommandeAppro', [
                'listItem' => [
                    (new WorkflowCommandeRepo($this->pdo))
                        ->getCommandeApproWithListEvent($commandeId),
                ],
                'hasImprCde' => Roles::droitsUtilisateur($this->pdo, 'HA_CA_IMIN'),
            ]);
        }
        if ($workflowId == 'CDE_ENVOIE') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailCommandeEnvoi', [
                'listItem' => [
                    (new WorkflowCommandeRepo($this->pdo))
                        ->getCommandeEnvoiWithListEvent($commandeId),
                ],
                'hasImprCde' => Roles::droitsUtilisateur($this->pdo, 'HA_CA_IMIN'),
            ]);
        }
        if ($workflowId == 'BR') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailBonRecep', [
                'listItem' =>
                    (new WorkflowCommandeRepo($this->pdo))
                        ->listBonRecepWithListEvent($commandeId),
                'hasImprBr' => roles::droitsUtilisateur($this->pdo, 'HA_BR_IMP'),
                'hasImprNonValoBr' => roles::droitsUtilisateur($this->pdo, 'HA_BR_IMPV'),
            ]);
        }

        if ($workflowId == 'EXP') {
            $menuBuilder = new WorkflowExpMenuContextuel(
                $this->pdo,
                $this->router,
                $this->getTranslationService()
            );
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailExp', [
                'listExp' => array_map(
                    function ($item) use ($menuBuilder) {
                        $item['menu'] = $menuBuilder->generate($item);
                        return $item;
                    },
                    (new WorkflowCommandeRepo($this->pdo))
                        ->listExpedition($commandeId)
                ),
                'hasImprExp' => Roles::droitsUtilisateur($this->pdo, 'HA_EXP_IMP'),
            ]);
        }

        if ($workflowId == 'FAC') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailFacture', [
                'listItem' =>
                    (new WorkflowCommandeRepo($this->pdo))
                        ->listFactureExpWithEvent($commandeId),
                'hasImprFacture' => Roles::droitsUtilisateur($this->pdo, 'HA_FA_IMP'),
            ]);
        }
        if ($workflowId == 'FAC_APPRO') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailFactureAppro', [
                'listItem' =>
                    (new WorkflowCommandeRepo($this->pdo))
                        ->listFactureExpApproWithEvent($commandeId),
                'hasImprFacture' => Roles::droitsUtilisateur($this->pdo, 'HA_FA_IMP'),
            ]);
        }

        throw new \Exception('invalid worflow item "'.$workflowId.'"');
    }
}
