<?php

namespace App\Http\Requests;

use App\Events\DealershipDataValidationEvent;
use App\Rules\DealershipDepartmentHasPrimaryRule;
use App\Rules\DealershipDepartmentUniqueNameRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Mtc\ContentManager\Rules\IsSlugRule;
use Mtc\MercuryDataModels\Country;
use Mtc\MercuryDataModels\SeoData;
use Stancl\Tenancy\Database\Concerns\CentralConnection;

class UpdateDealershipRequest extends FormRequest
{
    use CentralConnection;

    /**
     * @var bool
     */
    private bool $requires_postcode = true;

    private array $extra_fields = [];
    private array $extra_field_attributes = [];

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return Auth::check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        $global = $this->getConnectionName();
        return array_merge([
            'name' => 'required',
            'email' => 'email',
            'contact_no' => 'required',
            'address1' => 'sometimes',
            'address2' => 'sometimes',
            'city' => 'sometimes',
            'county' => 'sometimes',
            'postcode' => $this->requires_postcode ? 'sometimes' : 'required',
            'country' => "exists:$global.countries,code",
            'coordinates.lat' => 'numeric',
            'coordinates.lng' => 'numeric',
            'contact_form_id' => [
                'sometimes',
//                'exists:forms,id'
            ],
            'media_id' => [
                'sometimes',
//                'exists:media,id'
            ],
            'holidays' => [
                'array',
            ],
            'holidays.*' => [
                'date'
            ],
            'seo.title' => [
                'nullable',
                'min:' . SeoData::TITLE_MIN_LENGTH,
                'max:' . SeoData::TITLE_MAX_LENGTH,
            ],
            'seo.description' => [
                'nullable',
                'min:' . SeoData::DESCRIPTION_MIN_LENGTH,
                'max:' . SeoData::DESCRIPTION_MAX_LENGTH,
            ],
            'seo.jsonSchema' => 'json',
            'seo.slug' => [
                'nullable',
                new IsSlugRule(),
                'unique:vehicle_offers,slug,' . ($this->vehicle_offer->id ?? 0)
            ],
            'departments' => [
                'array',
                new DealershipDepartmentHasPrimaryRule(),
                new DealershipDepartmentUniqueNameRule(),
            ],
            'departments.*.is_primary' => [
                'required'
            ],
        ], $this->extra_fields);
    }

    /**
     * Prepare request for validation
     *
     * @return void
     */
    protected function prepareForValidation()
    {
        $this->requires_postcode = Country::query()
            ->where('code', $this->input('country'))
            ->where('has_postcodes', 1)
            ->exists();

        $fields = collect(event(new DealershipDataValidationEvent()))
            ->filter()
            ->mapWithKeys(fn($field) => $field);

        $this->extra_fields = $fields
            ->map(fn($field) => $field['validation'] ?? 'sometimes')
            ->keyBy(fn($field, $key) => 'data.' . $key)
            ->toArray();

        $this->extra_field_attributes = $fields
            ->map(fn($field) => $field['label'] ?? '')
            ->keyBy(fn($field, $key) => 'data.' . $key)
            ->filter()
            ->toArray();
    }

    public function attributes()
    {
        return array_merge([
            'open_times.1.open' => 'Monday open time',
            'open_times.1.close' => 'Monday close time',
            'open_times.2.open' => 'Tuesday open time',
            'open_times.2.close' => 'Tuesday close time',
            'open_times.3.open' => 'Wednesday open time',
            'open_times.3.close' => 'Wednesday close time',
            'open_times.4.open' => 'Thursday open time',
            'open_times.4.close' => 'Thursday close time',
            'open_times.5.open' => 'Friday open time',
            'open_times.5.close' => 'Friday close time',
            'open_times.6.open' => 'Saturday open time',
            'open_times.6.close' => 'Saturday close time',
            'open_times.7.open' => 'Sunday open time',
            'open_times.7.close' => 'Sunday close time',
            'seo.slug' => 'slug',
            'seo.title' => 'SEO page title',
            'seo.description' => 'SEO page description',

        ], $this->extra_field_attributes);
    }
}
