<?php

namespace Modules\Order\Requests\Api\Cart;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
use Modules\Order\Services\CartService;
use Modules\Product\Services\ProductService;
use Modules\Product\Services\ProductWarehouseService;
use Modules\User\Services\AccountService;

class CreateRequest extends FormRequest
{
    public function __construct(
        private ProductService $productService,
        private CartService $cartService,
        private AccountService $accountService,
        private ProductWarehouseService $productWarehouseService,
    ){}

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

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        $req_count = 0;
        $account = $this->accountService->getAccount();
        $user = $account['user'];
        $rules =
            [
                'product_id'=>[
                    'required',
                    Rule::exists('products','id')->whereNull('deleted_at')
                ],
                'count'=>'required|numeric|min:1',
            ];
        if(request('product_id'))
        {
            $product = $this->productService->checkItem(request('product_id'));

            if ($product) {
                $max_count_order = !is_null($product->max_count_order) ? $product->max_count_order : $product->category->max_count_order;
                $rules['count'] = [
                    'required',
                    'numeric',
                    'min:1',
                    'max:' . $max_count_order
                ];

                $warehouse_id = $user->address->city->warehouses->first()->warehouse_id;

                $stock = $this->productWarehouseService->get([
                    'product_id'=>request('product_id'),
                    'warehouse_id'=>$warehouse_id,
                    'option_id'=>request('option_id'),
                ])->first();



                if ($product->attribute_id) {
                    $rules['option_id'] = [
                        'required',
                        Rule::exists('options', 'id')->whereNull('deleted_at')
                    ];

                    $count = $this->productWarehouseService->get([
                            'warehouse_id' => $warehouse_id,
                            'product_id' => request('product_id'),
                            'option_id' => request('option_id')
                        ])->first()->count ?? 0;
                    if ($count == 0) {
                        $rules['empty'] = [
                            'required'
                        ];
                    }
                    $cart = $this->cartService->getCart([
                        'product_id' => request('product_id'),
                        'option_id' => request('option_id'),
                        'warehouse_id' => $warehouse_id,
                        'user_status' => $account['status'],
                        'user_id' => $user->id,
                    ]);
                    if ($cart)
                    {
                        $req_count = (request('count') + $cart->count);
                        if ($max_count_order < $req_count)
                        {
                            return [
                                'over_count'=>'required'
                            ];
                        }
                    }
                }
                else
                {
                    $count = $this->productWarehouseService->get([
                            'warehouse_id' => $warehouse_id,
                            'product_id' => request('product_id'),
                            'option_id' => null
                        ])->first()->count ?? 0;
                    if ($count == 0) {
                        $rules['empty'] = [
                            'required'
                        ];
                    }
                    $cart = $this->cartService->getCart([
                        'product_id' => request('product_id'),
                        'option_id' => null,
                        'warehouse_id' => $warehouse_id,
                        'user_status' => $account['status'],
                        'user_id' => $user->id,
                    ]);
                    if ($cart)
                    {
                        $req_count = (request('count') + $cart->count);
                        if ($max_count_order < $req_count)
                        {
                            return [
                                'over_count'=>'required'
                            ];
                        }
                    }
                }

                if ($stock)
                {
                    if ($stock->count < $req_count)
                    {
                        return [
                            'product_over'=>'required'
                        ];
                    }
                }
                else
                {
                    return [
                        'product_empty'=>'required'
                    ];
                }

            }
        }
        return $rules;
    }

    public function messages()
    {
        return [
            'over_count.required' => __('web.over_count'),
            'product_over.required' => __('web.product_over'),
            'product_empty.required' => __('web.product_empty'),
        ];
    }

    /**
     * Get custom attributes for validator errors.
     *
     * @return array
     */
    public function attributes()
    {

        $attributes= [
            'product_id' => __('web.product_id'),
            'count' => __('web.count'),
            'option_id' => __('web.option'),
        ];
        return $attributes;
    }

    /**
     * Handle a failed validation attempt.
     *
     * Override the parent method action if the request is for AJAX
     *
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    protected function failedValidation(Validator $validator)
    {
        // Change response attitude if the request done via Ajax requests like API requests

        $errors = (new ValidationException($validator))->errors();
        $message = $validator->errors()->first();
        throw new HttpResponseException(response()->json(['message'=> $message, 'errors' => $errors],  400));

    }
}
