<?php declare(strict_types=1);

namespace Helpers\PhpOffice;

use ErrorException;
use Exception;
use PhpOffice\PhpSpreadsheet\IOFactory as IOFactoryExcel;
use PhpOffice\PhpWord\IOFactory as IOFactoryWord;

class PhpOfficeAdapter
{
    private static string $pdf = 'pdf';

    // TODO: Convert to Enum
    /**
     * Summary of listWordFileExtensions
     * @var string[]
     */
    private static array $listWordFileExtensions = ['docx', 'doc', 'odt'];

    // TODO: Convert to Enum
    /**
     * Summary of listExcelFileExtensions
     * @var string[]
     */
    private static array $listExcelFileExtensions = ['xlsx', 'xls', 'ods', 'csv'];

    // TODO: Convert to Enum
    /**
     * Summary of listImageExtensions
     * @var string[]
     */
    private static array $listImageExtensions = ['jpg', 'jpeg', 'webp', 'png', 'gif', 'avif', 'svg', 'ico', 'bmp'];

    /**
     * Summary of wordToHtml
     * @param string $docPath
     * @throws \ErrorException
     * @return string
     */
    private static function wordToHtml(string $docPath): string
    {
        $phpWord   = IOFactoryWord::load($docPath);
        $objWriter = IOFactoryWord::createWriter($phpWord, 'HTML');
        ob_start();
        $objWriter->save('php://output');
        $html = ob_get_clean();
        if ($html) {
            return $html;
        }
        throw new ErrorException('Le fichier n\'a pas pû être converti en HTML.');
    }

    /**
     * Summary of excelToHtml
     * @param string $docPath
     * @throws \ErrorException
     * @return string
     */
    private static function excelToHtml(string $docPath): string
    {
        $phpExcel  = IOFactoryExcel::load($docPath);
        $objWriter = IOFactoryExcel::createWriter($phpExcel, 'Html');
        ob_start();
        $objWriter->save('php://output');
        $html = ob_get_clean();
        if ($html) {
            return $html;
        }
        throw new ErrorException('Le fichier n\'a pas pû être converti en HTML.');
    }

    /**
     * Summary of fileToHtmlForIFrameSrcDoc
     * @param string $docPath
     * @throws \Exception
     * @throws \ErrorException
     * @return string
     */
    public static function fileToHtmlForIFrameSrcDoc(string $docPath): string
    {
        if (str_ends_with($docPath, self::$pdf)) {
            throw new Exception('Le fichier est un PDF.');
        }

        if (self::isWordFile($docPath)) {
            return self::wordToHtml($docPath);
        }

        if (self::isExcelFile($docPath)) {
            return self::excelToHtml($docPath);
        }

        throw new ErrorException('Le fichier n\'a pas pû être converti en HTML.');
    }

    /**
     * Summary of isWordFile
     * @param string $fileType
     * @return bool|int
     */
    public static function isWordFile(string $fileType): bool|int
    {
        $patternWord = '/(' . implode('|', array_map('preg_quote', self::$listWordFileExtensions)) . ')/i';
        return preg_match($patternWord, $fileType);
    }

    /**
     * Summary of isExcelFile
     * @param string $fileType
     * @return bool|int
     */
    public static function isExcelFile(string $fileType): bool|int
    {
        $patternExcel = '/(' . implode('|', array_map('preg_quote', self::$listExcelFileExtensions)) . ')/i';
        return preg_match($patternExcel, $fileType);
    }

    public static function isImage(string $fileType): bool|int
    {
        $patternOthers = '/(' . implode('|', array_map('preg_quote', self::$listImageExtensions)) . ')/i';
        return preg_match($patternOthers, $fileType);
    }

    public static function isPdf(string $fileType): bool|int
    {
        return str_ends_with($fileType, self::$pdf);
    }
}
