<?php

namespace App\Domains\Tenant\Services;

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

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

    /**
     * Create a new tenant and store its logos.
     *
     * @param  array<string, mixed>  $data
     * @return Tenant
     */
    public function create(array $data): Tenant
    {
        return DB::transaction(function () use ($data): Tenant {
            $headerLogo = $data['header_logo'] ?? null;
            $footerLogo = $data['footer_logo'] ?? null;

            unset($data['header_logo'], $data['footer_logo']);

            $headerAttachmentId = null;
            if ($headerLogo) {
                $attachment = Str::isUuid($headerLogo)
                    ? \App\Domains\Attachable\Models\Attachment::query()->where('key', $headerLogo)->first()
                    : $this->attachmentService->store($headerLogo, 'tenants');

                if ($attachment) {
                    $headerAttachmentId = $attachment->id;
                }
            }

            $footerAttachmentId = null;
            if ($footerLogo) {
                $attachment = Str::isUuid($footerLogo)
                    ? \App\Domains\Attachable\Models\Attachment::query()->where('key', $footerLogo)->first()
                    : $this->attachmentService->store($footerLogo, 'tenants');

                if ($attachment) {
                    $footerAttachmentId = $attachment->id;
                }
            }

            $data['header_logo_id'] = $headerAttachmentId;
            $data['footer_logo_id'] = $footerAttachmentId;

            /** @var Tenant $tenant */
            $tenant = Tenant::query()->create($data);

            return $tenant;
        });
    }

    /**
     * Update an existing tenant and store new logos if uploaded.
     *
     * @param  Tenant  $tenant
     * @param  array<string, mixed>  $data
     * @return Tenant
     */
    public function update(Tenant $tenant, array $data): Tenant
    {
        return DB::transaction(function () use ($tenant, $data): Tenant {
            $hasHeaderLogoKey = array_key_exists('header_logo', $data);
            $hasFooterLogoKey = array_key_exists('footer_logo', $data);
            $headerLogo = $data['header_logo'] ?? null;
            $footerLogo = $data['footer_logo'] ?? null;

            unset($data['header_logo'], $data['footer_logo']);

            $tenant->fill($data);

            if ($hasHeaderLogoKey) {
                if ($headerLogo) {
                    $attachment = Str::isUuid($headerLogo)
                        ? \App\Domains\Attachable\Models\Attachment::query()->where('key', $headerLogo)->first()
                        : $this->attachmentService->store($headerLogo, 'tenants');

                    if ($attachment) {
                        $tenant->header_logo_id = $attachment->id;
                    } else {
                        $tenant->header_logo_id = null;
                    }
                } else {
                    $tenant->header_logo_id = null;
                }
            }

            if ($hasFooterLogoKey) {
                if ($footerLogo) {
                    $attachment = Str::isUuid($footerLogo)
                        ? \App\Domains\Attachable\Models\Attachment::query()->where('key', $footerLogo)->first()
                        : $this->attachmentService->store($footerLogo, 'tenants');

                    if ($attachment) {
                        $tenant->footer_logo_id = $attachment->id;
                    } else {
                        $tenant->footer_logo_id = null;
                    }
                } else {
                    $tenant->footer_logo_id = null;
                }
            }

            $tenant->save();

            return $tenant;
        });
    }
}
