<?php

namespace App\Services\ESign;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use RuntimeException;

class DocxToPdfConverter
{
    /**
     * Word 파일이면 PDF로 변환, PDF면 그대로 저장.
     *
     * @return array{path: string, name: string, hash: string, size: int}
     */
    public function convertAndStore(UploadedFile $file, string $storagePath): array
    {
        if (! $this->isWordFile($file)) {
            // PDF는 그대로 저장
            $path = $file->store($storagePath, 'local');

            return [
                'path' => $path,
                'name' => $file->getClientOriginalName(),
                'hash' => hash_file('sha256', $file->getRealPath()),
                'size' => $file->getSize(),
            ];
        }

        // Word → PDF 변환
        $originalName = $file->getClientOriginalName();
        $pdfName = preg_replace('/\.(docx?|DOCX?)$/', '.pdf', $originalName);

        $tmpDir = sys_get_temp_dir().'/esign_convert_'.Str::random(16);
        mkdir($tmpDir, 0755, true);

        try {
            $tmpWordPath = $tmpDir.'/'.'source.'.$file->getClientOriginalExtension();
            copy($file->getRealPath(), $tmpWordPath);

            $command = sprintf(
                'HOME=%s libreoffice --headless --convert-to pdf --outdir %s %s 2>&1',
                escapeshellarg($tmpDir),
                escapeshellarg($tmpDir),
                escapeshellarg($tmpWordPath)
            );

            exec($command, $output, $exitCode);

            if ($exitCode !== 0) {
                throw new RuntimeException(
                    'LibreOffice 변환 실패 (exit code: '.$exitCode.'): '.implode("\n", $output)
                );
            }

            $tmpPdfPath = $tmpDir.'/source.pdf';
            if (! file_exists($tmpPdfPath)) {
                throw new RuntimeException('변환된 PDF 파일을 찾을 수 없습니다.');
            }

            $hash = hash_file('sha256', $tmpPdfPath);
            $size = filesize($tmpPdfPath);

            // 최종 저장 경로
            $finalPath = $storagePath.'/'.Str::random(40).'.pdf';
            Storage::disk('local')->put($finalPath, file_get_contents($tmpPdfPath));

            return [
                'path' => $finalPath,
                'name' => $pdfName,
                'hash' => $hash,
                'size' => $size,
            ];
        } finally {
            // 임시 파일 정리
            array_map('unlink', glob($tmpDir.'/*'));
            @rmdir($tmpDir);
        }
    }

    public function isWordFile(UploadedFile $file): bool
    {
        $ext = strtolower($file->getClientOriginalExtension());

        return in_array($ext, ['doc', 'docx']);
    }
}
