<?php declare(strict_types=1);

namespace Modules\Additional\Specifique\Client164\Modules\Suivi\Controller;

use Entity\Model\CaEntet;
use Entity\Model\CaEvent;
use Entity\Model\CaLigne;
use Entity\Model\Centre;
use Entity\Model\Contfour;
use Entity\Model\CsDon;
use Entity\Model\Fourniss;
use Entity\Model\Hastutil;
use Entity\Model\Memos;
use Entity\Model\Unites;
use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Fichier\Fichier;
use Helpers\Outil\Date;
use Helpers\Outil\Outils;
use Helpers\Parametres\Constante;
use Helpers\PhpOffice\Utils\TableColumn;
use Helpers\Session\ParseBase1;
use Helpers\Trad\Trad;
use Modules\Additional\Specifique\Client164\Modules\Suivi\Service\EtatCommandeSpecifiqueService;
use PhpOffice\PhpWord\SimpleType\Jc;
use PhpOffice\PhpWord\SimpleType\JcTable;
use PhpOffice\PhpWord\SimpleType\TextAlignment;
use PhpOffice\PhpWord\Style\Font;
use Skeleton\Controller\Controller;

class EtatCommandeSpecifiqueController extends Controller
{

    public function indexAction(
        \PhpOffice\PhpWord\PhpWord $phpWord,
        CaEntet $caEntet,
        CaLigne $caLigne,
        CaEvent $caEvent,
        Fourniss $fourniss,
        Contfour $contfour,
        Hastutil $hastutil,
        Centre $centre,
        Memos $memos,
        Unites $unites,
        CsDon $csDon,
        EtatCommandeSpecifiqueService $etatCommandeSpecifiqueService,
        ParseBase1 $parseBase1,
    ): string {
        $idCommande = $this->request->getAttribute('idCommande');
        $trad       = $this->getTranslationService();

        // Récupération des informations pour générer le fichier Word
        $commande         = $caEntet->find(['NO_CDE' => $idCommande]);
        $lignesDeCommande = $caLigne->findAll(['NO_CDE' => $commande['NO_CDE']]);
        $fournisseur      = $fourniss->find(['CODE' => $commande['CODE_FOU']]);

        // Mise en place du fichier Word
        $phpWord->setDefaultFontName('Segoe UI');
        $phpWord->setDefaultFontSize(8);
        // 1. Création de la section (page)
        $sectionStyle = [
            'orientation'  => 'portrait',
            'paperSize'    => 'A4',
            'marginLeft'   => 600,
            'marginRight'  => 600,
            'marginTop'    => 600,
            'marginBottom' => 600,
        ];
        $section      = $phpWord->addSection($sectionStyle);

        $textStyleInBorderedCell    = [
            'indent'        => 0.2,
            'textAlignment' => TextAlignment::CENTER,
            'spaceBefore'   => 25,
            'spaceAfter'    => 25,
        ];
        $textStyleWithoutBorderCell = [
            'textAlignment' => TextAlignment::CENTER,
            'spaceBefore'   => 25,
            'spaceAfter'    => 25,
        ];

        $tableStyle = [
            "cellMarginTop" => 50,
        ];

        $rowHeight = 350;

        $cellsVerticalAlign = ['valign' => 'center'];

        $phpWord->addTableStyle('myTable', $tableStyle);

        $midTableWidth                = 10700;
        $firstSectionSpaceWidth       = 750;
        $firstSectionFirstTableWidth  = $midTableWidth / 2 - $firstSectionSpaceWidth / 2;
        $firstSectionSecondTableWidth = $midTableWidth / 2 - $firstSectionSpaceWidth / 2;

        //  c. Création du tableau d'entête
        $mainTable = $section->addTable('myTable');
        $mainTable->addRow($rowHeight);

        //  d. Ajout de 3 colonnes pour les titres
        $mainTable->addCell($firstSectionFirstTableWidth)->addText(Trad::strBuild($trad->t("Commande N°@1@"), htmlspecialchars($commande['NO_CDE'], ENT_COMPAT, 'UTF-8')), null, $textStyleWithoutBorderCell + ['indent' => 1]);
        $mainTable->addCell($firstSectionSpaceWidth);
        $mainTable->addCell($firstSectionSecondTableWidth)->addText(Trad::strBuild($trad->t("Fournisseur N°@1@"), htmlspecialchars($fournisseur['ID_EXT'], ENT_COMPAT, 'UTF-8')), null, $textStyleWithoutBorderCell + ['indent' => 0.3]);

        //  e. Ajout de 3 tableaux : Celui de gauche, un pour créer un espace blanc, et celui de droite
        $parentTable = $section->addTable('myTable');
        $parentTable->addRow();

        // Cellule gauche (tableau 1)
        $cellLeft = $parentTable->addCell($firstSectionFirstTableWidth);
        // Cellule espace (vide)
        $cellMiddle = $parentTable->addCell($firstSectionSpaceWidth);
        // Cellule droite (tableau 2)
        $cellRight = $parentTable->addCell($firstSectionSecondTableWidth);

        // === TABLEAU DE GAUCHE: Détail Commande ===
        $tableLeft         = $cellLeft->addTable([
            'width'            => 100 * 50,
            'unit'             => 'pct',
            'borderSize'       => 12,
            'borderColor'      => '000000',
            'cellMarginTop'    => 400,
            'cellMarginBottom' => 200,
            'cellMarginRight'  => 400,
            // 'cellMarginLeft' => 250,
        ]);
        $mainTableLeftRow  = $tableLeft->addRow(3200, ['exactHeight' => true]);
        $mainTableLeftCell = $mainTableLeftRow->addCell($firstSectionFirstTableWidth);

        $dateMaxLivr       = $etatCommandeSpecifiqueService->getMaxDteLivCon($commande['NO_CDE'])['MAXDTELIVCON'] ?? '00000000';
        $centreDeLivraison = htmlspecialchars($centre->find(['CODE_CTR' => $commande['CTR_LIV']])['RAIS_SOC'] ?? '', ENT_COMPAT, 'UTF-8');

        $champsTableauCommande = [
            $trad->t('Facture N°')        => '',
            $trad->t('Période Comptable') => '',
            $trad->t('Batiment')          => $centreDeLivraison,
            $trad->t('Description')       => '',
            $trad->t('N° immos ou IEC')   => '',
            $trad->t('Dates MES')         => Date::dateConverte($dateMaxLivr),
        ];

        $innerTableLeft = $mainTableLeftCell->addTable('myTable');

        //  b. Mise en place du style des tableaux
        $cellStyleLeft  = ['valign' => 'center'];
        $cellStyleRight = [
            'borderColor' => '000000',
            'borderSize'  => 1,
        ] + $cellStyleLeft;

        foreach ($champsTableauCommande as $champs => $valeur) {
            $row = $innerTableLeft->addRow($rowHeight);
            $row->addCell(\intval($firstSectionFirstTableWidth / 2 + 100), $cellStyleLeft)->addListItem($champs, 0, null, null, $textStyleWithoutBorderCell);
            $row->addCell(\intval($firstSectionFirstTableWidth / 2 - 100), $cellStyleRight)->addText($valeur, null, $textStyleInBorderedCell);
        }


        // === TABLEAU DE DROITE: Détail Fournisseur ===
        $tableRight         = $cellRight->addTable([
            // 'width' => 100 * 50,
            // 'unit' => 'pct',
            // 'cellMarginTop' => 0
            'width'            => 100 * 50,
            'unit'             => 'pct',
            'borderSize'       => 12,
            'borderColor'      => '000000',
            'cellMarginBottom' => 200,
            'cellMarginRight'  => 400,
            'cellMarginTop'    => 50,
        ]);
        $mainTableRightRow  = $tableRight->addRow(3200, ['exactHeight' => true]);
        $cellStyleBorder    = [
            // 'borderColor' => '000000',
            // 'borderSize' => 1,
            // 'borderStyle' => 'single',
            // 'borderTopSize' => 1,
            // 'borderRightSize' => 1,
            // 'borderBottomSize' => 1,
            // 'borderLeftSize' => 1,
            // 'valign' => 'center',
        ];
        $mainTableRightCell = $mainTableRightRow->addCell($firstSectionSecondTableWidth, $cellStyleBorder);
        $innerTableRight    = $mainTableRightCell->addTable('myTable');

        // TODO: Revoir la création de cette partie
        $champsTableauFournisseurHeader = [
            $fournisseur['RS'],
            $fournisseur['ADR'],
            $fournisseur['VILLE'],
            '',
        ];

        foreach ($champsTableauFournisseurHeader as $key => $value) {
            $row = $innerTableRight->addRow($rowHeight);
            $row->addCell($firstSectionSecondTableWidth)->addText(
                $value,
                array_key_first($champsTableauFournisseurHeader) === $key
                ? ['bold' => true]
                : [],
                $textStyleWithoutBorderCell + ['indent' => 0.1]
            );
        }

        // TODO: A revoir également car plusieurs emails ?
        $champsTableauFournisseurDetails = [
            Trad::strBuild($trad->t("A l'attention de @1@"), htmlspecialchars($commande['CTCT_FOU'], ENT_COMPAT, 'UTF-8')),
            Trad::strBuild($trad->t('Tél : @1@'), htmlspecialchars($commande['TEL_CTCT'], ENT_COMPAT, 'UTF-8')),
        ];

        foreach ($champsTableauFournisseurDetails as $key => $value) {
            $row = $innerTableRight->addRow($rowHeight);
            $row->addCell($firstSectionSecondTableWidth)->addText(
                $value,
                array_key_first($champsTableauFournisseurDetails) === $key
                ? ['bold' => true]
                : [],
                $textStyleWithoutBorderCell + ($key > 0
                    ? ['indent' => 0.2]
                    : ['indent' => 0.1])
            );
        }

        // Email
        $row  = $innerTableRight->addRow($rowHeight);
        $cell = $row->addCell($firstSectionSecondTableWidth)->addTextRun($textStyleWithoutBorderCell + ['indent' => 0.2]);
        $cell->addText($trad->t('Email : '));
        if (!empty($commande['EMA_CTCT'])) {
            $cell->addLink('mailto:' . htmlspecialchars($commande['EMA_CTCT'], ENT_COMPAT, 'UTF-8'), htmlspecialchars($commande['EMA_CTCT'], ENT_COMPAT, 'UTF-8'), ['color' => 'blue', 'underline' => Font::UNDERLINE_SINGLE]);
        }

        // %%% SECONDE SECTION %%%%
        // --- STYLES ---

        // Style des tableaux visibles (bordures noires simples)
        $tableStyleName = 'Fancy Table';
        $tableStyle     = [
            'borderSize'  => 1,
            'borderColor' => '000000',
            'cellMargin'  => 80,
            'alignment'   => JcTable::CENTER,
            'valign'      => 'center',
        ];
        $phpWord->addTableStyle($tableStyleName, $tableStyle);

        // Style pour le tableau de mise en page (invisible)
        $layoutTableStyle = [
            'borderSize' => 0,
            'cellMargin' => 0,
        ];

        $signataires = $etatCommandeSpecifiqueService->getAllSignataireCDE($idCommande);
        $signataires = $etatCommandeSpecifiqueService->getAllSignataireDA($idCommande);

        if ($signataires !== []) {
            // --- CONTENU ---
            $section->addTextBreak(1);

            // 3. Partie Milieu : Tableau large (5 colonnes, grande hauteur)
            $midTable = $section->addTable('myTable');

            // Header row
            $midTable->addRow($rowHeight);
            $fontStyleEntete = [
                "bold" => true,
            ];
            $midTable->addCell($midTableWidth, ['gridSpan' => 5])->addText($trad->t("Détails visas : Commandes"), $fontStyleEntete);

            $midTable->addRow($rowHeight);

            $enteteColonnesMidTable = [
                $trad->t("Nom"),
                $trad->t("Fonction"),
                $trad->t("Rôle et commentaire"),
                $trad->t("Date et Heure"),
                $trad->t("Image"),
            ];
            $cellStyle              = [
                'borderSize'  => 1,
                'borderColor' => '000000',
                'valign'      => 'center',
            ];

            foreach ($enteteColonnesMidTable as $label) {
                $column = new TableColumn($label, $midTableWidth / 5, $cellStyle);
                $midTable->addCell($column->width, $column->style)->addText($column->label, $fontStyleEntete, $textStyleInBorderedCell);
            }

            $detailsSignataires = $hastutil->findAll(["CODE" => array_column($signataires, "SIGNAT")]);
            $signatairesOnKey   = array_column($signataires, null, 'SIGNAT');

            $mergedArrays = array_map(
                fn($utilisateur) => array_merge($utilisateur, $signatairesOnKey[$utilisateur['CODE']] ?? []),
                $detailsSignataires,
            );

            foreach ($mergedArrays as $signataire) {
                $midTable->addRow($rowHeight);

                $midTable->addCell(
                    $midTableWidth / 5,
                    $cellStyle,
                )->addText(
                    htmlspecialchars($signataire['SIGNAT'], ENT_COMPAT, 'UTF-8'),
                    null,
                    $textStyleInBorderedCell,
                );

                $midTable->addCell(
                    $midTableWidth / 5,
                    $cellStyle,
                )->addText(
                    htmlspecialchars($signataire['FONCTION'], ENT_COMPAT, 'UTF-8'),
                    null,
                    $textStyleInBorderedCell,
                );

                if (!empty($signataire['NM_COMME'])) {
                    $value = $memos->getValue($signataire['NM_COMME']) ?? '';
                    $value = htmlspecialchars($value, ENT_COMPAT, 'UTF-8');

                    $midTable->addCell(
                        $midTableWidth / 5,
                        $cellStyle,
                    )->addText(
                        $value,
                        null,
                        $textStyleInBorderedCell,
                    );
                } else {
                    $midTable->addCell(
                        $midTableWidth / 5,
                        $cellStyle,
                    );
                }

                $midTable->addCell(
                    $midTableWidth / 5,
                    $cellStyle,
                )->addText(
                    Date::dateConverte($signataire['DTE']) . ' ' . Date::heureConverte($signataire['HEURE']),
                    null,
                    $textStyleInBorderedCell,
                );

                if (!empty($signataire['IMAGSIG'])) {
                    $midTable->addCell(
                        $midTableWidth / 5,
                        $cellStyle,
                    )->addImage(
                        str_replace('%_images%', Fichier::getDirImg(), $signataire['IMAGSIG']),
                        [
                                'alignment'     => Jc::CENTER,
                                'valign'        => 'center',
                                'width'         => 100,
                                'height'        => 50,
                                'marginTop'     => -1,
                                'marginLeft'    => -1,
                                'wrappingStyle' => 'behind',
                            ],
                    );
                } else {
                    $midTable->addCell(
                        $midTableWidth / 5,
                        $cellStyle,
                    );
                }
            }
        }

        $section->addTextBreak(1);

        // 4. Partie Basse : Tableau large
        $bottomTable = $section->addTable('myTable');

        $bottomTable->addRow($rowHeight, ['tblHeader' => true]);
        $enteteColonnesBottomTable = [
            $trad->t("Désignation")   => (int) $midTableWidth * 25 / 100,
            $trad->t("Qté commande")  => (int) $midTableWidth * 25 / 100,
            $trad->t("Qté réception") => (int) $midTableWidth * 10 / 100,
            $trad->t("P.U.")          => (int) $midTableWidth * 20 / 100,
            $trad->t("Prix total")    => (int) $midTableWidth * 20 / 100,
        ];
        $cellStyle                 = [
            'valign'    => 'center',
            'alignment' => JcTable::START,
        ];
        $fontStyleEntete           = [
            "bold" => true,
        ];
        foreach ($enteteColonnesBottomTable as $label => $width) {
            $column = new TableColumn($label, (int) $midTableWidth / 5, $cellStyle);
            $bottomTable->addCell($column->width, $column->style)->addText($column->label, $fontStyleEntete);
        }

        foreach ($lignesDeCommande as $key => $ligne) {
            $unite = $unites->find(['CODE_UNI' => $ligne['UNITE']]);
            // Récupération de la valeur du champ supp. "OTP", toujours en premier champs cf LPU
            $codeEnr             = ChampSupp::autoCompletCodeEnr($ligne['NO_CDE'], $ligne['NO_PO']);
            $valeurChampsSuppOTP = $csDon->find([
                "COD_TAB" => "CA_LIGNE",
                "COD_ENR" => $codeEnr,
                "NUM_FIX" => 1,
            ])["VALEUR"] ?? "";

            $bottomTable->addRow($rowHeight);
            $cellulesColonnesArticles = [
                $ligne['DES_SOMM'],
                Outils::qteByUnite($this->pdo, $ligne['QTE_COMM'], $ligne['UNITE']) . ' ' . $ligne['UNITE'],
                bccomp($ligne['QTE_COMM'], $ligne['RAL'], 0) == 0
                ? '0 ' . $ligne['UNITE']
                : Outils::qteByUnite($this->pdo, bcsub($ligne['QTE_COMM'], $ligne['RAL'], (int) $unite['NB_DECIM']), $ligne['UNITE']) . ' ' . $ligne['UNITE'],
                Outils::formatMontant($ligne['PU']) . ' ' . $commande['DEVISE'],
                Outils::formatMontant(bcmul($ligne['PU'], $ligne['QTE_COMM'], Constante::montantDecimal)) . ' ' . $commande['DEVISE']
            ];

            foreach ($cellulesColonnesArticles as $key => $label) {
                $column = new TableColumn($label, (int) $midTableWidth / 5, $cellStyle);
                $bottomTable->addCell($column->width, $column->style)->addText($column->label, $key > 2 ? ['alignment' => JcTable::END] : [], ['spaceAfter' => $rowHeight / 4, 'keepNext' => true]);
            }

            $bottomTable->addRow($rowHeight);
            $bottomTable->addCell($midTableWidth / 4, $cellStyle)->addText($trad->t('Référence article fournisseur :'), ['bold' => true], ['keepNext' => true]);
            $bottomTable->addCell($midTableWidth / 4, $cellStyle)->addText(htmlspecialchars($ligne['REF_FOUR']??'', ENT_COMPAT, 'UTF-8'), ['keepNext' => true]);

            $bottomTable->addRow($rowHeight);
            $bottomTable->addCell($midTableWidth / 4, $cellStyle)->addText($trad->t('Nature comptable :'), ['bold' => true], ['keepNext' => true]);
            $bottomTable->addCell($midTableWidth / 4, $cellStyle)->addText(htmlspecialchars($ligne['SSCPTEANA'], ENT_COMPAT, 'UTF-8'), ['keepNext' => true]);
            if ($valeurChampsSuppOTP !== "") {
                $bottomTable->addCell($midTableWidth / 4, $cellStyle)->addText($trad->t('Elément OTP :'), ['bold' => true], ['keepNext' => true]);
                $bottomTable->addCell($midTableWidth / 4, $cellStyle)->addText(htmlspecialchars($valeurChampsSuppOTP, ENT_COMPAT, 'UTF-8'), null, ['keepNext' => true]);
            } else {
                $bottomTable->addCell($midTableWidth / 4, $cellStyle)->addText($trad->t('Centre de coût :'), ['bold' => true], ['keepNext' => true]);
                $bottomTable->addCell($midTableWidth / 4, $cellStyle)->addText(htmlspecialchars($ligne['SECTIMP'], ENT_COMPAT, 'UTF-8'), null, ['keepNext' => true]);
            }
            if (array_key_last($lignesDeCommande) != $key) {
                $bottomTable->addRow(\intval($rowHeight / 1.5), ['exactHeight' => true])->addCell($midTableWidth, $cellStyle)->addText('', [], ['keepLines' => true]);
            }
        }

        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
        $fileName  = "Etat_Specifique_ROLEX_Commande_{$idCommande}_du_" . date('d_m_Y') . '.docx';

        if (Fichier::fileExisteTmp($fileName)) {
            Fichier::deleteFichierTmp($fileName);
        }

        $objWriter->save($parseBase1->getRep()->tmp . '/' . $fileName);

        return Fichier::UploadClient($parseBase1->getRep()->tmp . '/' . $fileName, $fileName);
    }
}
