<?php

namespace App\Services\PromptLandingPageEditor;

use App\Enums\PromptLandingPageVersionKind;
use App\Models\PromptLandingPage;
use App\Models\PromptLandingPageVersion;
use App\Models\User;
use Illuminate\Support\Facades\DB;

class SavePage
{
    public function __construct(
        private SanitizeDocument $sanitizer,
        private UniqueDuplicateIds $uniqueDuplicateIds,
        private MergeEditedDocument $merger,
        private RecordPublishedVersion $recordPublishedVersion,
    ) {}

    /**
     * @return array{html: string, css: string, js: string, version: int}
     */
    public function handle(PromptLandingPage $page, User $actor, string $html, string $css, string $js): array
    {
        $attachments = $page->attachments()->get()->all();
        $sanitized = $this->sanitizer->sanitize($html, $css, $js, $attachments);
        $merged = $this->merger->merge(
            (string) ($page->html ?? ''),
            (string) ($page->css ?? ''),
            (string) ($page->js ?? ''),
            $sanitized['html'],
            $sanitized['css'],
            $sanitized['js'],
        );
        $merged['html'] = $this->uniqueDuplicateIds->rewrite($merged['html']);

        return DB::transaction(function () use ($page, $actor, $merged): array {
            $this->recordPublishedVersion->snapshotLive($page, $actor);

            $page->update([
                'html' => $merged['html'],
                'css' => $merged['css'],
                'js' => $merged['js'],
            ]);

            $version = $this->nextVersionNumber($page);
            $this->snapshot(
                $page,
                $actor,
                $merged['html'],
                $merged['css'],
                $merged['js'],
                $version,
            );

            $page->editorDraft?->delete();

            return [
                'html' => $merged['html'],
                'css' => $merged['css'],
                'js' => $merged['js'],
                'version' => $version,
            ];
        });
    }

    private function snapshot(
        PromptLandingPage $page,
        User $actor,
        string $html,
        string $css,
        string $js,
        int $version,
    ): PromptLandingPageVersion {
        return $page->versions()->create([
            'version' => $version,
            'kind' => PromptLandingPageVersionKind::Published,
            'html' => $html,
            'css' => $css,
            'js' => $js,
            'created_by' => $actor->id,
            'created_at' => now(),
        ]);
    }

    private function nextVersionNumber(PromptLandingPage $page): int
    {
        return max(2, (int) $page->versions()->max('version') + 1);
    }
}
