<?php

namespace App\Domains\Tenant\Services;

use App\Domains\Attachable\Models\Attachment;
use App\Domains\Attachable\Services\AttachmentService;
use App\Domains\Tenant\Models\WebsiteType;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class WebsiteTypeService
{
    public function __construct(
        protected AttachmentService $attachmentService,
    ) {}

    /**
     * Create a website type and store its site logo.
     *
     * @param  array<string, mixed>  $data
     */
    public function create(array $data): WebsiteType
    {
        return $this->save(new WebsiteType, $data);
    }

    /**
     * Create or update a website type and replace its site logo when provided.
     *
     * @param  array<string, mixed>  $attributes
     * @param  array<string, mixed>  $values
     */
    public function updateOrCreate(array $attributes, array $values = []): WebsiteType
    {
        /** @var WebsiteType $websiteType */
        $websiteType = WebsiteType::query()->firstOrNew($attributes);

        return $this->save($websiteType, [...$attributes, ...$values]);
    }

    /**
     * @param  array<string, mixed>  $data
     */
    private function save(WebsiteType $websiteType, array $data): WebsiteType
    {
        return DB::transaction(function () use ($websiteType, $data): WebsiteType {
            $hasSiteLogo = array_key_exists('site_logo', $data);
            $siteLogo = $data['site_logo'] ?? null;
            $previousSiteLogo = $websiteType->exists
                ? $websiteType->siteLogo()->first()
                : null;

            unset($data['site_logo']);

            if ($hasSiteLogo) {
                $attachment = null;

                if ($siteLogo) {
                    $attachment = is_string($siteLogo) && Str::isUuid($siteLogo)
                        ? Attachment::query()->where('key', $siteLogo)->first()
                        : $this->attachmentService->store($siteLogo, 'website-types');
                }

                $data['site_logo'] = $attachment?->id;
            }

            $websiteType->fill($data)->save();

            if (
                $hasSiteLogo
                && $previousSiteLogo instanceof Attachment
                && $previousSiteLogo->id !== $websiteType->site_logo
            ) {
                $this->attachmentService->delete($previousSiteLogo);
            }

            return $websiteType;
        });
    }
}
