<?php

namespace App\Http\Requests;

use App\Models\Ecommerce\Product\Order\Payment\OrderPayment;
use App\Models\Ecommerce\Product\Order\Shipping\OrderShipping;
use App\Models\Ecommerce\Product\Order\Status\OrderStatus;
use App\Models\System\Settings\Location\Region;
use App\Models\System\Settings\OS;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;

class CheckoutOrderRequest extends FormRequest
{
    /**
     * Configure the validator instance.
     *
     * @param  \Illuminate\Validation\Validator  $validator
     */
    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {
            if (auth()->user()->carts->count() == 0) {
                $validator->errors()->add('user_without_product_in_cart', 'user has no product in his cart');
            }
        });
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules(): array
    {
        return [
            'customer_name' => ['required', 'string', 'max:255'],
            'customer_phone' => ['required', 'integer', 'between:61000000,71999999'],
            'customer_address' => ['required', 'string', 'max:255'],

            'shipping_method' => ['required', 'string', 'max:255', Rule::in(array_keys(OrderShipping::values()))],

            'shipping_price' => ['nullable', 'numeric'],
            'product_ids' => ['required', 'array'],
            'product_ids.*' => ['required', 'integer', 'exists:products,id'],

            'payment_type_id' => ['required', Rule::in(array_keys(OrderPayment::values()))],

            'notes' => ['nullable', 'string', 'max:255'],
            'delivery_time' => ['nullable', 'string', 'max:255', Rule::in(array_keys(OrderShipping::times()))],
            'delivery_at' => ['nullable', 'string', 'max:255', 'date'],
            'region' => ['required', 'string', 'max:255', Rule::in(array_keys(Region::values()))],
            'province_id' => ['nullable', ],

            'source' => ['nullable', 'string', 'in:site,mobile_app'],

            'cart_number' => ['nullable', 'integer'],
            'cart_expiration_date' => ['nullable'],
            'cart_user_name' => ['nullable', 'string'],
            'csv' => ['nullable'],
        ];
    }

    /**
     * Handle a passed validation attempt.
     */
    protected function passedValidation(): void
    {
        $this->merge([
            'number' => Str::random(30),
            'status' => OrderStatus::default(),
            'user_id' => auth()->id(),
            'notes' => $this->notes ?: null,
            'province_id' => $this->province_id ?: null,
            'shipping_price' => $this->shipping_price ?: OrderShipping::priceFor($this->shipping_method),
            'delivery_time' => $this->delivery_time ?: OrderShipping::MORNING,
            'delivery_at' => $this->delivery_at ?: date('Y-m-d'),
            'source_app' => $this->source ?: OS::MOBILE_APP,
        ]);
    }

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array<string, string>
     */
    public function messages(): array
    {
        return [
            'shipping_method.in' => sprintf('Valid sources: %s', implode(', ', array_keys(
                OrderShipping::values()
            ))),
            'payment_type_id.in' => sprintf('Valid sources: %s', implode(', ', array_keys(
                OrderPayment::values()
            ))),
            'delivery_time.in' => sprintf('Valid sources: %s', implode(', ', array_keys(
                OrderShipping::times()
            ))),
            'region.in' => sprintf('Valid sources: %s', implode(', ', array_keys(
                Region::values()
            ))),
        ];
    }
}
