<?php

namespace Daylight\Core\Livewire\Store\Products;

use Daylight\Core\Models\OptionValue;
use Daylight\Core\Models\Product;
use Daylight\Core\Models\Variant;
use Daylight\Core\Modules\Multilingualism\Multilingualism;
use Ijpatricio\Mingle\Concerns\InteractsWithMingles;
use Ijpatricio\Mingle\Contracts\HasMingles;
use Illuminate\Support\ViewErrorBag;
use Livewire\Component;

class ProductVariationBuilder extends Component implements HasMingles
{
    use InteractsWithMingles;

    public ?Product $product = null;

    public function component(): string
    {
        return 'resources/js/admin/ProductVariationBuilder/ProductVariationBuilder.js';
    }

    public function search(string $query)
    {
        $variants = Variant::query()
            ->where('sku', 'like', "%$query%")
            ->whereNull('product_id')
            ->with('media')
            ->limit(10)
            ->get();

        $exactVariant = Variant::query()
            ->where('sku', $query)
            ->whereNull('product_id')
            ->with('media')
            ->first();

        return [
            'alreadyExists' => Variant::query()
                ->where('sku', $query)
                ->where('product_id', '!=', optional($this->product)->id)
                ->exists(),
            'exactMatch' => $exactVariant
                ? [
                    'id' => $exactVariant->id,
                    'sku' => $exactVariant->sku,
                    'title' => $exactVariant->title,
                    'image' => $exactVariant->media->first()?->getUrl('thumbnail'),
                ]
                : null,
            'variants' => $variants->map(function (Variant $variant) {
                return [
                    'id' => $variant->id,
                    'sku' => $variant->sku,
                    'title' => $variant->title,
                    'image' => $variant->media->first()?->getUrl('thumbnail'),
                ];
            }),
        ];
    }

    public function mingleData(): array
    {
        return [
            'options' => $this->getOptions(),
            'variants' => $this->getVariants(),
            'errors' => session()->get('errors', new ViewErrorBag)->getBag('default')->messages(),
            'locales' => Multilingualism::getAvailableLocales(),
            'selectedVariants' => $this->product
                ? $this->product->variants->map(function (Variant $variant) {
                    return [
                        'id' => $variant->id,
                        'sku' => $variant->sku,
                        'title' => $variant->title,
                        'image' => $variant->media->first()?->getUrl('thumbnail'),
                    ];
                })
                : [],
        ];
    }

    private function getOptions()
    {
        if (old('options')) {
            return collect(json_decode(old('options'), true));
        }

        return $this->product
            ? $this->product->options->sortBy('order')->map(function ($option) {
                return [
                    'id' => $option->id,
                    'type' => $option->type,
                    'translations' => $option->translations->mapWithKeys(function ($translation) {
                        return [$translation->locale => ['name' => $translation->name]];
                    }),
                    'optionValues' => $option->values->sortBy('position')->map(function ($optionValue) {
                        return [
                            'id' => $optionValue->id,
                            'color' => $optionValue->color,
                            'translations' => $optionValue->translations->mapWithKeys(function ($translation) {
                                return [$translation->locale => ['name' => $translation->name]];
                            }),
                        ];
                    })->values()->toArray(),
                ];
            })->toArray()
            : [];
    }

    public function getVariants()
    {
        if (old('variants')) {
            return collect(json_decode(old('variants'), true));
        }

        return $this->product
            ? $this->product->variants->map(function (Variant $variant) {
                return [
                    'sku' => $variant->sku,
                    'optionValues' => $variant->optionValues->map(function (OptionValue $optionValue) {
                        return [
                            'option_id' => $optionValue->option_id,
                            'option_value_id' => $optionValue->id,
                        ];
                    })->toArray(),
                ];
            })
            : collect();
    }
}
