<?php

namespace Modules\Fournisseur\Controller;

use Entity\Model\ParamDico;
use Entity\Model\Parametr;
use Entity\Model\Periodes;
use Helpers\Pagination\PaginatorGestion;
use Modules\Evaluation\Service\ResultatService;
use Skeleton\Controller\Controller;
use Helpers\Ariane\Ariane;
use Modules\Fournisseur\Repository\Indicateur;
use Helpers\Highcharts\Highcharts;
use Helpers\Outil\ArrayHelper;
use Helpers\Outil\Outils;
use Helpers\Trad\Trad;
use Modules\Evaluation\Repository\Resultat;
use PDO;

class IndicateurFournisseurController extends Controller
{

    public function indicateurAction(): string
    {
        $post = $this->request->getParsedBody();

        $trad = $this->getTranslationService();

        $indicateur = new Indicateur($this->pdo);
        $periodes = $indicateur->periodedispo();

        /* highcharts 1 */
        $nbrFournissActif = $indicateur->nbrFournissActif();

        $array1['titre'] = $trad->t('Nombre de fournisseurs actifs') . ' - ' . ($post['annee'] ?? date('Y'));
        $array1['Fourchette'] = [0, $nbrFournissActif[1]['value']];
        $array1['value'] = $nbrFournissActif[0]['value'];
        $array1['legend'] = $trad->t('Fournisseurs');
        $array1['type'] = 'solidgauge';

        $highcharts1 = Highcharts::generate($array1, $this->pdo, $trad);

        /* highcharts 2 */
        $nbrFournissParPeriode = $indicateur->nbrFournissParPeriode($post['annee'] ?? date('Y'));

        $array2['titre'] = $trad->t('Nombre de fournisseurs utilisés') . ' - ' . ($post['annee'] ?? date('Y'));
        $array2['Fourchette'] = [0, $nbrFournissParPeriode[1]['value']];
        $array2['value'] = $nbrFournissParPeriode[0]['value'];
        $array2['legend'] = $trad->t('Fournisseurs');
        $array2['type'] = 'solidgauge';

        $highcharts2 = Highcharts::generate($array2, $this->pdo, $trad);

        /* indicateur */
        $cumulCA = $indicateur->totalCAParPeriode($post['annee'] ?? date('Y'));
        /* highcharts 3 */
        $graphIncident = $indicateur->nbrIncidentFou($post['annee'] ?? date('Y'));

        $array3['value']                  = $graphIncident;
        $array3['categorie']              = 'mois';
        $array3['titre']                  = $trad->t("Nombre incidents") . ' - ' . ($post['annee'] ?? date('Y'));
        $array3['type']                   = 'area';
        $array3['detailColone']['NOMBRE_INCIDENT'] = ['nom' => $trad->t("Nbr d'incidents"), 'axeLier' => 'gauche'];
        $array3['legendGraph'][]          = ['texte' => $trad->t("Nbr d\'incidents"), 'format' => '', 'axe' => 'gauche'];
        $array3['path']                   = $this->router->generateUri('GlobalApplication.Incidents.incidents', ['MODULE' => 'MultiFournisseur', 'id' => 'ALL']);
        $array3['pathPost']               = "{'BETWEEN_DTE_OCCUR' : '" . ($post['annee'] ?? date('Y')) . "'}";

        $highcharts3 = Highcharts::generate($array3, $this->pdo, $trad);

        /* highcharts 4 */
        $graphPalmares = $indicateur->palmaresFou($post['annee'] ?? date('Y'));

        $categorieArray4 = [];
        foreach ($graphPalmares as $val) {
            $categorieArray4[] = $val['CODE_FOU'] . ' - ' . addslashes($val['RS']);
        }

        $array4['value']                  = $graphPalmares;
        $array4['titre']                  = $trad->t("Palmarès des fournisseurs") . ' - ' . ($post['annee'] ?? date('Y'));
        $array4['type']                   = 'column';
        $array4['categorie']              = $categorieArray4;
        $array4['detailColone']['NBRE_COMMANDE'] = ['nom' => $trad->t('Nombre de commandes'), 'type' => 'spline', 'axeLier' => 'gauche', 'index' => 2];
        $array4['detailColone']['MONTANT'] = ['nom' => $trad->t('Montant'), 'axeLier' => 'droit'];
        $array4['legendGraph'][]          = ['texte' => $trad->t("Nbr de commandes"), 'format' => '', 'axe' => 'gauche'];
        $array4['legendGraph'][]          = ['texte' => $trad->t('Montant'), 'format' => ' ' . $_SESSION['parametrage']['DEVISE_BASE'], 'axe' => 'droit'];

        $highcharts4 = Highcharts::generate($array4, $this->pdo, $trad);

        $listeParentaire = $indicateur->listePartenaire();

        Ariane::generate(0, $trad->t('Analyse'), $post);

        return $this->renderer->render('@Fournisseur/Indicateur/indicateur', [
            'menuActive' => 'Fournisseur',
            'periodes' => $periodes,
            'dataHighchart1' => $highcharts1,
            'dataHighchart2' => $highcharts2,
            'dataHighchart3' => $highcharts3,
            'dataHighchart4' => $highcharts4,
            'annee' => $post['annee'] ?? date('Y'),
            'totalCA' => intval($cumulCA['CA'] ?? 0),
            'moyenCA' => empty($cumulCA) ? 0 : (float)$cumulCA['CA'] / (float)$cumulCA['NB_CDES'],
            'devise' => $_SESSION['parametrage']['DEVISE_BASE'],
            'listePartenaire' => $listeParentaire,
        ]);
    }

    public function evaluationsAction(): string
    {
        $post = $this->request->getParsedBody();
        $action = $this->request->getAttribute('action');
        $trad = $this->getTranslationService();

        $companyParameters = (new Parametr($this->pdo))->find(['CLE' => '1'], ['STDEVSTK', 'PER_ENCOU']);
        $post['end'] = $post['end'] ?? $companyParameters['PER_ENCOU'];

        //on récupère les infos sur la période sélectionnée
        $endPeriodData = (new Periodes($this->pdo))->find(['CODE_PER' => $post['end']]);
        $startPeriodData = [];

        if (($post['start'] ?? '') != '') {
            $startPeriodData = (new Periodes($this->pdo))->find(['CODE_PER' => $post['start']]);
        }

        if (empty($startPeriodData) || ($startPeriodData['DATE_DEB'] ?? '00000000' > $endPeriodData['DATE_DEB'])) {
            $startPeriodData = (new Periodes($this->pdo))->find([
                'DATE_DEB' => (string)(intval(\mb_substr($endPeriodData['DATE_DEB'], 0, 4)) - 5)
                    . \mb_substr($endPeriodData['DATE_DEB'], 4, 8)
            ]);

            $post['start'] = $startPeriodData['CODE_PER'];
        }

        $indicateur = new Indicateur($this->pdo);
        $resultatRepository = new Resultat($this->pdo);
        $periodes = [];
        $filtersPeriods = [];
        $filtersPeriodsTmp = $indicateur->periodedispo($post);
        $periodesTmp = $indicateur->periodedispo();
        foreach ($filtersPeriodsTmp as $val) {
            $filtersPeriods[$val['CODE_PER']] = $val['LIBELLE'];
        }
        foreach ($periodesTmp as $val) {
            $periodes[$val['CODE_PER']] = $val['LIBELLE'];
        }

        $ssFam = $post['ssFam'] ?? '';

        $param = (new ResultatService($this->pdo))->getEvalParamdico();

        $paginator = new PaginatorGestion();
        $paginator->generate(7, 'MOYENNE');

        $suppliersByGrade = $indicateur->getSuppliersGradesByPeriode($post['end'], $param, $ssFam, $post);
        $chartsPeriodes = array_keys($filtersPeriods);
        $amountBySupplier = array_column(
            $resultatRepository->getAmountBySupplier(
                $chartsPeriodes,
                $startPeriodData['DATE_DEB'],
                $endPeriodData['DATE_FIN']
            ),
            'TOTAL_ORDERED',
            'CODE_FOU'
        );

        if ($action == 'export') {
            $exportData = $indicateur->getExportData($param, $post);
            foreach ($exportData as &$exportLine) {
                $exportLine['STATUS'] = ($exportLine['NOTE'] <= $param['ALPHA3'])
                    ? $param['ALPHA6']
                    : (($exportLine['NOTE'] <= $param['ALPHA4'])
                        ? $param['ALPHA7']
                        : $param['ALPHA8']);
                // @phpstan-ignore-next-line
                $exportLine['TOTAL_ORDERED'] = round($amountBySupplier[$exportLine['CODE_FOU']] ?? 0, 2);
                if ($post['ssFam'] == '') {
                    // @phpstan-ignore-next-line
                    unset($exportLine['SSFAM']);
                }
            }

            \Helpers\ExportTo\Outils::gestionEmailAsync2(
                'reporting_eval_suppliers_' . date('Ymd'),
                $exportData,
                $this->JWTKEY,
                $this->router,
                $this->getTranslationService(),
                [
                    'ID_CAMP' => $trad->t('Id de la campagne'),
                    'COD_PER' => $trad->t('Année'),
                    'CODE_FOU' => $trad->t('Code fournisseur'),
                    'NOTE' => $trad->t('Note'),
                    'RS' => $trad->t('Raison sociale'),
                    'CLASSE' => $trad->t('Classification'),
                    'STATUS' => $trad->t('Statut'),
                    'TOTAL_ORDERED' => Trad::strBuild($trad->t('Total commandé entre @1@ et @2@'), $post['start'], $post['end']),
                ] + ($post['ssFam'] != ''
                    ? ['SSFAM' => $trad->t('Sous-famille')]
                    : []
                )
            );

            return 'ok';
        }

        $infopagination = PaginatorGestion::getInfoPagination();
        $listePartenaire = $indicateur->listePartenaire();

        $tmpCountSuppliersByYear = $resultatRepository
            ->getCountSuppliersByGradeByYear([
                'noteMinBad' => 0, 'noteMaxBad' => intval($param['ALPHA3']), 'noteMinMedium' => intval($param['ALPHA3']) + 1,
                'noteMaxMedium' => intval($param['ALPHA4']), 'start' => min($chartsPeriodes), 'end' => max($chartsPeriodes),
                'ssFam' => ($post['ssFam'] ?? ''), 'categorization' => ($post['categorization'] ?? '')
            ]);
        
        $countSuppliersByYear = [];
        $total = [];
        foreach ($tmpCountSuppliersByYear as $year) {
            $countSuppliersByYear[$year['COD_PER']][$year['statut']] += 1;
            $total[$year['COD_PER']] += 1;
        }

        /* highcharts 1 - nombre de fournisseurs par statuts et par années */
        $chartsData = [];
        foreach ($chartsPeriodes as $periode) {
            $chartsData[] = [
                'badSuppliers' => $countSuppliersByYear[(string)$periode]['bad'] ?? 0,
                'averageSuppliers' => $countSuppliersByYear[(string)$periode]['average'] ?? 0,
                'goodSuppliers' => $countSuppliersByYear[(string)$periode]['good'] ?? 0,
            ];
        }

        $evolutionCharts = $this->_generateHighcharts('evolution', $chartsData, $chartsPeriodes, $param + ['total' => $total]);

        /* highcharts 2 - pourcentage de fournisseurs par statuts et par années */
        $chartsData = [];
        foreach ($chartsPeriodes as $periode) {
            $chartsData[] = [
                'badSuppliers' => round(intval(($countSuppliersByYear[(string)$periode]['bad']) ?? 0)
                    / ($total[(string)$periode] ?? 1)
                    * 100),
                'averageSuppliers' => round(intval(($countSuppliersByYear[(string)$periode]['average']) ?? 0)
                    / ($total[(string)$periode] ?? 1)
                    * 100),
                'goodSuppliers' => round(intval(($countSuppliersByYear[(string)$periode]['good']) ?? 0)
                    / ($total[(string)$periode] ?? 1)
                    * 100),
            ];
        }

        $percentageCharts = $this->_generateHighcharts('percentage', $chartsData, $chartsPeriodes, $param + ['total' => $total]);

        /* highcharts 3 - fournisseurs par note et par montant */
        $gradeBySupplier = $resultatRepository->getGradeBySupplier($chartsPeriodes);

        $chartsData = [];
        $suppliers = [];
        foreach ($gradeBySupplier as $supplier) {
            $supplierOk = true;
            if (($post['amount_min'] ?? '') !== '') {
                if (intval($amountBySupplier[$supplier['CODE_FOU']] ?? 0) < intval($post['amount_min'])) {
                    $supplierOk = false;
                }
            }
            if (($post['amount_max'] ?? '') !== '') {
                if (intval($amountBySupplier[$supplier['CODE_FOU']] ?? 0) > intval($post['amount_max'])) {
                    $supplierOk = false;
                }
            }
            if ($supplierOk) {
                $suppliers[] = $supplier['CODE_FOU'] . ' - ' . addslashes($supplier['RS']);
                $chartsData[] = [
                    'gradeBySupplier' => round((int)$supplier['AVG_NOTE']),
                    'amountBySupplier' => round($amountBySupplier[$supplier['CODE_FOU']] ?? 0),
                ];
            }
        }

        $amountGradeCharts = $this->_generateHighcharts('amount', $chartsData, $chartsPeriodes, $param + [
            'suppliers' => $suppliers,
            'devise' => $companyParameters['STDEVSTK']
        ]);

        return $this->renderer->render('@Fournisseur/Indicateur/evaluations', [
            'menuActive' => 'Fournisseur',
            'periodes' => $periodes,
            'evolutionCharts' => $evolutionCharts,
            'percentageCharts' => $percentageCharts,
            'amountGradeCharts' => $amountGradeCharts,
            'suppliersByGrade' => $suppliersByGrade,
            'param' => $param,
            'start' => $post['start'],
            'end' => $post['end'],
            'amount_min' => $post['amount_min'] ?? '',
            'amount_max' => $post['amount_max'] ?? '',
            'ssFam' => $ssFam,
            'listePartenaire' => $listePartenaire,
            'infopagination' => $infopagination,
            'post' => $post,
            'categorizations' => [
                '' => $trad->t("Toutes"),
                'A' => 'A',
                'B' => 'B',
                'C' => 'C',
            ],
            'statuses' => [
                '' => $trad->t("Tous"),
                'bad' => ($param['ALPHA6'] ?: $trad->t('Mauvais')),
                'mid' => ($param['ALPHA7'] ?: $trad->t('Moyen')),
                'good' => ($param['ALPHA8'] ?: $trad->t('Bon')),
            ]
        ]);
    }

    public function documentsAction(): string
    {
        $trad = $this->getTranslationService();

        $indicateur = new Indicateur($this->pdo);
        //$nombreFrs = $indicateur->nbrFrs();

        /** HC 1 **/
        $nombreTotal = $indicateur->nbrDocTotal()['NB_DOC'];
        $nombreDocActif = $indicateur->nbrDocValide();

        $tableauHC1 = [
            'A_JOUR' => $nombreDocActif['NB_DOC'],
            'ABSENT' => $nombreTotal - ($nombreDocActif['NB_DOC'] == '' ? 0 : $nombreDocActif['NB_DOC']),
        ];

        $array1['titre'] = $trad->t('Nombre de documents à jour');
        $array1['Fourchette'] = [0, $nombreTotal];
        $array1['value'] = $nombreDocActif['NB_DOC'];
        $array1['legend'] = $trad->t('Documents à jour');
        $array1['type'] = 'solidgauge';

        $highcharts1 = Highcharts::generate($array1, $this->pdo, $trad);

        /** HC2 **/
        $nombreTotalCritique =  $indicateur->nbrDocTotal(true)['NB_DOC'];
        $nombreDocActifCritque = $indicateur->nbrDocValide(true);

        $tableauHC2 = [
            'A_JOUR' => $nombreDocActifCritque['NB_DOC'],
            'ABSENT' => $nombreTotalCritique - ($nombreDocActifCritque['NB_DOC'] == '' ? 0 : $nombreDocActifCritque['NB_DOC']),
        ];

        $array2['titre'] = $trad->t('Nombre de documents critiques à jour');
        $array2['Fourchette'] = [0, $nombreTotalCritique];
        $array2['value'] = $nombreDocActifCritque['NB_DOC'];
        $array2['legend'] = $trad->t('Documents critiques à jour');
        $array2['type'] = 'solidgauge';

        $highcharts2 = Highcharts::generate($array2, $this->pdo, $trad);

        /** HC3 **/
        $nombreTotalSurv = $indicateur->nbrDocTotal(false, true)['NB_DOC'];
        $nombreDocActifSurv = $indicateur->nbrDocValide(false, true);

        $tableauHC3 = [
            'A_JOUR' => $nombreDocActifSurv['NB_DOC'],
            'ABSENT' => $nombreTotalSurv - ($nombreDocActifSurv['NB_DOC'] == '' ? 0 : $nombreDocActifSurv['NB_DOC']),
        ];

        $array3['titre'] = $trad->t('Nombre de documents en surveillance');
        $array3['Fourchette'] = [0, $nombreTotalSurv];
        $array3['value'] = $nombreDocActifSurv['NB_DOC'];
        $array3['legend'] = $trad->t('Documents en surveillance');
        $array3['type'] = 'solidgauge';

        $highcharts3 = Highcharts::generate($array3, $this->pdo, $trad);

        $listeParentaire = $indicateur->listePartenaire();

        return $this->renderer->render('@Fournisseur/Indicateur/documents', [
            'menuActive' => 'Fournisseur',
            'menuLeft' => 'Fournisseur.Incidateur.indicateur',
            'dataHighchart1' => $highcharts1,
            'dataHighchart2' => $highcharts2,
            'dataHighchart3' => $highcharts3,

            'tableauHC1' => $tableauHC1,
            'tableauHC2' => $tableauHC2,
            'tableauHC3' => $tableauHC3,

            'listePartenaire' => $listeParentaire,
        ]);
    }

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

        $indicateur = new Indicateur($this->pdo);
        $frsInscrit = (int)$indicateur->nbrFrsInscrit($partenaire);

        /** HC1 **/
        $frsInvite = (int)$indicateur->nbrFrsInvite($partenaire);


        $tableauHC1 = [
            '0' => $frsInscrit,
            '1' => $frsInvite,
        ];
        $trad = $this->getTranslationService();

        $array1['titre'] = $trad->t('Adhésion fournisseurs');
        $array1['Fourchette'] = [0, $frsInvite, true];
        $array1['value'] = $frsInscrit;
        if ($frsInvite) {
            $array1['legend'] = number_format(($frsInscrit * 100) / $frsInvite, 2) . ' %';
        } else {
            $array1['legend'] = '0%';
        }
        $array1['type'] = 'solidgauge';

        $highcharts1 = Highcharts::generate($array1, $this->pdo, $trad);

        /** HC2**/
        $docValide = (int)$indicateur->nbrDocCollectValide($partenaire);
        $docDemande = (int)$indicateur->nbrDocDemande($partenaire);

        $tableauHC2 = [
            '0' => $docValide,
            '1' => ((float)$docDemande * $frsInscrit),
        ];

        $array2['titre'] = $trad->t('Complétude documentaire');
        $array2['Fourchette'] = [0, ($docDemande * $frsInscrit), true];
        $array2['value'] = $docValide;

        if ($docDemande * $frsInscrit) {
            $array2['legend'] = number_format(($docValide * 100) / ($docDemande * $frsInscrit), 2) . ' %';
        } else {
            $array2['legend'] = '0%';
        }
        $array2['type'] = 'solidgauge';

        $highcharts2 = Highcharts::generate($array2, $this->pdo, $trad);

        $listeParentaire = $indicateur->listePartenaire();

        return $this->renderer->render('@Fournisseur/Indicateur/partenaire', [
            'menuActive' => 'Fournisseur',
            'menuLeft' => 'Fournisseur.Incidateur.indicateur',
            'dataHighchart1' => $highcharts1,
            'dataHighchart2' => $highcharts2,

            'tableauHC1' => $tableauHC1,
            'tableauHC2' => $tableauHC2,

            'listePartenaire' => $listeParentaire,
            'partenaireCurrent' => $partenaire,
        ]);
    }
    
    /**
     * _generateHighcharts
     *
     * @param  string $type
     * @param  array<mixed> $chartsData
     * @param  array<mixed> $chartsPeriodes
     * @param  array<mixed> $params
     * @return array<mixed>
     */
    private function _generateHighcharts(string $type, array $chartsData, array $chartsPeriodes, array $params): array
    {
        $trad = $this->getTranslationService();
        
        $highcharts['value'] = $chartsData;
        $highcharts['type'] = 'column';
        $highcharts['categorie'] = $chartsPeriodes;
        $highcharts['detailColone']['badSuppliers'] = [
            'nom' => Trad::strBuild($trad->t('Fournisseurs @1@'), $params['ALPHA6']),
            'type' => 'spline', 'axeLier' => 'gauche', 'index' => 2, 'color' => '#FD0D0D'
        ];
        $highcharts['detailColone']['averageSuppliers'] = [
            'nom' => Trad::strBuild($trad->t('Fournisseurs @1@'), $params['ALPHA7']),
            'type' => 'spline', 'axeLier' => 'gauche', 'index' => 2, 'color' => '#FF6B3D'
        ];
        $highcharts['detailColone']['goodSuppliers'] = [
            'nom' => Trad::strBuild($trad->t('Fournisseurs @1@'), $params['ALPHA8']),
            'type' => 'spline', 'axeLier' => 'gauche', 'index' => 2, 'color' => '#39b54a'
        ];

        switch ($type) {
            case 'evolution':
                $highcharts['titre'] = $trad->t("Évolution des statuts");
                $highcharts['legendGraph'][] = ['texte' => $trad->t("Nombre de fournisseurs"), 'format' => '', 'axe' => 'gauche'];
                break;
            
            case 'percentage':
                $highcharts['titre'] = Trad::strBuild(
                    $trad->t("Taux de fournisseurs évalués par statut (total : @1@)"),
                    array_sum($params['total'])
                );
                $highcharts['legendGraph'][] = ['texte' => $trad->t("Taux (en %)"), 'format' => '', 'axe' => 'gauche'];
                break;
            
            case 'amount':
                $highcharts['titre'] = $trad->t("Note moyenne et montant commandé par fournisseur");
                $highcharts['categorie'] = $params['suppliers'];
                $highcharts['detailColone'] = [
                    'gradeBySupplier' => [
                        'nom' => $trad->t('Note moyenne'),
                        'type' => 'spline',
                        'axeLier' => 'gauche',
                        'index' => 2
                    ],
                    'amountBySupplier' => [
                        'nom' => Trad::strBuild($trad->t('Montant commandé (en @1@)'), $params['devise']),
                        'type' => 'column',
                        'axeLier' => 'droit',
                        'index' => 1
                    ]
                ];
                $highcharts['legendGraph'][] = ['texte' => $trad->t("Note"), 'format' => '', 'axe' => 'gauche'];
                $highcharts['legendGraph'][] = ['texte' => Trad::strBuild($trad->t('Montant (en @1@)'), $params['devise']),
                    'format' => '', 'axe' => 'droit'];
                break;
            
            default:
                $highcharts = [];
                break;
        }

        return Highcharts::generate($highcharts, $this->pdo, $trad);
    }
}
