<?php declare(strict_types=1);

namespace Modules\TermeDePaiement\Service\Strategy;

use Entity\Model\CaEntet;
use Entity\Model\CaLigne;
use Modules\Commande\Repository\Commande;

class TPStrategyCommande implements TPStrategyInterface
{

    public function __construct(
        private CaLigne $caligne,
        private CaEntet $caEntet,
        private Commande $commandeRepo
    ) {
    }

    /**
     * Summary of getLignesTpPos
     * @param string $id
     * @return ?string
     */
    public function getDevise(string $id): ?string
    {
        return $this->caEntet->find(['NO_CDE' => $id], ['DEVISE'])['DEVISE'] ?? '';
    }

    /**
     * Summary of getLignesTpPos
     * @param string $id
     * @param array<mixed> $allTpPos
     * @return ?array<mixed>
     */
    public function getDetailLigneTpPos(string $id, array $allTpPos): ?array
    {
        $lignesTpPos = [];
        foreach ($allTpPos as $ligne) {
            $lignesTpPos[$ligne['NUM_PO_CD']] = $this->caligne->find(['NO_CDE' => $id, 'NO_PO' => $ligne['NUM_PO_CD']]);
        }
        return $lignesTpPos;
    }

    /**
     * Summary of getLignesSeuil
     * @param string $id
     * @param array<mixed> $allLignesOnEvent
     * @return ?array<mixed>
     */
    public function getDetailLigneSeuil(string $id, array $allLignesOnEvent): ?array
    {
        $lignesSeuil = [];
        foreach ($allLignesOnEvent as $ligneOnEvent) {
            $lignesSeuil[$ligneOnEvent["NOPOCDE"]] = $this->caligne->find(['NO_CDE' => $id, 'NO_PO' => $ligneOnEvent['NOPOCDE']]) + $ligneOnEvent;
        }
        return $lignesSeuil;
    }

    /**
     * Summary of getAllArticles
     * @param string $id
     * @return ?array<mixed>
     */
    public function getAllDocArticles(string $id): ?array
    {
        return $this->caligne->findAll(['NO_CDE' => $id]);
    }

    /**
     * Summary of getMontantTotal
     * @param string $id
     * @return string
     */
    public function getMontantTotal(string $id): string
    {
        return $this->caEntet->find(['NO_CDE' => $id], ['TOT_CDE'])['TOT_CDE'] ?? '';
    }

    public function getCodeFou(string $id): string
    {
        return $this->caEntet->find(['NO_CDE' => $id], ['CODE_FOU'])['CODE_FOU'] ?? '';
    }

    /**
     * Summary of verifPourcTP
     * @param string $id
     * @param array<mixed> $tps
     * @param array<mixed> $evts
     * @return array<mixed>
     */
    public function verifPourcTP(string $id, array &$tps, array $evts, ?string $critere = null): array
    {
        if (count($tps) == 0) {
            return [];
        }
        
        $pourcentageParArticle = [];
        $articlesNumbers       = array_map(fn($po) => (int) $po['NO_PO'], $this->caligne->findAll(['NO_CDE' => $id]));

        foreach ($tps as &$tp) {
            $verifPourcTp = $this->commandeRepo->verifPourcTp($id, $tp['NUM_TP']);
            foreach ($verifPourcTp as $ligne) {
                if (!isset($pourcentageParArticle[$ligne['NO_PO']])) {
                    $pourcentageParArticle[$ligne['NO_PO']] = 0;
                }
                $pourcentageParArticle[$ligne['NO_PO']] += $ligne['total_pourc_tp'];
            }
            $tpEvts       = array_filter($evts, fn($tpEvt) => $tpEvt['NUM_TP'] == $tp['NUM_TP']);
            $declencheurs = [];
            foreach ($tpEvts as $evt) {
                if (!empty($evt['LIB_EVT'])) {
                    // TODO: Vérifier la trad
                    $declencheurs[] = $evt['LIB_EVT'];
                }
            }
            $tp['DECLENCHEUR'] = implode(', ', $declencheurs); // TODO: move to view
        }
        unset($tp);

        foreach ($articlesNumbers as $noPo) {
            // @phpstan-ignore-next-line
            if (!isset($pourcentageParArticle[$noPo])) {
                $verifPourcTpGlobal[] = [
                    'NO_PO' => $noPo,
                    'total_pourc_tp' => 0,
                    'pourcentage_manquant' => 100,
                    'missing' => true
                ];
            } else {
                $pourcentageManquant  = 100 - $pourcentageParArticle[$noPo];
                $verifPourcTpGlobal[] = [
                    'NO_PO' => $noPo,
                    'total_pourc_tp' => $pourcentageParArticle[$noPo],
                    'pourcentage_manquant' => abs($pourcentageManquant),
                ];
            }
        }

        return $verifPourcTpGlobal ?? [];
    }
}
