<?php

namespace App\Jobs;

use App\Events\PowerPointConversionProgress;
use App\Services\FileConversionService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use RuntimeException;
use Symfony\Component\Process\Process;

class ConvertPowerPointJob implements ShouldQueue
{
    use Dispatchable;
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    public function __construct(
        public string $inputPath,
        public string $jobId,
    ) {}

    public function handle(FileConversionService $conversionService): void
    {
        event(new PowerPointConversionProgress($this->jobId, 'started'));

        $tempDir = storage_path('app/temp/ppt-'.$this->jobId);
        if (! is_dir($tempDir) && ! mkdir($tempDir, 0775, true) && ! is_dir($tempDir)) {
            throw new RuntimeException('Temporaires Verzeichnis konnte nicht erstellt werden.');
        }

        $process = new Process([
            'soffice',
            '--headless',
            '--convert-to',
            'pdf',
            '--outdir',
            $tempDir,
            $this->inputPath,
        ]);

        $process->setTimeout(300);
        $process->run();

        if (! $process->isSuccessful()) {
            throw new RuntimeException('PowerPoint-Konvertierung fehlgeschlagen: '.$process->getErrorOutput());
        }

        $pdfPath = $tempDir.DIRECTORY_SEPARATOR.pathinfo($this->inputPath, PATHINFO_FILENAME).'.pdf';
        if (! is_file($pdfPath)) {
            throw new RuntimeException('PDF wurde von LibreOffice nicht erzeugt.');
        }

        $pdfClass = implode('\\', ['Spatie', 'PdfToImage', 'Pdf']);
        $pdf = new $pdfClass($pdfPath);
        $pageCount = $pdf->pageCount();
        $convertedFiles = [];

        for ($page = 1; $page <= $pageCount; $page++) {
            $slidePath = $tempDir.DIRECTORY_SEPARATOR.'slide-'.$page.'.jpg';
            $pdf->selectPage($page)->save($slidePath);

            $convertedFiles[] = $conversionService->convertImage($slidePath);

            event(new PowerPointConversionProgress($this->jobId, 'processing', $page, $pageCount, $convertedFiles));
        }

        event(new PowerPointConversionProgress($this->jobId, 'finished', $pageCount, $pageCount, $convertedFiles));

        $this->cleanup($tempDir);
        @unlink($this->inputPath);
    }

    public function failed(\Throwable $exception): void
    {
        event(new PowerPointConversionProgress($this->jobId, 'failed'));

        Log::error('PowerPoint-Konvertierung fehlgeschlagen', [
            'job_id' => $this->jobId,
            'input_path' => $this->inputPath,
            'error' => $exception->getMessage(),
        ]);
    }

    private function cleanup(string $tempDir): void
    {
        if (! is_dir($tempDir)) {
            return;
        }

        $entries = scandir($tempDir);
        if ($entries === false) {
            return;
        }

        foreach ($entries as $entry) {
            if ($entry === '.' || $entry === '..') {
                continue;
            }

            $path = $tempDir.DIRECTORY_SEPARATOR.$entry;

            if (is_file($path)) {
                @unlink($path);
            }
        }

        @rmdir($tempDir);
    }
}
