<?php

namespace App\Services;

use App\Support\LetterLayout;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\View;
use Spatie\Browsershot\Browsershot;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;

class LetterService
{
    /**
     * @param  array<string, mixed>  $data
     */
    public function renderHtml(string $view, array $data = []): string
    {
        return View::make($view, $this->prepareViewData($data))->render();
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function htmlResponse(string $view, array $data = []): Response
    {
        return response($this->renderHtml($view, $data), SymfonyResponse::HTTP_OK, [
            'Content-Type' => 'text/html; charset=UTF-8',
        ]);
    }

    /**
     * @param  array<string, mixed>  $data
     */
    public function pdfResponse(string $view, array $data = [], string $filename = 'letter.pdf'): Response
    {
        $pdf = $this->makeBrowsershot($this->renderHtml($view, $data))->pdf();

        return response($pdf, SymfonyResponse::HTTP_OK, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'inline; filename="'.$filename.'"',
        ]);
    }

    /**
     * @param  array<string, mixed>  $overrides
     * @return array<string, mixed>
     */
    public function prepareViewData(array $overrides = []): array
    {
        $logoPath = $overrides['logoPath'] ?? config('mail.logo_path');

        return array_merge([
            'letterLayout' => LetterLayout::resolve(),
            'logoPath' => $logoPath,
            'logoUrl' => $this->resolveLogoDataUri($logoPath),
            'organizationAddress' => $overrides['organizationAddress'] ?? null,
            'organizationContact' => $overrides['organizationContact'] ?? null,
        ], $overrides);
    }

    protected function makeBrowsershot(string $html): Browsershot
    {
        $layout = LetterLayout::resolve();
        [$top, $right, $bottom, $left] = $layout['margins_mm'];

        $browsershot = Browsershot::html($html)
            ->setNodeModulePath(config('browsershot.node_module_path'))
            ->timeout(config('browsershot.timeout'))
            ->format($layout['page_format'])
            ->margins($top, $right, $bottom, $left)
            ->showBackground();

        if ($nodeBinary = config('browsershot.node_binary')) {
            $browsershot->setNodeBinary($nodeBinary);
        }

        if ($npmBinary = config('browsershot.npm_binary')) {
            $browsershot->setNpmBinary($npmBinary);
        }

        if ($chromePath = config('browsershot.chrome_path')) {
            $browsershot->setChromePath($chromePath);
        }

        if (config('browsershot.no_sandbox')) {
            $browsershot->noSandbox();
        }

        return $browsershot;
    }

    protected function resolveLogoDataUri(?string $logoPath): ?string
    {
        if (empty($logoPath) || ! file_exists($logoPath)) {
            return null;
        }

        $mime = mime_content_type($logoPath) ?: 'image/svg+xml';

        return 'data:'.$mime.';base64,'.base64_encode(file_get_contents($logoPath));
    }
}
