<?php

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use YesWiki\Bazar\Field\CheckboxField ;
use YesWiki\Bazar\Field\EmailField ;
use YesWiki\Bazar\Field\EnumField ;
use YesWiki\Bazar\Field\ImageField ;
use YesWiki\Bazar\Field\MapField ;
use YesWiki\Bazar\Service\FormManager ;
use YesWiki\Core\Service\AclService ;
use YesWiki\Wiki ;

// get services
$formManager = $this->wiki->services->get(FormManager::class);
$aclService = $this->wiki->services->get(AclService::class);

$dataList = [];
$colors = [];
$icons = [];
$columnsInfo = [];
$sanitizedParams = [];
$optionsIfDisplayvaluesinsteadofkeys = [];

if (count($fiches)>0) {
    $formId = $fiches[array_key_first($fiches)]['id_typeannonce'] ?? null;
    $form = $formManager->getOne($formId);
    if (!empty($form)) {
        $fields = $form['prepared'];
        
        /*	Parameters  */
        foreach([
            'columntitles' => 'columnTitlesNames',
            'columnfieldsids' => 'columnFieldsIdsRaw',
            'sumfieldsids' => 'sumFieldsIds',
            ] as $paramKey => $varName){
            $tmp = (isset($params[$paramKey]) && is_string($params[$paramKey])) ? $params[$paramKey] : "";
            $tmp = array_filter(
                array_map('trim', explode(',', trim($tmp))),
                function ($name) {
                    return !empty($name);
                }
            );
            extract([$varName => $tmp]);
        }


        $checkboxFieldsInColumns = $params['checkboxfieldsincolumns'] ?? null;
        $checkboxFieldsInColumns = !in_array($checkboxFieldsInColumns, ["0",0,false,"false","non"], true);

        foreach(['displayadmincol','displaycreationdate','displaylastchangedate','displayowner'] as $paramName){
            $paramValue = (!empty($params[$paramName]) && in_array($params[$paramName], ['yes','onlyadmins'], true)) ? $params[$paramName] : false;
            switch ($paramValue) {
                case 'onlyadmins':
                    $paramValue = $this->wiki->UserIsAdmin();
                    break;
                case 'yes':
                    $paramValue = true;
                    break;
                case false:
                default:
                    $paramValue = false;
                    break;
            }
            $sanitizedParams[$paramName] = $paramValue;
        }
        $sanitizedParams['displayvaluesinsteadofkeys'] = !isset($params['displayvaluesinsteadofkeys']) ? false : filter_var($params['displayvaluesinsteadofkeys'],FILTER_VALIDATE_BOOLEAN);
        $sanitizedParams['exportallcolumns'] = !isset($params['exportallcolumns']) ? false : filter_var($params['exportallcolumns'],FILTER_VALIDATE_BOOLEAN);
        $sanitizedParams['displayimagesasthumbnails'] = !isset($params['displayimagesasthumbnails']) ? false : filter_var($params['displayimagesasthumbnails'],FILTER_VALIDATE_BOOLEAN);

        $sanitizedParams['columnswidth'] = [];
        if (isset($params['columnswidth']) && is_string($params['columnswidth'])){
            foreach(explode(',',$params['columnswidth']) as $columnInfo){
                $columnInfoExtracted = explode('=',$columnInfo);
                if (!empty($columnInfoExtracted[0]) && !empty($columnInfoExtracted[1])){
                    $sanitizedParams['columnswidth'][$columnInfoExtracted[0]] = $columnInfoExtracted[1];
                }
            }
        }

        /* columnsInfo */
        if (!function_exists('tableauGetFieldsCols')) {
            function tableauGetFieldsCols($field, $checkboxFieldsInColumns, $displayimagesasthumbnails): array
            {
                $propertyName = $field->getPropertyName();
                if (empty($propertyName)) {
                    return [];
                }
                
                $fieldLabel = $field->getLabel();
                if ($field instanceof MapField) {
                    $cols = [];
                    $cols[]  = [
                        'propertyName' => $propertyName,
                        'title' => _t('BAZ_LATITUDE'),
                        'key' => null,
                        'mapFieldId' => $field->getLatitudeField(),
                        'multivalues' => false];
                    $cols[]  = [
                        'propertyName' => $propertyName,
                        'title' => _t('BAZ_LONGITUDE'),
                        'key' => null,
                        'mapFieldId' => $field->getLongitudeField(),
                        'multivalues' => false];
                    return $cols;
                } elseif ($field instanceof CheckboxField && $checkboxFieldsInColumns) {
                    $options = $field->getOptions();
                    if (empty($options)) {
                        return [];
                    } else {
                        $cols = [];
                        foreach ($options as $key => $optionName) {
                            $cols[] = [
                                'propertyName' => $propertyName,
                                'title' => "$fieldLabel - $optionName",
                                'key' => $key,
                                'mapFieldId' => null,
                                'multivalues' => false];
                        }
                        return $cols;
                    }
                } else {
                    return [['propertyName' => $propertyName, 'title' => $fieldLabel, 'key' => null,
                        'mapFieldId' =>  null,
                        'multivalues' => $field instanceof CheckboxField]+(
                            $displayimagesasthumbnails && $field instanceof ImageField
                            ? ['imageAsThumbnail' => true]
                            :[]
                        )];
                }
            }
        }
        /* options when displaying values */
        if (!function_exists('tableauGetOptionsForField')) {
            function tableauGetOptionsForField($field,&$optionsIfDisplayvaluesinsteadofkeys,$sanitizedParams){
                $propertyName = $field->getPropertyName();
                if ($sanitizedParams['displayvaluesinsteadofkeys'] &&
                    $field instanceof EnumField && 
                    !isset($optionsIfDisplayvaluesinsteadofkeys[$propertyName])){
                    $optionsIfDisplayvaluesinsteadofkeys[$propertyName] = $field->getOptions();
                }
            }
        }

        if (empty($columnFieldsIdsRaw)) {
            // if no title, display all fields
            foreach ($fields as $field) {
                foreach (tableauGetFieldsCols($field, $checkboxFieldsInColumns, $sanitizedParams['displayimagesasthumbnails']) as $col) {
                    $columnsInfo[] = $col;
                }
                tableauGetOptionsForField($field,$optionsIfDisplayvaluesinsteadofkeys,$sanitizedParams);
            }
        } else {
            foreach ($columnFieldsIdsRaw as $fieldId) {
                $field = $formManager->findFieldFromNameOrPropertyName($fieldId, $formId);
                if (!empty($field)) {
                    foreach (tableauGetFieldsCols($field, $checkboxFieldsInColumns, $sanitizedParams['displayimagesasthumbnails']) as $col) {
                        $columnsInfo[] = $col;
                    }
                    tableauGetOptionsForField($field,$optionsIfDisplayvaluesinsteadofkeys,$sanitizedParams);
                }
            }
            if ($sanitizedParams['exportallcolumns']) {
                $alreadyDefinedPropertyNames = array_map(function ($col){
                    return $col['propertyName'];
                },$columnsInfo);
                foreach ($fields as $field) {
                    $fieldPropertyName = $field->getPropertyName();
                    if (!empty($fieldPropertyName) && !in_array($fieldPropertyName,$alreadyDefinedPropertyNames)){
                        foreach (tableauGetFieldsCols($field, $checkboxFieldsInColumns, $sanitizedParams['displayimagesasthumbnails']) as $col) {
                            $columnsInfo[] = array_merge($col,[ 'not-visible' => true ]);
                        }
                        tableauGetOptionsForField($field,$optionsIfDisplayvaluesinsteadofkeys,$sanitizedParams);
                    }
                }
            }
        }

        /* append extra cols */
        foreach([
                'displaycreationdate' => [
                        'fieldName'=>'date_creation_fiche',
                        'translationKey'=>'BAZ_DATE_CREATION'
                    ],
                'displaylastchangedate' => [
                    'fieldName'=>'date_maj_fiche',
                    'translationKey'=>'BAZ_DATE_MAJ'
                ],
                'displayowner' => [
                    'fieldName'=>'owner',
                    'translationKey'=>'TEMPLATE_OWNER'
                ],
            ] as $paramName => $data){
            if (isset($sanitizedParams[$paramName]) && $sanitizedParams[$paramName]){
                $columnsInfo[] = [
                    'propertyName' => $data['fieldName'],
                    'title' => _t($data['translationKey']),
                    'key' => null,
                    'mapFieldId' => null
                ];
            }
        }

        /* columnTitles custom */
        if (!empty($columnTitlesNames)) {
            foreach ($columnTitlesNames as $key => $value) {
                if (isset($columnsInfo[$key]) && !empty($value)) {
                    $columnsInfo[$key]['title'] = $value;
                }
            }
        }

        /* sanitize emails */
        if (!$this->wiki->UserIsAdmin()){
            foreach($fiches as $index => $fiche){
                $formId = $fiche['id_typeannonce'];
                if (strval($formId) != strval(intval($formId))){
                    unset($fiches[$index]);
                } else {
                    $form = $formManager->getOne($formId);
                    if (empty($form['prepared'])){
                        unset($fiches[$index]);
                    } else {
                        foreach($form['prepared'] as $field){
                            if ($field instanceof EmailField && !$field->canRead($fiches[$index],null)){
                                $fiches[$index][$field->getPropertyName()] = "***@***.***";
                            } elseif (empty($field->renderStaticIfPermitted($fiche)) || 
                                empty(trim($field->renderStaticIfPermitted($fiche)))){
                                $fiches[$index][$field->getPropertyName()] = "";
                            } 
                        }
                    }
                }
            }
        }

        /* manage colors and icons */
        foreach($fiches as $fiche){
            $colors[$fiche['id_fiche']] = getCustomValueForEntry(
                $params['color'],
                $params['colorfield'],
                $fiche,
                ''
              );
            $icons[$fiche['id_fiche']] = getCustomValueForEntry(
                $params['icon'],
                $params['iconfield'],
                $fiche,
                ''
              );
        }
    } else {
        echo $this->render('@templates/alert-message.twig', [
            'type' => 'danger',
            'message' => _t('BAZ_NO_FORMS_FOUND'),
        ]);
    }
}
echo $this->render('@bazar/tableau.twig', [
    'infoRes' => $info_res ?? null,
    'params' => $param,
    'columnsInfo' => $columnsInfo,
    'entries' => $fiches,
    'sumFieldsIds' => $sumFieldsIds ?? null,
    'displayadmincol' => $sanitizedParams['displayadmincol'] ?? null,
    'displayvaluesinsteadofkeys' => $sanitizedParams['displayvaluesinsteadofkeys'] ?? null,
    'optionsIfDisplayvaluesinsteadofkeys' => $optionsIfDisplayvaluesinsteadofkeys,
    'aclService' => $aclService,
    'wiki' => $this->wiki,
    'colors' => $colors,
    'icons' => $icons,
    'columnswidth' => $sanitizedParams['columnswidth'] ?? [],
]);
