<?php

namespace App\Domains\Purchase\Resources;

use App\Domains\Cart\Models\CartItem;
use App\Domains\Purchase\Models\Purchase;
use App\Domains\Purchase\Models\PurchaseItem;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Collection;

/**
 * @mixin Purchase
 */
class PurchaseResource extends JsonResource
{
    /**
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        [$items, $itemsSource] = $this->resolveItems();

        $subtotal = $items->isNotEmpty()
            ? $items->reduce(
                fn (float $carry, PurchaseItem|CartItem $item): float => $carry + $this->resolveItemSubtotal($item),
                0.0,
            )
            : (float) ($this->total ?? 0);

        $total = $items->isNotEmpty()
            ? $items->reduce(
                fn (float $carry, PurchaseItem|CartItem $item): float => $carry + $this->resolveItemTotal($item),
                0.0,
            )
            : (float) ($this->total ?? 0);

        return [
            'id' => $this->id,
            'cart_id' => $this->cart_id,
            'tenant_codigo' => $this->tenant_codigo,
            'user_id' => $this->user_id,
            'created_at' => $this->created_at,
            'status' => $this->status,
            'payment_method' => $this->payment_method,
            'dni' => $this->dni,
            'transfer_payer_dni' => $this->transfer_payer_dni,
            'telefono' => $this->telefono,
            'nombre_apellido' => $this->nombre_apellido,
            'email' => $this->email,
            'items_source' => $itemsSource,
            'items' => PurchaseItemResource::collection($items),
            'subtotal' => $this->formatMoney($subtotal),
            'total' => $this->formatMoney($total),
        ];
    }

    /**
     * @return array{0: Collection<int, PurchaseItem|CartItem>, 1: string|null}
     */
    protected function resolveItems(): array
    {
        if (! $this->resource->relationLoaded('items')) {
            return [collect(), null];
        }

        $purchaseItems = $this->resource->getRelation('items');

        if ($purchaseItems->isNotEmpty()) {
            return [$purchaseItems, 'purchase'];
        }

        if (! $this->resource->relationLoaded('cart')) {
            return [collect(), null];
        }

        $cart = $this->resource->getRelation('cart');

        if ($cart === null || ! $cart->relationLoaded('items')) {
            return [collect(), null];
        }

        return [$cart->getRelation('items'), 'cart'];
    }

    protected function resolveItemSubtotal(PurchaseItem|CartItem $item): float
    {
        if ($item instanceof PurchaseItem) {
            return (float) $item->precio_unitario * $item->cantidad;
        }

        return (float) ($item->selectedItem()?->getPrice() ?? 0) * $item->cantidad;
    }

    protected function resolveItemTotal(PurchaseItem|CartItem $item): float
    {
        if ($item instanceof PurchaseItem) {
            return (float) ($item->total ?? 0);
        }

        return $this->resolveItemSubtotal($item);
    }

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