<?php

namespace App\Domains\Purchase\Services\Checkout;

use App\Domains\Attachable\Models\Attachment;
use App\Domains\Cart\Models\CartItem;
use App\Domains\Catalog\Models\Variant;
use Illuminate\Support\Collection;

class PurchaseItemSnapshotFactory
{
    /**
     * @param  Collection<int, CartItem>  $cartItems
     * @return array<int, array<string, mixed>>
     */
    public function fromCartItems(Collection $cartItems): array
    {
        return $cartItems
            ->map(function (CartItem $item): array {
                $selectedItem = $item->selectedItem();
                $quantity = (int) $item->cantidad;
                $unitPrice = $selectedItem?->getPrice() ?? 0;

                return [
                    'source_catalog_item_id' => $item->catalog_item_id,
                    'source_variant_id' => $item->variant_id,
                    'image_attachment_id' => $this->firstImageAttachment($item)?->id,
                    'nombre' => $item->catalogItem->nombre,
                    'descripcion' => $selectedItem?->getDescription(),
                    'slug' => $item->catalogItem->slug,
                    'item_nombre' => $selectedItem->getName(),
                    'variant_attributes' => $item->variant === null
                        ? []
                        : $this->snapshotAttributes($item->variant),
                    'cantidad' => $quantity,
                    'precio_unitario' => $unitPrice,
                    'discount_total' => null,
                    'tax_total' => null,
                    'total' => $unitPrice * $quantity,
                ];
            })
            ->all();
    }

    private function firstImageAttachment(CartItem $item): ?Attachment
    {
        return $item->variant?->attachments->first()
            ?? $item->catalogItem?->attachments->first();
    }

    /** @return array<int, array{name: string, value: mixed}> */
    private function snapshotAttributes(Variant $variant): array
    {
        $attributes = $variant->definitions
            ->groupBy('item_attribute_id')
            ->map(function ($definitions): array {
                $itemAttribute = $definitions->first()?->itemAttribute;
                $values = $definitions->pluck('value')->values();

                return [
                    'name' => (string) ($itemAttribute?->attribute?->nombre ?? ''),
                    'value' => $itemAttribute?->allow_multi_select
                        ? $values->all()
                        : $values->first(),
                ];
            })
            ->filter(fn (array $attribute): bool => $attribute['name'] !== '' || $attribute['value'] !== null)
            ->values();

        $eventDates = $variant->selectedEventDates();
        if ($eventDates->isNotEmpty()) {
            $attributes->prepend([
                'name' => 'Fecha',
                'value' => $eventDates
                    ->map(fn ($eventDate): string => $eventDate->date->format('Y-m-d'))
                    ->values()
                    ->all(),
            ]);
        }

        return $attributes->all();
    }
}
