<?php
namespace Modules\Catalogue\Service;

use Entity\Model\FmtMapp;
use Entity\Model\FValDef;
use Entity\Model\MultiMapp;
use Entity\Model\RegValid;
use Entity\Model\Transcod;
use Helpers\Outil\ArrayHelper;
use Helpers\Session\ParseBase1;
use Modules\Catalogue\Repository\FormatRepository;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;

class MappingDefaultService
{

    const OCI = 'OCI';
    const CXML = 'cXML';

    /**
     * @var array<mixed>
     */
    private $listeChps = [
            'PROTOCOLE',
            'ORDRE',
            'TAG_XML',
            'LONGUEUR',
            'DESCRIPTION'
    ];

    /**
     * @var array<mixed>
     */
    private $orderParam = [
        self::OCI => [
            [
                'valeurMapping'     =>13,
                'valeurSTRUCATA'    =>1,
            ],
            [
                'valeurMapping'     =>11,
                'valeurSTRUCATA'    =>2,
            ],
            [
                'valeurMapping'     =>1,
                'valeurSTRUCATA'    =>3,
            ],
            [
                'valeurMapping'     =>9,
                'valeurSTRUCATA'    =>4,
            ],
            [
                'valeurMapping'     =>4,
                'valeurSTRUCATA'    =>7,
            ],
            [
                'valeurMapping'     =>14,
                'valeurSTRUCATA'    =>8,
            ],
            [
                'valeurMapping'     =>5,
                'valeurSTRUCATA'    =>13,
            ],
            [
                'valeurMapping'     =>7,
                'valeurSTRUCATA'    =>14,
            ],
            [
                'valeurMapping'     =>8,
                'valeurSTRUCATA'    =>25,
            ],
        ],
        self::CXML => [
            [
                'valeurMapping'     =>13,
                'valeurSTRUCATA'    =>1,
            ],
            [
                'valeurMapping'     =>11,
                'valeurSTRUCATA'    =>2,
            ],
            [
                'valeurMapping'     =>1,
                'valeurSTRUCATA'    =>3,
            ],
            [
                'valeurMapping'     =>1,
                'valeurSTRUCATA'    =>4,
            ],
            [
                'valeurMapping'     =>4,
                'valeurSTRUCATA'    =>7,
            ],
            [
                'valeurMapping'     =>14,
                'valeurSTRUCATA'    =>8,
            ],
            [
                'valeurMapping'     =>5,
                'valeurSTRUCATA'    =>13,
            ],
        ]
    ];

    private string $fichier;
    private string $typeMapping = '';

    /**
     * @var array<mixed>
     */
    private array $mapping = [];

    public function __construct(
        private Csv $reader,
        private ParseBase1 $parseBase1,
        private ArrayHelper $arrayHelper,
        private FmtMapp $FMTMAPP,
        private MultiMapp $multiMapp,
        private Transcod $transcod,
        private FValDef $fValDef,
        private RegValid $regValid
    ) {
        $this->fichier = $this->parseBase1->getRep()->etc.'\\Referentiel_PUNCHOUT.csv';
    }

    /**
     * @param string $typeMapping
     * @return void
     */
    public function setTypeMapping(string $typeMapping)  // OCI || cXML
    {
        $this->typeMapping = $typeMapping;
    }

    public function initializeMapping(string $ifFormat):void
    {
        $this->parseReferentielPunchout();

        $listeMapping = $this->mapping[$this->typeMapping];
        
        $this->FMTMAPP->delete(['IDFORMAT' => $ifFormat]);
        $this->multiMapp->delete(['IDFORMAT' => $ifFormat]);
        $this->transcod->delete(['IDFORMAT' => $ifFormat]);
        $this->fValDef->delete(['IDFORMAT' => $ifFormat]);
        $this->regValid->delete(['IDFORMAT' => $ifFormat]);

        foreach ($this->orderParam[$this->typeMapping] as $orderMap) {
            $mapping = $listeMapping[$orderMap['valeurMapping']];
            $this->FMTMAPP->insert([
                'IDFORMAT'      => $ifFormat,
                'LIGNE'         => $orderMap['valeurSTRUCATA'],
                'ACTIVE'        => true,
                'POSITION'      => 0,
                'LONGUEUR'      => 0,
                'ELEM_XML'      => $mapping['TAG_XML'],
                'TYPEMAPPING'   => 'S',
                'TYPECONTSTR'   => 'N',
            ]);
        }
    }

    private function parseReferentielPunchout():void
    {
        if (mb_detect_encoding($this->fichier) !== 'UTF-8') {
            $this->reader->setInputEncoding('Windows-1252');
        }
        $this->reader->setDelimiter(';');

        $spreadsheet = $this->reader->load($this->fichier);

        $sheet = $spreadsheet->getSheet(0);

        $highestRow = $spreadsheet->getActiveSheet()->getHighestRow();
        $listeLigne = [];
        for ($i=1; $highestRow > $i+1; $i++) {
            $ligne = [];

            $row = 0;
            foreach ($this->listeChps as $v) {
                $valueCell = $this->parseCell($sheet, $i+1, $row+1);

                if ($valueCell === null) {
                    $valueCell = '';
                }

                $ligne[$v] = $valueCell;
                $row ++;
            }

            $listeLigne[] = $ligne;
        }

        $mappingTmp = $this->arrayHelper::indexBy($listeLigne, 'PROTOCOLE');

        $mapping = [];
        foreach ($mappingTmp as $k => $byType) {
            foreach ($byType as $m) {
                $mapping[$k][$m['ORDRE']] = $m;
            }
        }

        $this->mapping = $mapping;
    }

    /**
     * Summary of parseCell
     * @param Worksheet $sheet
     * @param mixed $row
     * @param mixed $column
     * @return mixed $value
     */
    private function parseCell($sheet, $row, $column)
    {
        return $sheet->getCell([
            intval($column),
            intval($row)
        ])->getValue();
    }

    /**
     * @return array<mixed>
     */
    public function getListeMapping()
    {
        $this->parseReferentielPunchout();

        return $this->mapping[$this->typeMapping];
    }
}
