<?php
namespace Modules\GlobalApplication\Controller;

use Helpers\ChampsSupplementaire\ChampSupp;
use Helpers\Outil\ArrayHelper;
use Helpers\Outil\Date;
use Helpers\Outil\Sql;
use Helpers\QueryBuilder\EntityTool;
use Helpers\QueryBuilder\QueryBuilder;
use Skeleton\Controller\Controller;

abstract class AbsExportController extends Controller
{
    /**
    * @return string[]
    */
    abstract protected function getExportTab(): array;

    /**
     * @param array<mixed> $post
     * @return array<string,string> list of selected fields (indexed by themself)
     */
    protected function extractFieldList(array $post) :array
    {
        $arrayMultiSelect = ArrayHelper::filterByKey($post, function ($k) {
            return str_starts_with($k, 'multiSelectexport');
        });

        // Filter any unauthorized fields
        $arrayMultiSelect = array_intersect(
            $arrayMultiSelect,
            $this->getExportTab()
        );

        // Key == Value
        return array_combine($arrayMultiSelect, $arrayMultiSelect);
    }

    /**
     * @param array<mixed> $mapArchi
     * @param array<mixed> $listFieldSelected
     * @return array<string, string>
     */
    protected function getEntityTitle(
        array $mapArchi,
        string $table, // TODO : deduce from $entityRepo
        array $listFieldSelected
    ) {
        $tab = [];
        foreach ($mapArchi as $k => $value) {
            $key = $table.'.' . $k;
            if (in_array($key, $listFieldSelected)) {
                $tab[$key] = $value['nomChamp'];
            }
        }
        return $tab;
    }

    /**
     * Get a list of field associated to an entity
     * with it's table name
     * including special field (CS & MEMO)
     * @return array<string>
     */
    protected function getFieldListFullPath(QueryBuilder $qb) :array
    {
        $trad = $this->getTranslationService();

        $tab = [];
        foreach ($qb->getArchitecture($trad) as $key => $value) {
            if (($value['type'] ?? null) == 'MEMO') {
                $tab[] = $qb->getTable() . '.MEMOS.' . $key;
                continue;
            }
            
            $tab[] = $qb->getTable() . '.' . $key;
        }

        $listeTmpCS = (new ChampSupp($this->pdo))->getSchema($qb->getTable());

        foreach ($listeTmpCS as $cs) {
            $tab[] = $qb->getTable() . '.CS_DON.' . $cs['NUM_FIX'];
        }
        return $tab;
    }

    /**
     *
     * @param string $path
     * @param bool $fullLabel
     * @return string
     */
    protected function getTabLabel(string $path, bool $fullLabel = false): string
    {
        $trad = $this->getTranslationService();
        // list($table, $second, $third) = explode('.', $path);
        $a = explode('.', $path);
        $table = $a[0];
        $second = $a[1];
        $third = $a[2] ?? null;

        $qb = QueryBuilder::getEntityFromTable($table, $this->pdo);

        $prefix = ($fullLabel ?
            $this->getEntityTaxonomyLabel($qb->getTaxonomie())
            . $trad->colon() : '');

        // Case : special field CS
        if ($second == 'CS_DON') {
            $numfix = intval($third);
            $config = (new ChampSupp($this->pdo))->getinfoOneCs($qb->getTable(), $numfix);
            return $prefix . $trad->t('CS') . ' - ' . $config['NOM'];
        }


        $field = ($second == 'MEMOS' ? $third : $second);

        return $prefix . ($qb->getArchitecture($trad)[ $field ]['nomChamp'] ?? 'Unknown');
    }

    protected function getEntityTaxonomyLabel(int $taxo) :string
    {
        $trad = $this->getTranslationService();
        switch ($taxo) {
            case 1:
                return $trad->t('Entête');
            case 2:
                return $trad->t('Ligne');
        }
        return $trad->t('Autre');
    }

    /**
     * @param array<mixed> $row
     * @return array<mixed>
     */
    protected function formatExportRow(array $row) :array
    {
        $trad = $this->getTranslationService();
        $cacheQb = [];
        $cacheQbArchi = [];


        foreach ($row as $path => $value) {
            // list($table, $second, $third) = explode('.', $path);
            $a = explode('.', $path);
            $table = $a[0];
            $second = $a[1];
            $third = $a[2] ?? null;

            if (str_starts_with($table, 'oxaExport')) {
                continue;
            }
            
            $qb = $cacheQb[ $table ] ?? ($cacheQb[ $table ] = QueryBuilder::getEntityFromTable($table, $this->pdo));
            if ($second == 'CS_DON') {
                $row[ $path ] = ChampSupp::formatValue(
                    (new ChampSupp($this->pdo))
                        ->getInfoCS($qb->getTable(), intval($third))
                        ['TYPE'],
                    $value,
                    $trad
                );
                continue;
            }

            if ($second == 'MEMOS') {
                continue;
            }
            $archi = $cacheQbArchi[ $table ] ?? ($cacheQbArchi[ $table ] = $qb->getArchitecture($trad));
            $row[ $path ] = EntityTool::formatFieldDisplay(
                $archi[ $second ],
                $value,
                $trad
            );
        }
        return $row;
    }
}
