<?php

namespace Inside\BCLH\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Inside\BCLH\Events\EbookGeneratedEvent;
use Inside\BCLH\Facades\Pdf;
use Inside\Content\Models\Contents\Brands;

class GenerateEbook implements ShouldQueue
{
    use InteractsWithQueue;
    use Queueable;
    use SerializesModels;

    /**
     * @var string
     */
    protected $userUuid;

    /**
     * @var array|null
     */
    public $contents;

    /**
     * @var Brands|null
     */
    protected $brand;

    /**
     * @var string|null
     */
    protected $langcode;

    /**
     * @var mixed|null
     */
    protected $baseFolder;

    /**
     * @param string $userUuid
     * @param string|null $langcode
     * @param Brands|null $brand
     * @param array|null $contents
     * @param mixed|null $baseFolder
     */
    public function __construct(string $userUuid, ?string $langcode, ?Brands $brand, ?array $contents, $baseFolder)
    {
        $this->userUuid = $userUuid;
        $this->langcode = $langcode;
        $this->brand = $brand;
        $this->contents = $contents;
        $this->baseFolder = $baseFolder;
    }

    public function handle(): void
    {
        $cover = [
            'view' => 'cover',
            'filename' => 'pdf/cover/default.pdf',
            'data' => [],
            'update' => false,
        ];

        if (! empty($this->brand)) {
            $path = $this->brand->brand_logo ?? false;
            $cover['data']['image'] = $this->getDataImage($path) ?? '';
            $cover['filename'] = 'pdf/cover/'.$this->brand->uuid.'.pdf';
            $cover['update'] = true;
        }

        $pdfs = [
            $cover,
        ];

        $hasFolders = false;

        $contents = $this->contents ?? [];
        foreach ($contents as $content) {
            if ($content['type'] === 'folder') {
                $hasFolders = true;
                break;
            }
        }

        if ($hasFolders) {
            $pdfs[] = [
                'view' => 'summary',
                'filename' => 'pdf/summaries/'.$this->userUuid.'.pdf',
                'data' => [
                    'folders' => $this->contents ?? [],
                    'brand' => $this->brand,
                    'langcode' => $this->langcode,
                ],
                'update' => true,
            ];
        }

        if (! empty($this->baseFolder)) {
            $this->addPdfs($pdfs, [$this->baseFolder]);
        }

        $this->addPdfs($pdfs, $this->contents);

        if (! empty($this->brand) && ! empty($this->brand->legal_mentions)) {
            $pdfs[] = [
                'view' => 'legal',
                'filename' => 'pdf/legal/'.$this->brand->uuid.'.pdf',
                'data' => [
                    'body' => Pdf::convertImages($this->brand->legal_mentions, $this->brand),
                    'langcode' => $this->brand->langcode,
                ],
                'update' => true,
            ];
        }

        Pdf::mergePdfs($pdfs, 'storage/app/protected/pdf/download/'.$this->userUuid.'.pdf');
        $pdfs = null;

        event(new EbookGeneratedEvent($this->userUuid));

        $this->delete();
    }

    private function getDataImage(?string $path): ?string
    {
        if (empty($path) || ! Storage::disk('local')->exists($path)) {
            return null;
        }

        $mimeContent = mime_content_type(Storage::disk('local')->path($path));
        $base64Content = base64_encode(file_get_contents(Storage::disk('local')->path($path)) ?: '');

        return "data:$mimeContent;base64,$base64Content";
    }

    private function addPdfs(array &$pdfs, ?array $contents): void
    {
        if (empty($contents)) {
            return;
        }

        foreach ($contents as $content) {
            if ($content['type'] === 'folder' && ! $content['hasSops']) {
                continue;
            }

            if ($content['type'] === 'folder') {
                $pdfs[] = [
                    'view' => 'folder',
                    'filename' => 'pdf/folders/'.$content['uuid'].'.pdf',
                    'data' => ['folder' => $content],
                    'update' => false,
                ];

                if (isset($content['children']) && ! empty($content['children'])) {
                    $this->addPdfs($pdfs, $content['children']);
                }
            }

            if ($content['type'] === 'sop') {
                $pdfs[] = [
                    'view' => 'sop',
                    'filename' => 'pdf/'.($content['is_rop'] ? 'rops' : 'sops').'/'.$content['uuid'].'.pdf',
                    'data' => ['sop' => $content],
                    'update' => false,
                ];
            }
        }

        $contents = null;
    }
}
