<?php

namespace App\Domains\Cart\Resources;

use App\Domains\Cart\Models\CartItem;
use App\Domains\Catalog\Enums\InventoryPolicy;
use App\Domains\Catalog\Models\Variant;
use App\Domains\Tenant\Models\Tenant;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @mixin CartItem
 */
class CartItemResource extends JsonResource
{
    /**
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        $selectedItem = $this->selectedItem();
        $imageUrl = null;
        $tenant = $request->route('tenant');
        $displayImage = ! $tenant instanceof Tenant || $tenant->display_cart_item_images;
        $includeVariants = $tenant instanceof Tenant
            && $tenant->cart_editing_policy->allowsVariantChanges();

        if ($displayImage && $selectedItem?->relationLoaded('attachments')) {
            $imageUrl = $selectedItem->attachments->first()?->getTemporaryUrl(1440);
        }

        if ($displayImage && $imageUrl === null && $this->catalogItem?->relationLoaded('attachments')) {
            $imageUrl = $this->catalogItem->attachments->first()?->getTemporaryUrl(1440);
        }

        return [
            'id' => $this->id,
            'cantidad' => $this->cantidad,
            'precio_unitario' => $this->formatMoney($selectedItem?->getPrice()),
            'catalog_item_id' => $this->catalog_item_id,
            'variant_id' => $this->variant_id,
            'nombre' => $selectedItem?->getName(),
            'imagen' => $imageUrl,
            'variant' => $this->variant === null ? null : $this->variantData($this->variant),
            'variants' => $this->when(
                $includeVariants,
                fn () => $this->catalogItem
                    ->visibleVariants($this->variant_id)
                    ->map(fn (Variant $variant): array => $this->variantData($variant))
                    ->values(),
            ),
        ];
    }

    /** @return array<string, mixed> */
    protected function variantData(Variant $variant): array
    {
        return [
            'id' => $variant->id,
            'precio' => $this->formatMoney($variant->precio ?? $this->catalogItem->precio),
            'stock_tecnico' => $this->catalogItem->inventory_policy === InventoryPolicy::Unlimited
                ? null
                : $variant->inventory->availableStock(),
            'values' => $variant->selectorOptions($this->catalogItem->itemAttributes),
        ];
    }

    protected function formatMoney(float|int|string|null $amount): string
    {
        return number_format((float) ($amount ?? 0), 2, '.', '');
    }
}
