<?php
/**
 * Procedure Class
 *
 * @version     1.0.$Revision:$
 * @version     SVN: $Id:$
 * @package     bplan-base/globals
 * @subpackage  Procedures
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 * @copyright   Copyright (C) 2025, 2026 bplan-solutions GmbH & Co. KG <https://www.bplan-solutions.de/>
 * /Δ\
 */

namespace BplanBase\Globals\Services;


use BplanBase\Globals\Models\Tenant;
use BplanBase\Globals\Support\ModuleStorage;
use BplanModules\VisitorManagement\Repositories\AppointmentRepository;
use BplanModules\VisitorManagement\Repositories\EmployeeRepository;
use BplanModules\VisitorManagement\Repositories\VisitorRepository;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Storage;


/**
 * Procedure Class
 *
 * @version     1.2.0 / 2026-05-12
 * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
 */
class FillerService
{


/* +++ TRAITS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ CLASS CONSTANTS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ OBJECT MEMBERS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ CLASS MEMBERS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ */


/* +++ OBJECT METHODS +++ +++++++++++++++++++++++++++++++++++++++++++++++++++ */


    /**
     * Create the print-file
     *
     * @param       array $printData
     *
     * @param       string $dataFileName
     *              Der Name der Datendatei (json), ohne Dateiendung.
     *
     * @param       string|null $iniFileName
     *              Der Name der zu verwendenden ini-Datei.
     *
     * @param       string|null $outputFilePostfix
     *              Das Präfix für den Namen der Druckdatei.
     *
     *
     * @return      string  Die URL der erzeugten Druckdatei.
     *
     * @version     3.0.0 / 2026-05-12
     * @author      Wassilios Meletiadis <wassilios.meletiadis@bplan-solutions.de>
     */
    public function createPrintFile(array $printData, string $dataFileName, string|null $iniFileName = null, string|null $outputFilePostfix = null, string|null $pathExtension = null): string
    {
        /*
        **  Dateien werden global abgelegt, weil alle Prints über eine Ini laufen und so
        **  nur ein Zielpfad definiert werden kann. */
        $ModuleStorage = new ModuleStorage(false, null, false);

        $config = config('globals.filler');

        if($config['binary'] === null) {
            throw new Exception('No binary configured');

        } elseif (file_exists($config['binary']) === false) {
            throw new Exception('Could not find binary');

        } elseif (is_executable($config['binary']) === false) {
            throw new Exception('['.$config['binary'].'] is not executable');
        }
        $binaryPath          = dirname($config['binary']);
        $executable          = basename($config['binary']);
        $iniFileName       ??= $config['ini-file-name'];
        $iniFile             = $binaryPath.'/InitialCustomer/'.$iniFileName;
        $outputFilePostfix ??= $config['output-file-name'];

        if (file_exists($iniFile) === false) {
            throw new Exception('Could not find ini file '.$iniFile);
        }
        /*
        **  Alle Verzeichnisnamen und Pfade sind für die Speicherung der Queue-Datei (Json). Lediglich der
        **  Verzeichnisname in "$dirName" wird auch für die Ausgabedateien des Fillers verwendet und muss
        **  auch in der ini-Datei genutzt werden. */
        $dirName = 'filler'.(empty($pathExtension) ? '' : '/'.$pathExtension);
        $subPath = 'queue/'.$dirName;

        $targetPath = $ModuleStorage->path($subPath);

        if ($ModuleStorage->exists($subPath) === false) {
            if (mkdir($targetPath, 0777, true) === false) {
                throw new Exception('Could not create target directory');
            }
        } elseif (is_writable($targetPath) === false) {
            throw new Exception('Target directory is not writable');
        }
        $fileName = $dataFileName.'.json';
        $queueFile = $ModuleStorage->path($subPath).'/'.$fileName;

        if ($ModuleStorage->put($subPath.'/'.$fileName, json_encode($printData, JSON_PRETTY_PRINT)) === false) {
            throw new Exception('Could not create file');
        }
        $command = '"'.$executable.'" '.$iniFileName.' "'.$queueFile.'"';

        $cwd = getcwd();
        /*
        **  Ins Verzeichnis des Layouters wechseln. */
        chdir($binaryPath);

        ob_start(); {
            $lastOutputLine = system($command, $resultCode);

        } ob_end_clean();

        chdir($cwd);

        if ($resultCode !== false) {
            switch ($resultCode) {
                case 1:
                    throw new Exception('Error while creating print file: error code '.$resultCode.', '.$lastOutputLine);
                    break;

                case 0:
                    if(!empty($lastOutputLine)) {
                        throw new Exception('Error while creating print file: error code '.$resultCode.', '.$lastOutputLine);
                    }
                    // no break
                default:
                    // Success
            }
        }
        try {
            // unlink($queueFile);

        } catch (\Throwable $th) {
            //
        }
        /*
        **  Ergebnisdatei zusammenstellen. */
        $PublicStorage = new ModuleStorage(true, null, false);

        $printFileName = $dataFileName.'_'.$outputFilePostfix.'.'.$config['output-file-extension'];

        return $PublicStorage->url($dirName.'/'.$printFileName);

    } // createPrintFile()


/* +++ CLASS METHODS +++ ++++++++++++++++++++++++++++++++++++++++++++++++++++ */


} // class FillerService extends Procedure {}
