<?php

namespace Modules\DemandeAchat\Controller;

use Entity\Model\Parametr;
use Entity\Model\Paravrac;
use Helpers\Ariane\Ariane;
use Helpers\Outil\Roles;
use Helpers\Outil\Sql;
use Modules\Commande\MenuContextuel\WorkflowBonSortieMenuContextuel;
use Modules\Commande\MenuContextuel\WorkflowExpMenuContextuel;
use Modules\DemandeAchat\Repository\WorkflowDemandeAchatRepo;
use Skeleton\Controller\Controller;

class WorkflowController extends Controller
{

    public function summaryAction(): string
    {

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

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

        $state = (new WorkflowDemandeAchatRepo($this->pdo))->getWorkflowState($demandeId);

        if (empty($state)) {
            return ''; // TODO : 404
        }

        $paramtr = new Parametr($this->pdo);
        $paravrac = new Paravrac($this->pdo);

        $listItem = [
            ['id' => 'DEBUT', 'status' => 'T'],
        ];
        $listItem[] = [
            'id' => 'DA',
            'status' => (Sql::toBool($state['VALIDITE']) ? 'T' : 'C')
        ];

        if ($paramtr->isSignDemAchatActive()
            && ($state['CHIF_EXEC'] == 'E'
                || Sql::toBool($paravrac->getForSig('NOTSIGDACHIF'))
            )
        ) {
            $status = 'C';
            // Si la DA n'est pas validée alors le statut de l'objet Signature DA est "non commencé"
            if (!Sql::toBool($state['VALIDITE'])) {
                $status = 'N';
                // Si la DA est refusée
            } elseif (Sql::toBool($state['REFUSEE'])) {
                $status = 'R';
                // Si la DA est traitée
            } elseif (Sql::toBool($state['SIGNEE'])) {
                $status = 'T';
            }

            $listItem[] = [
                'id' => 'DA_APPRO',
                'status' => $status,
            ];
        }

        // L'objet BS est affiché si : La DA donne lieu à un BS avec au moins une ligne sur stock
        if ($state['hasLigneStock']
            && !empty($state['FM_CODE'])
        ) {
            $status = 'T';
            if (!$state['hasBonSortie']) {
                $status = 'N';
            } elseif ($state['hasBonSortieNonValide']) {
                $status = 'C';
            }

            $listItem[] = [
                'id' => 'BS',
                'status' => $status,
            ];
        }


        if ($state['CHIF_EXEC'] == 'E'
            && ($state['hasLigneNonStocke']
                || empty($state['FM_CODE'])
            )
        ) {
            $status = 'T';
            if (!$state['hasCommande']) {
                $status = 'N';
            } elseif ($state['hasCommandeNonValide']
                || $state['hasLigneNonStockeNonTraite'] // ligne non stockées n'est pas traitée
            ) {
                $status = 'C';
            }

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

            if ($paramtr->isSignCommandeActive()) {
                $status = 'T';
                if (!$state['hasCommande']) {
                    $status = 'N';
                    // Si au moins une commande a été refusée
                } elseif ($state['hasCommandeRefuse']) {
                    $status = 'R';
                    // Sinon, si l'une des commandes n'est pas validée
                } elseif ($state['hasCommandeNonValide']) {
                    $status = 'N';
                    // Sinon si l'une des commandes n'est pas signée
                } elseif ($state['hasCommandeNonSigne']) {
                    $status = 'C';
                }

                $listItem[] = [
                    'id' => 'CDE_APPRO',
                    'status' => $status,
                ];
            }

            $statusCdeEnvoie = 'N';
            if ($state['hasCommande'] && !$state['hasCommandeNonCommence']) {
                $statusCdeEnvoie = 'T';
            } elseif ($state['hasCommandeCommence']) {
                $statusCdeEnvoie = 'C';
            }
            $listItem[] = [
                'id' => 'CDE_ENVOIE',
                'status' => $statusCdeEnvoie,
            ];


            $status = 'N';
            if (!$state['hasCommande']) {
                $status = 'N';
            } elseif (Sql::toBool($state['TRAITEE'])) {
                $status = $state['hasCommandeNonSolde'] ? 'C' : 'T';
            }

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


            // Si la DA est de type exécution et que le centre de livraison est du type internationnal
            $statusExp = null;
            if (/*$state['CHIF_EXEC'] == 'E' && */Sql::toBool($state['TRS_INTER'])) {
                $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')) {
                $statusFac = 'T';

                // Si aucune facture n'existe alors le statut est "non commencé"
                if (!$state['hasFacExp']) {
                    $statusFac = 'N';

                    // S'il existe au moins une facture et (une commande non soldée financièrement ou une expédition non soldée)
                    // ou que tous les envois de commande n'ont pas été réalisé alors le statut est commencé
                } elseif ($state['hasFacExpNonSolde']
                    || $statusCdeEnvoie != 'T'
                    || !in_array($statusExp, [null, 'T'])
                ) {
                    $statusFac = 'C';
                }

                $listItem[] = [
                    'id' => 'FAC',
                    'status' => $statusFac,
                ];

                if ($paravrac->getValue('PARAMINIFA', 'SIGN_BAP')) {
                    $status = 'T';
                    if (!$state['hasBap']) {
                        $status = 'N';
                    } elseif ($state['hasBapNonValide']) {
                        $status = 'C';
                    }
                    $listItem[] = [
                        'id' => 'FAC_APPRO',
                        'status' => $status,
                    ];
                }
            }
        }

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

    public function detailAction(): string
    {
        $demandeId = $this->request->getAttribute('demandeId');
        $workflowId = $this->request->getAttribute('workflowId');

        if ($workflowId == 'DA') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailDemAchat', [
                'listItem' => [
                    (new WorkflowDemandeAchatRepo($this->pdo))
                        ->getDemAchatWithListEvent($demandeId)
                ],
                '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 WorkflowDemandeAchatRepo($this->pdo))
                        ->getDemAchatApproWithListEvent($demandeId),
                ],
                'hasImprValoDa' => roles::droitsUtilisateur($this->pdo, 'HA_DA_IMP'),
                'hasImprNonValoDa' => roles::droitsUtilisateur($this->pdo, 'HA_DA_IMPN'),
            ]);
        }

        if ($workflowId == 'BS') {
            $menuBuilder = new WorkflowBonSortieMenuContextuel(
                $this->pdo,
                $this->router,
                $this->getTranslationService()
            );
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailBonSortie', [
                'listBonSortie' => array_map(
                    function ($item) use ($menuBuilder) {
                        $item['menu'] = $menuBuilder->generate($item);
                        return $item;
                    },
                    (new WorkflowDemandeAchatRepo($this->pdo))
                        ->listBonSortie($demandeId)
                ),
            ]);
        }

        if ($workflowId == 'CDE') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailCommande', [
                'listItem' => (new WorkflowDemandeAchatRepo($this->pdo))
                    ->listCommandeWithListEvent($demandeId),
                'hasImprCde' => Roles::droitsUtilisateur($this->pdo, 'HA_CA_IMIN'),
            ]);
        }
        if ($workflowId == 'CDE_APPRO') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailCommandeAppro', [
                'listItem' => (new WorkflowDemandeAchatRepo($this->pdo))
                    ->listCommandeApproWithListEvent($demandeId),
                'hasImprCde' => Roles::droitsUtilisateur($this->pdo, 'HA_CA_IMIN'),
            ]);
        }
        if ($workflowId == 'CDE_ENVOIE') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailCommandeEnvoi', [
                'listItem' => (new WorkflowDemandeAchatRepo($this->pdo))
                    ->listCommandeEnvoiWithListEvent($demandeId),
                'hasImprCde' => Roles::droitsUtilisateur($this->pdo, 'HA_CA_IMIN'),
            ]);
        }
        if ($workflowId == 'BR') {
            return $this->renderer->render('@GlobalApplication/WorkflowEvent/workflowDetailBonRecep', [
                'listItem' => (new WorkflowDemandeAchatRepo($this->pdo))
                    ->listBonRecepWithListEvent($demandeId),
                '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 WorkflowDemandeAchatRepo($this->pdo))
                        ->listExpedition($demandeId)
                ),
                'hasImprExp' => Roles::droitsUtilisateur($this->pdo, 'HA_EXP_IMP'),
            ]);
        }

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

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