<?php

namespace Modules\API\APIInterne\OxaMobility\Outil;

use Helpers\ExportTo\Generate;
use Modules\Ajax\Repository\Listes;
use Helpers\Session\ParseBase1;

class ExportArticle
{
    /** @var \PDO $pdo */
    private \PDO $pdo;

    /** @var array<mixed> $body */
    private array $body;

    /** @var array<mixed> $zipFiles */
    private array $zipFiles;

    /** @var int $nbFile */
    private int $nbFile = 1;

    /**
     * @param \PDO $pdo
     * @param array<mixed> $body
     */
    public function __construct(\PDO $pdo, array $body)
    {
        $this->pdo = $pdo;
        $this->body = $body;
    }

    /**
     * @return array<mixed>
     */
    public function exportArticles()
    {
        $listes = new Listes($this->pdo);

        $params = [
            'SITE' => $this->body['CodeSite'],
        ];

        $articles = $listes->getListArticlesSiteStock($params);
        // @phpstan-ignore-next-line
        $nbArticles = count($articles);

        if ($nbArticles > $this->body['NbLigParFichier']) {
            $this->createMultipleFiles($articles);
        } else {
            $fileName   = $this->body['CodeSite'].uniqid();
            $csv        = [];
            // @phpstan-ignore-next-line
            foreach ($articles as $article) {
                $this->incrementArray($csv, $article);
            }
            $zipPath = (new ParseBase1())->getRep()->tmp.$fileName.'.zip';

            $this->buildCsvAndZip($csv, $fileName, $zipPath);
            $this->zipFiles = [
                $fileName.'.zip',
            ];
        }

        return [
            'nbFile' => $this->nbFile,
            'zipFiles' => $this->zipFiles
        ];
    }

    /**
     * @param mixed $articles
     * @return void
     */
    private function createMultipleFiles($articles)
    {
        $uniqid         = uniqid();
        $iLine          = 1;
        $createFileNow  = false;
        $csv            = [];
        $zipFiles       = [];
        // @phpstan-ignore-next-line
        foreach ($articles as $article) {
            $this->incrementArray($csv, $article);
            $createFileNow = false;

            if ($iLine >= $this->body['NbLigParFichier']) {
                $this->generateCSV($csv, $uniqid, $zipFiles);
                $createFileNow  = true;
                $iLine          = 0;
                $csv            = [];
                $this->nbFile++;
            }

            $iLine++;
        }
        if (!$createFileNow) {
            $this->generateCSV($csv, $uniqid, $zipFiles);
        }

        $this->zipFiles = $zipFiles;
    }

    /**
     * incrementArray
     *
     * @param  array<mixed> $csv
     * @param  array<mixed> $article
     * @return void
     */
    private function incrementArray(array &$csv, array $article)
    {
        $csv[] = [
            $article['CODE_ART'],
            $article['DESIGN'],
            $article['EMPLAC'],
            $article['UNITE_STK'],
            $article['FERME'],
            number_format($article['VAL_LOCAL'], 5, '.', ' '),
            $article['TYPE_VALO'],
        ];
    }

    /**
     * @param array<mixed> $array
     * @param string $fileName
     * @param string $zipPath
     * @return void
     */
    private function buildCsvAndZip($array, $fileName, $zipPath)
    {
        $file       = new Generate($fileName, 'csvV2', $array, [], false, false);
        $array      = explode('\\', $file->urlCsv);
        $csvName    = end($array);

        $zip = new \ZipArchive();
        $zip->open($zipPath, \ZipArchive::CREATE);
        $zip->addFile($file->urlCsv, $csvName);
    }

    /**
     * generateCSV
     *
     * @param  array<mixed> $csv
     * @param  string $uniqid
     * @param  array<mixed> $zipFiles
     * @return void
     */
    private function generateCSV(array $csv, string $uniqid, array &$zipFiles)
    {
        $fileName   = $this->body['CodeSite'].'_'.$uniqid.'_'.str_pad((string)$this->nbFile, 2, '0', STR_PAD_LEFT);
        $zipPath    = (new ParseBase1())->getRep()->tmp.$fileName.'.zip';
        $zipFiles[] = $fileName.'.zip';
        $this->buildCsvAndZip($csv, $fileName, $zipPath);
    }
}
