<?php
namespace Modules\API\APIInterne\Magic\Controller;

use Modules\API\APIInterne\Magic\Service\MatchArrayProperty;
use Modules\API\Authenticate\Service\AuthService;
use GuzzleHttp\Psr7\Response;
use Helpers\Fichier\Fichier;
use Modules\API\APIInterne\Magic\Service\Files;
use Modules\API\APIInterne\Magic\WebService\Export;
use SimpleXMLElement;

class ExportController extends AbstractController implements InterfaceController
{
    protected Files $files;
    protected AuthService $authService;
    protected $body;
    protected array $header;
    
    public function execAction() : Response
    {

        $importService = new Export();

        // TODO : validate each field of $this->body

        $retourWSDL = $importService->exportWSDL(
            strtoupper($this->request->getAttribute('document')),
            $this->body['Mode'] ?? '',
            $this->body['CodeInterface'] ?? '',
            $this->body['NumJournal'] ?? '',
            $this->body['ID_1'] ?? '',
            $this->body['ID_2'] ?? '',
            $this->body['ID_3'] ?? '',
            $this->body['ID_4'] ?? '',
            $this->body['ID_5'] ?? '',
            $this->body['Date'] ?? '',
            $this->header['HTTP_CODECONNECTEUR'] ?? '',
            $this->header['HTTP_CODEVERSION'] ?? '',
            $this->header['HTTP_CODESOCIETE'] ?? ''
        );

        $reponse = new \SimpleXMLElement($retourWSDL->responseData);
        $statut = $reponse->Status;

        switch ((int)$statut) {
            case 200:
            case 202:
                if (isset($reponse->FichierExport) && (string)$reponse->FichierExport != '') {
                    $contentFile = Fichier::getContentFile((string)$reponse->FichierExport);
                    $reponse = $reponseExport = new SimpleXMLElement((string)$contentFile);
                }
                break;
        }

        $nodeName = '';
        if (isset($reponseExport->Record)) {
            $nodeName = 'Record';
        } elseif (isset($reponseExport->Document)) {
            $nodeName = 'Document';
        }


        

        if (!empty($nodeName) && isset($reponseExport)) {// TODO : why ?
            $name = $reponseExport->getName();
            $reponse = [$name => []];
            
            $response[$name]["JournalExtract"] = (string) $reponseExport->JournalExtract;

            $response[$name][$nodeName] = [];

            foreach ($reponseExport->Record as $record) {
                /** @phpstan-ignore-next-line */
                $response[$name][$nodeName][] = (array) $record;
            }

            $document = $this->request->getAttribute('document');
            $service = new MatchArrayProperty($document);
            $response = $service->checkMissingArray($response, $name, $nodeName);
        } else {
            $response = str_replace('{}', '""', (string)json_encode($reponse));
            $response = json_decode($response, true);
            if (empty($response)) {
                $response = [];
            }

            if (isset($reponseExport) && $reponseExport->getName() == 'FAR') {
                // Force Regroupement & Regroupement.Record as sequential array
                $response = $this->forceSequentialArray($response, 'Regroupement');
                foreach ($response['Regroupement'] as &$item) {
                    $item = $this->forceSequentialArray($item, 'Record');
                    foreach ($item['Record'] as &$record) {
                        $record['Lignes_FAR'] = $this->forceSequentialArray($record['Lignes_FAR'], 'Ligne');
                    }
                    unset($record);
                }
                unset($item);
            }
            
            $response[isset($reponseExport) ? $reponseExport->getName() : ucwords(strtolower($this->body['CodeInterface']))] = [
                "JournalExtract"    => (string) $response["JournalExtract"],
                "Record"            => []
            ];
            unset($response["JournalExtract"]);
        }

        return new Response(
            (int)$statut,
            [
                'Content-Type' => 'application/json'
            ],
            str_replace('{}', '""', (string)json_encode($response))
        );
    }

    /**
     * Due to xml nature, depth can be lost, this function restore this depth
     * @param array<mixed> $subject
     * @return array<mixed>
     */
    private function forceSequentialArray(array $subject, string $key)
    {
        if (array_key_exists($key, $subject) && array_is_list($subject[$key])) {
            return $subject;
        }
        
        $subject[$key] = [$subject[$key]];
        return $subject;
    }
}
