<?php
namespace Modules\EtatStatistiques\Controller;

use Entity\Model\Hastutil;
use Entity\Model\ReqFiltresDon;
use Helpers\Outil\ArrayHelper;
use Helpers\Pagination\PaginatorGestion;
use Modules\EtatStatistiques\Outil\EtatStatOutil;
use Modules\EtatStatistiques\Repository\EtatStatDataRepo;
use Modules\EtatStatistiques\Repository\EtatStatRepo;
use Skeleton\Controller\Controller;

class EtatStatTableauController extends Controller
{
    protected function getRepo() :EtatStatRepo
    {
        return new EtatStatRepo($this->getPdo());
    }

    protected function getDataRepo() :EtatStatDataRepo
    {
        $pdo = $this->getPdoOxaDw();
        if ($pdo === false) {
            throw new \Exception('DW is required');
        }
        return new EtatStatDataRepo($pdo);
    }

//_____________________________________________________________________________
// Actions

    /**
     * @return string|\GuzzleHttp\Psr7\Response
     */
    public function detailAction()
    {
        $id = $this->request->getAttribute('id');
        $post = $this->request->getParsedBody();
        $etatstat = $this->getRepo()->getDetail($id);
        if (empty($etatstat)) {
            return $this->create404Response();
        }

        return $this->renderer->render('@EtatStatistiques/Tableau/pageTableEtatStat', [
            'form_filter' =>
                array_map(
                    function ($filter) {
                        return $this->filterToInput($filter);
                    },
                    $etatstat['listFilter']
                ),
            'etatstat' => $etatstat,
            'post' => $post,
            'gestable' => $this->getGestable($etatstat),
        ]);
    }

    /**
     * @param array<mixed> $etatstat entity Etatstat
     * @return \stdClass
     */
    private function getGestable(array $etatstat)
    {

        $mainQuery = ArrayHelper::findFirst($etatstat['listQuery'], function ($query) {
            return !empty($query['listSelect']);
        });
        
        $data = $this->getDataRepo()->getData(
            $etatstat,
            $this->request->getParsedBody()
        ); // Must be executed before the getInfoPagination

        $firstRow = $data[0] ?? [];

        return (object) [
            'hasColSearch' => false,
            'listCol' => array_map(
                function ($select) use ($firstRow) {
                    return (object)[
                        'name' => $select['ELEM_SQL'],
                        'label' => $select['ELEM_ALIAS'],
                        'type' => $this->getSelectType($select, $firstRow),
                        'filter' => [
                            'type' => 'text',
                                // $select['RSEL_TYPE_DONNEE'] == 'A' 'N' 'D' ?  'text' : 'zoom'
                        ],
                    ];
                },
                $mainQuery['listSelect']
            ),
            'listRow' => $data,
            'pagination' => PaginatorGestion::getInfoPagination()
                + ['path' => $this->router->generateUri(
                    $this->router->getNameRoute(),
                    $this->request->getAttributes()
                )]
        ];
    }

    /**
     * @param array<mixed> $select
     * @param array<mixed> $firstRow
     */
    private function getSelectType(array $select, array $firstRow) :string
    {
        switch ($select['RSEL_TYPE_DONNEE']) {
            case 'D':
                return 'date';
            case 'N':
                // If the first value has a '.' -> assume it's an amount
                if (strpos($firstRow[ $select['ELEM_SQL'] ] ?? '', '.') !== false) {
                    return 'amount';
                }
                return 'integer';
        }
        return '';
    }

    /**
     * @param array<mixed> $filter entity ReqFiltres
     * @throws \Exception
     * @return \stdClass
     */
    private function filterToInput(array $filter)
    {
        $code = ReqFiltresDon::getInputId($filter);
        
        switch ($filter['TYPE_FILTRE']) {
            case 'USER':
                return (object) ([
                    'label' => $filter['LIB_FILTRE'],
                    'type' => 'ZOOM',
                    'name' => $code,
                ]
                + ($filter['FENT_TYPE_AFFICHAGE'] == 'L' ? [
                    'entity' => Hastutil::class,
                    'zoom_path' => 'EtatStatistique.ajaxListe.utilisateurEtatStat',
                    'zoom_path_param' => [// TODO : implements FormExtention
                        'userCode' => $filter['CODE_FILTRE'],
                    ],
                ] : [ // Assume $filter['FENT_TYPE_AFFICHAGE'] == 'R'
                    'entity' => Hastutil::class,
                    'zoom_path' => 'EtatStatistique.ajaxListe.acheteurEtatStat',
                    'zoom_path_param' => [// TODO : implements FormExtention
                        'memo' => $filter['FENT_NM_REQ_LIB'], // TODO : pass filter id instead ?
                        'bdd' => $filter['FENT_BASE_DE_DONNEE'],
                    ],
                ]));
            case 'STD':
                $info = EtatStatOutil::getFilterInfo($filter['CODE_FILTRE']);
                if ($info === null) {
                    throw new \Exception('Invalid code "'.$code.'"');
                }
                return (object) [
                    'label' => $filter['LIB_FILTRE'],
                    'type' => 'ZOOM',
                    'name' => $code,
                    'zoom_path' => $info['path'],
                    'zoom_path_param' => $info['path_param'] ?? [],
                ];
            case 'CS':
                return (object) [
                    'label' => $filter['LIB_FILTRE'],
                    'type' => ($filter['TYPE_DON_FILTRE'] == 'D' ? 'DATE' : 'ZOOM'),
                    'name' => $code,
                    // TODO : path zoom
                ];
            case 'LIBRE':
                return (object) [
                    'label' => $filter['LIB_FILTRE'],
                    'type' => ($filter['TYPE_DON_FILTRE'] == 'D' ? 'DATE' : 'TEXT'),
                    'name' => $code,
                ];
        }
        throw new \Exception('Invalid type "'.$filter['TYPE_FILTRE'].'"');
    }
}
