<?php

namespace App\Repositories\Ecommerce\Product\Property;

use App\Models\Ecommerce\Product\Property\Attribute;
use App\Repositories\System\Cache\CacheRepository;
use Illuminate\Database\Eloquent\Collection;

class PropertyRepository
{
    public static function properties(): array|Collection
    {
        return CacheRepository::make(
            name: 'product-properties-with-values',
            value: fn () => Attribute::with('values')->get(),
        );
    }

    public static function getRealValue(string $slug, string|int|float|null $value)
    {
        if (is_null($value)) {
            return $value;
        }

        $attribute = static::properties()->firstWhere('slug', $slug);

        if (! $attribute) {
            return $value;
        }

        if ($attribute->type !== 'select') {
            return $value;
        }

        return $attribute->values?->firstWhere('id', $value)?->value;
    }

    public static function getAvailableColors($product): array
    {
        $colors = collect();

        // Add current product color
        if ($product->colour) {
            $colors->push([
                'product_id' => $product->id,
                'colour' => PropertyRepository::getRealValue('colour', $product->colour),
                'availabel_sizes' => static::getAvailableSizes($product),
            ]);
        }

        if (! $product->relationLoaded('variations')) {
            return $colors->toArray();
        }

        $product->variations->each(function ($variation) use (&$colors, $product) {
            if ($variation->colour) {
                $colors->push([
                    'product_id' => $variation->id,
                    'colour' => PropertyRepository::getRealValue('colour', $variation->colour),
                    'availabel_sizes' => static::getAvailableSizes($variation, $product),
                ]);
            }
        });

        return $colors->uniqueStrict('colour')->toArray();
    }

    public static function getAvailableSizes($product, $parent = null): array
    {
        $sizes = collect();

        // Add current product size
        if ($product->size) {
            $sizes->push([
                'product_id' => $product->id,
                'size' => PropertyRepository::getRealValue('size', $product->size),
            ]);
        }

        $product = $parent ?: $product;

        if (! $product->relationLoaded('variations')) {
            return $sizes->toArray();
        }

        $product->variations->each(function ($variation) use (&$sizes) {
            if ($variation->size) {
                $sizes->push([
                    'product_id' => $variation->id,
                    'size' => PropertyRepository::getRealValue('size', $variation->size),
                ]);
            }
        });

        return $sizes->uniqueStrict('size')->toArray();
    }
}
