<?php

namespace Modules\Parametrage\Facture\Controller;

use API\Agena\AgenaPartenaire;
use API\Partenaire\Exception\WsInvalidResponse;
use GuzzleHttp\Psr7\Response;
use Helpers\Form\FormBuilder;
use Helpers\Log\LogSysteme;
use Helpers\Trad\Trad;
use Modules\Facture\Repository\PartnDematRepo;
use Skeleton\Controller\Controller;

class ParametrageAgenaBranchController extends Controller
{

    /** @var array<mixed> as returned by FactureDematRepo::getPartenaire */
    private array $pdpConfig;
    private ?AgenaPartenaire $pdpPartn = null;

    /**
     * @return void|Response
     */
    public function init()
    {
        $pdpId = $this->request->getAttribute('pdp');

        $this->pdpConfig = (new PartnDematRepo($this->pdo))->getPartenaire($pdpId);

        if (($this->pdpConfig['PARTN'] ?? null) != 'AGN3') {
            return $this->create404Response();
        }
    }

    private function getPartAgena() :AgenaPartenaire
    {
        return $this->pdpPartn ?? ($this->pdpPartn = AgenaPartenaire::getFromConfig(
            $this->contenaire,
            $this->pdpConfig
        ));
    }

    public function indexAction() :string
    {
        try {
            $listBranch = $this->getPartAgena()->listBranch();
        } catch (WsInvalidResponse $e) {
            LogSysteme::prefixErrorLog((string) $e);
            return $this->renderer->render('@ParamFac/Demat/Branch/gestion', [
                'error' => 'WS_ERROR',
                'listRow' => [],
                'pdpConfig' => $this->pdpConfig,
            ]);
        }

        return $this->renderer->render('@ParamFac/Demat/Branch/gestion', [
            'listRow' => array_map(function ($item) {
                return $item + [
                    // 'menu' => $this->createMenuCont($item),
                ];
            }, $listBranch),
            'pdpConfig' => $this->pdpConfig,
        ]);
    }

    public function formExportAdrAction() :string
    {
        return $this->renderer->render('@ParamFac/Demat/Branch/formExportAdr', [
            'pdpConfig' => $this->pdpConfig,
            'listUser' => array_column(
                $this->getPartAgena()->listUser(),
                'labelFull',
                'id'
            ),
        ]);
    }

    public function exportAdrAction() :Response
    {
        $post = $this->request->getParsedBody();
        $partn = $this->getPartAgena();
        $trad = $this->getTranslationService();

        $validator = $this->createValidator();
        $validator->isStringAvecEspace('Identifiant', $post['InitialAdminUser'], 36, 36);

        if (! $validator->isValid()) {
            return new Response(400, [], $validator->getError());
        }

        $listSuccess = [];
        $listError = [];
        foreach ((new PartnDematRepo($this->pdo))->listAdrElec() as $adrElec) {
            try {
                $partn->createBranch([
                    'BusinessName' => $adrElec['Centre_RAIS_SOC'],
                    'InitialAdminUser' => $post['InitialAdminUser'],
                    'PpfDirectory' => $adrElec['ADR_FACELEC'],
                ]);
                $listSuccess[] = $adrElec['ADR_FACELEC'];
            } catch (WsInvalidResponse $e) {
                $listError[] = $adrElec['ADR_FACELEC'] . $trad->colon() . (string) $e->getResponse()->getBody();
            } catch (\Exception $e) {
                $listError[] = $adrElec['ADR_FACELEC'];
                LogSysteme::prefixErrorLog((string) $e);
            }
        }

        return new Response(
            ! empty($listError) ? 400 : 200,
            [],
            (! empty($listError)
                ? $trad->t('Export des l’adresse suivante a échoué') . $trad->colon() . '<br>'
                    . implode('<br>', $listError) . '<br>'
                : ''
            )
            . (! empty($listSuccess)
                ? $trad->t('Export des l’adresse suivante a réussit') . $trad->colon() . '<br>'
                    . implode('<br>', $listSuccess)
                : ''
            )
        );
    }

    public function formCreateAction() :string
    {
        return $this->renderer->render('@ParamFac/Demat/Branch/formBranchCreate', [
            'form' => $this->getFormBranchCreation(),
            'pdpConfig' => $this->pdpConfig,
        ]);
    }

    // public function formUpdateAction() :string
    // {
    //     return $this->renderer->render('@ParamFac/Demat/Branch/formBranchUpdate', [
    //         'form' => $this->getFormBranchUpdate(),
    //         'subject' => $this->getPartAgena()->getBranch(
    //             $this->request->getAttribute('id')
    //         ),
    //         'pdpConfig' => $this->pdpConfig,
    //     ]);
    // }

    public function createAction() :Response
    {
        $paId = $this->request->getAttribute('pdp');
        $post = $this->request->getParsedBody();

        $validator = $this->createFormValidator();
        $post = $validator->validateForm(
            $this->getFormBranchCreation(),
            $post
        );
        if (! $validator->isValid()) {
            return new Response(400, [], $validator->getError());
        }
        
        //_________

        
        $partn = $this->getPartAgena();

        try {
            $partn->createBranch($post);
        } catch (WsInvalidResponse $e) {
            LogSysteme::prefixErrorLog((string) $e);
            $trad = $this->getTranslationService();
            return new Response(400, [], $trad->t('Le webservice a retourné une erreur.'));
        }

        return new Response(200);
    }
    // public function updateAction() :Response
    // {
    //     $id = $this->request->getAttribute('id');
    //     $paId = $this->request->getAttribute('pdp');
    //     $post = $this->request->getParsedBody();

    //     $validator = $this->createFormValidator();
    //     $post = $validator->validateForm(
    //         $this->getFormBranchCreation(),
    //         $post
    //     );
    //     if (! $validator->isValid()) {
    //         return new Response(400, [], $validator->getError());
    //     }
        
    //     //_________

    //     $partn = AgenaPartenaire::getFromConfig(
    //         $this->contenaire,
    //         (new PartnDematRepo($this->pdo))->getPartenaire($paId)
    //     );

    //     try {
    //         $partn->updateBranch($id, $post);
    //     } catch (WsInvalidResponse $e) {
    //         LogSysteme::prefixErrorLog((string) $e);
    //         $trad = $this->getTranslationService();
    //         return new Response(400, [], $trad->t('Le webservice a retourné une erreur.'));
    //     }

    //     return new Response(200);
    // }

//_____________________________________________________________________________
// Sub-routine
    
    /**
     * @param array<mixed> $branch
     * @return array<mixed>
     */
    // private function createMenuCont(array $branch) :array
    // {
    //     $trad = $this->getTranslationService();
    //     $paramId = ['pdp' => $this->pdpConfig['ID'], 'id' => $branch['Id']];
    //     return [
    //         'listeSecondaire' => [
    //             // Update and delete are not available
    //             // [
    //             //     'libelle' => $trad->t('Modifier'),
    //             //     'route' => 'Parametrage.Agena.formUpdate',
    //             //     'routeParam' => $paramId,
    //             // ],
    //             // [
    //             //     'libelle' => $trad->t('Supprimer'),
    //             //     'lienJs' =>
    //             //         'popupConfirmSimple('
    //             //         . implode(',', [
    //             //             json_encode($trad->t('Confirmation')),
    //             //             json_encode(Trad::strBuild(
    //             //                 $trad->t('Êtes-vous sur de vouloir supprimer @1@'),
    //             //                 Trad::strBuild(
    //             //                     $trad->t('l’établissement @1@'),
    //             //                     $branch['BusinessName']
    //             //                 )
    //             //             )),
    //             //             json_encode($this->router->generateUri(
    //             //                 'Parametrage.Agena.delete',
    //             //                 $paramId
    //             //             )),
    //             //             '{}',
    //             //             '() => {window.location.reload()}'
    //             //         ])
    //             //         . ')',
    //             // ],
    //         ],
    //     ];
    // }

    /**
     * @return array<mixed>
     */
    private function getFormBranchCreation() :array
    {
        return $this->getFormView($this->getForm());
    }
    
    /**
     * @return array<mixed>
     */
    // private function getFormBranchUpdate() :array
    // {
    //     $form = $this->getFormView($this->getForm());
    //     unset($form['BusinessName']);
    //     unset($form['InitialAdminUser']);
    //     return $form;
    // }

    /**
     * @return array<\stdClass>
     */
    private function getForm()
    {
        $partn = $this->getPartAgena();
        return
            (new FormBuilder())
            // TODO : get a default InitialAdminUser
            //->addSelect('InitialAdminUser', ['TODO make a zoom instead ?'])
            ->addText('BusinessName', 512, [
                'validator' => ['mandatory' => true]
            ])
            ->addSelect(
                'InitialAdminUser',
                array_reduce(
                    $partn->listUser(),
                    fn($carry, $item) => $carry + [$item['Id'] => $item['Login']],
                    []
                ),
                ['validator' => ['mandatory' => true]]
            )
            ->addText('PpfDirectory', 300, [
                'validator' => ['mandatory' => true]
            ])
            // ->addText('Siren', 9)
            // ->addText('Siret', 14)
            // ->addText('BeKBO', 10)
            // ->addText('VatIntracomm', 15)
            ->build()
        ;
    }

    /**
     * @param array<mixed> $form
     * @return array<mixed>
     */
    private function getFormView(array $form)
    {
        foreach (FormBuilder::traverseForm($form) as $input) {
            $input->label = $this->getInputLabel($input->name);
        }
        return $form;
    }

    private function getInputLabel(string $inputName) :string
    {
        $trad = $this->getTranslationService();
        switch ($inputName) {
            case 'BusinessName':
                return $trad->t('Raison sociale');
            case 'InitialAdminUser':
                return $trad->t('Identifiant administrateur initial');
            case 'PpfDirectory':
                return $trad->t('Code routage (Adresse électronique)');
            // case 'Siren':
            //     return $trad->t('Siren');
            // case 'Siret':
            //     return $trad->t('Siret');
            // case 'BeKBO':
            //     return $trad->t('KBO');
            // case 'VatIntracomm':
            //     return $trad->t('TVA intracommunautaire');
        }
        return $inputName;
    }
}
