<?php

namespace App\Domains\Catalog\Services;

use App\Domains\Catalog\Enums\FeaturedGroupSource;
use App\Domains\Catalog\Enums\GroupLayout;
use App\Domains\Catalog\Enums\ProductLayout;
use App\Domains\Catalog\Models\Category;
use App\Domains\Catalog\Models\FeaturedGroup;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;

class OnTicketFeaturedGroupService
{
    /** @return Collection<int, FeaturedGroup> */
    public function forTenant(Tenant $tenant): Collection
    {
        return FeaturedGroup::query()
            ->where('tenant_code', $tenant->codigo)
            ->where('source_type', FeaturedGroupSource::Category)
            ->whereHas('category', fn ($query) => $query->where('tenant_code', $tenant->codigo))
            ->with('category')
            ->orderBy('group_order')
            ->orderBy('id')
            ->get();
    }

    /** @param array{category_name: string, is_featured: bool} $data */
    public function create(Tenant $tenant, array $data): FeaturedGroup
    {
        return DB::transaction(function () use ($tenant, $data): FeaturedGroup {
            $category = $tenant->categories()->create([
                'nombre' => $data['category_name'],
            ]);

            $featuredGroup = FeaturedGroup::query()->create([
                'tenant_code' => $tenant->codigo,
                'source_type' => FeaturedGroupSource::Category,
                'category_id' => $category->id,
                'product_layout' => $this->productLayout($data['is_featured']),
                'group_layout' => GroupLayout::Paginated,
                'group_name' => $data['category_name'],
                'group_order' => $this->nextOrder($tenant),
            ]);

            return $featuredGroup->setRelation('category', $category);
        });
    }

    /** @param array{category_name: string, is_featured: bool} $data */
    public function update(
        Tenant $tenant,
        FeaturedGroup $featuredGroup,
        array $data,
    ): FeaturedGroup {
        return DB::transaction(function () use ($tenant, $featuredGroup, $data): FeaturedGroup {
            $featuredGroup = FeaturedGroup::query()
                ->whereKey($featuredGroup->getKey())
                ->where('tenant_code', $tenant->codigo)
                ->where('source_type', FeaturedGroupSource::Category)
                ->lockForUpdate()
                ->firstOrFail();

            $category = Category::query()
                ->whereKey($featuredGroup->category_id)
                ->where('tenant_code', $tenant->codigo)
                ->lockForUpdate()
                ->firstOrFail();

            $category->update(['nombre' => $data['category_name']]);
            $featuredGroup->update([
                'group_name' => $data['category_name'],
                'product_layout' => $this->productLayout($data['is_featured']),
                'group_layout' => GroupLayout::Paginated,
            ]);

            return $featuredGroup->setRelation('category', $category);
        });
    }

    private function productLayout(bool $isFeatured): ProductLayout
    {
        return $isFeatured ? ProductLayout::Row : ProductLayout::ColumnWithCart;
    }

    private function nextOrder(Tenant $tenant): int
    {
        $maximumOrder = FeaturedGroup::query()
            ->where('tenant_code', $tenant->codigo)
            ->max('group_order');

        return $maximumOrder === null ? 0 : ((int) $maximumOrder) + 1;
    }
}
