<?php

namespace Daylight\Core\Http\Requests\Store\Products;

use Daylight\Core\Models\Enums\ProductStatus;
use Daylight\Core\Modules\Multilingualism\Multilingualism;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class UpdateProductRequest extends FormRequest
{
    public function authorize(): bool
    {
        return auth()->check() && auth()->user()->can('update:products');
    }

    public function rules(): array
    {
        return [
            'locale' => ['required', 'string', Rule::in(Multilingualism::getAvailableLocales())],
            'type' => ['required', 'string', Rule::in(['simple', 'variable'])],
            'sku' => ['required_if:type,simple', 'string', 'max:255'],

            'translations' => ['required', 'array'],
            'translations.*.name' => ['required', 'string', 'max:255'],
            'translations.*.description' => ['nullable'],
            'translations.*.pros' => ['nullable', 'array'],
            'translations.*.cons' => ['nullable', 'array'],
            'translations.*.robots' => ['required', Rule::in(['index, follow', 'noindex, nofollow', 'nofollow', 'noindex'])],
            'translations.*.meta_title' => ['nullable', 'string', 'max:255'],
            'translations.*.meta_description' => ['nullable', 'string', 'max:255'],

            'brand_id' => ['required', 'exists:brands,id'],

            'categories' => ['nullable', 'array'],
            'categories.*' => ['exists:categories,id'],

            'labels' => ['nullable', 'array'],
            'labels.*' => ['exists:labels,id'],

            'attributes' => ['nullable', 'array'],
            'attributes.*' => ['required', 'exists:attribute_values,id'],

            'downloads' => ['nullable', 'array'],
            'downloads.*.id' => ['exists:media,id'],

            'options' => ['nullable', 'array', 'required_if:type,variable'],
            'options.*.id' => ['required_if:type,variable'],
            'options.*.type' => ['required_if:type,variable', Rule::in(['select', 'swatches'])],
            'options.*.translations' => ['required_if:type,variable', 'array'],
            'options.*.optionValues' => ['required_if:type,variable', 'array'],
            'options.*.optionValues.*.id' => ['required_if:type,variable'],
            'options.*.optionValues.*.translations' => ['array'],
            'options.*.optionValues.*.color' => ['nullable', 'string', 'regex:/^#[0-9A-F]{6}$/i'],

            'variants' => ['nullable', 'array', 'required_if:type,variable'],
            'variants.*.sku' => ['required_if:type,variable', 'distinct', 'string', 'exists:variants,sku'],
            'variants.*.optionValues' => ['required_if:type,variable', 'array'],
            'variants.*.optionValues.*.option_id' => ['required_if:type,variable'],
            'variants.*.optionValues.*.option_value_id' => ['required_if:type,variable'],

            'status' => ['required', 'string', Rule::enum(ProductStatus::class)],
        ];
    }

    public function attributes()
    {
        $attributes = [];

        if ($this->input('variants')) {
            foreach ($this->input('variants', []) as $index => $variant) {
                $attributes["variants.$index.sku"] = 'SKU for row '.($index + 1);
            }
        }

        return [
            'brand_id' => 'brand',
            'translations.*.name' => 'name',
            'translations.*.description' => 'description',
            'translations.*.pros' => 'pros',
            'translations.*.cons' => 'cons',
            'translations.*.robots' => 'robots',
            'translations.*.meta_title' => 'meta title',
            'translations.*.meta_description' => 'meta description',
            ...$attributes,
        ];
    }

    public function prepareForValidation(): void
    {
        $this->merge([
            'options' => json_decode($this->input('options'), true),
            'variants' => json_decode($this->input('variants'), true),
            'gallery' => json_decode($this->input('gallery'), true),
            'downloads' => json_decode($this->input('downloads'), true),
        ]);
    }
}
