<?php

namespace Daylight\Core\Livewire\Store;

use Daylight\Core\Models\Option;
use Daylight\Core\Models\OptionValue;
use Daylight\Core\Models\Variant;
use Livewire\Component;

class ProductOptions extends Component
{
    public $product;

    public $options = [];

    public $optionValues = [];

    public $selectedOption = null;

    public $newOption = '';

    public $newOptionValue = '';

    public $showNewOptionInput = false;

    public $selectedOptionsValues = [];

    public $optionsToConfig = [];

    public $groupedOptionsToConfig = [];

    public $sku = [];

    public $skuSearch = [];

    public function setSelectedOption()
    {
        if ((int) $this->selectedOption == 9999) {
            $this->showNewOptionInput = true;
            $this->optionValues = [];
        } else {
            $this->showNewOptionInput = false;
            $this->getOptionValues();
        }
    }

    public function addNewOption()
    {
        if (! empty($this->newOption)) {
            tap(Option::create([
                'type' => 'select',
            ]), function (Option $option) {
                $option->translations()->create([
                    'locale' => request()->get('locale', app()->getLocale()),
                    'name' => $this->newOption,
                ]);
            });

            $this->options[] = $this->newOption;
            $this->selectedOption = $this->newOption;
            $this->newOption = '';
            $this->showNewOptionInput = false;
        }
    }

    public function addNewOptionValue()
    {
        if (! empty($this->newOptionValue)) {
            $option = Option::query()->where('id', $this->selectedOption)->first();

            tap($option->values()->create(['position' => 1]), function ($value) {
                $value->translations()->create([
                    'locale' => request()->get('locale', app()->getLocale()),
                    'name' => $this->newOptionValue,
                ]);
            });

            $this->newOptionValue = '';
            $this->showNewOptionInput = false;
            $this->getOptionValues();
        }
    }

    public function getOptionValues()
    {
        $this->optionValues = OptionValue::where('option_id', $this->selectedOption)->get();
    }

    public function optionvalueChanged($optionId)
    {
        //
    }

    public function applyOptions()
    {
        $option = Option::query()->where('id', $this->selectedOption)->first();

        foreach ($this->selectedOptionsValues as $optionValue) {
            $optionValue = OptionValue::query()
                ->where('id', $optionValue)
                ->first();
            $this->optionsToConfig[] =
                [
                    'option' => $option->translations->where('locale', request()->get('locale', app()->getLocale()))?->first()?->name.':'.$option->id,
                    'optionvalue' => $optionValue->translations->where('locale', request()->get('locale', app()->getLocale()))?->first()->name.':'.$optionValue->id,
                ];
        }

        $grouped = [];
        foreach ($this->optionsToConfig as $option) {
            $grouped[$option['option']][] = $option['optionvalue'];
        }

        $combined = $this->combineOptions($grouped);
        $this->groupedOptionsToConfig = [];
        $this->groupedOptionsToConfig = $this->prepareForProduct($combined);

        $this->selectedOptionsValues = [];
        $this->newOption = '';
        $this->newOptionValue = '';
        $this->showNewOptionInput = false;
    }

    public function combineOptions($options, $prefix = [])
    {
        $result = [];

        $keys = array_keys($options);
        $firstKey = array_shift($keys);
        $values = array_shift($options);

        foreach ($values as $value) {
            $newPrefix = array_merge($prefix, [$firstKey => $value]);

            if (! empty($options)) {
                $result = array_merge($result, $this->combineOptions($options, $newPrefix));
            } else {
                $result[] = $newPrefix;
            }
        }

        return $result;
    }

    public function prepareForProduct($combined)
    {
        $prepared = [];
        foreach ($combined as $index => $option) {
            $text = [];
            $optionValueIds = [];
            foreach ($option as $key => $value) {
                $keys = explode(':', $key);
                $values = explode(':', $value);

                $text[] = '<strong>'.$keys[0].'</strong>: '.$values[0];
                $optionValueIds[] = $values[1];

                $prepared[$index] = [
                    'name' => implode(' / ', $text),
                    'ids' => implode(', ', $optionValueIds),
                ];
            }
        }

        return $prepared;
    }

    public function searchSku($index)
    {
        $this->skuSearch = [];
        if (strlen($this->sku[$index] > 2)) {
            $variants = Variant::query()
                ->where('sku', 'LIKE', '%'.$this->sku[$index].'%')
                ->where('purchasable', '1')
                ->whereNull('product_id')
                ->limit(5)
                ->get();

            foreach ($variants as $variant) {
                $this->skuSearch[$index][] = $variant->toArray();
            }
        }
    }

    public function applySku($variant_id, $index)
    {
        $variant = Variant::query()
            ->where('id', $variant_id)->first();

        $this->sku[$index] = $variant->sku;
        unset($this->skuSearch[$index]);
    }

    public function render()
    {
        $this->options = [
            ['id' => 0, 'name' => 'Choose'],
        ];

        foreach (Option::all() as $option) {
            $this->options[] = [
                'id' => $option->id,
                'name' => $option->translations->where('locale', request()->get('locale', app()->getLocale()))?->first()?->name,
            ];
        }
        $this->options[] = [
            'id' => 9999,
            'name' => 'New option',
        ];

        return view('daylight.store.products.partials.product-options',
            [
                'product' => $this->product,
            ]);
    }
}
