<?php

namespace App\Http\Requests;

use App\Models\Order;
use App\Models\Product;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class StoreReviewRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        // Allow if guest reviews are enabled, or user is authenticated
        if (config('reviews.allow_guest_reviews')) {
            return true;
        }

        return auth()->check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        $productId = $this->route('id') ?? $this->input('product_id');
        $userId = auth()->id();

        $rules = [
            'rating' => 'required|integer|min:1|max:5',
            'title' => 'nullable|string|max:255',
            'body' => 'nullable|string|max:5000',
            'order_id' => 'nullable|exists:orders,id',
        ];

        // If verified purchase only is enabled, order_id becomes required
        if (config('reviews.verified_purchase_only')) {
            $rules['order_id'] = 'required|exists:orders,id';

            // Add custom validation to ensure order contains the product and belongs to user
            $this->merge([
                'custom_order_validation' => true,
            ]);
        }

        return $rules;
    }

    /**
     * Configure the validator instance.
     */
    public function withValidator($validator): void
    {
        $validator->after(function ($validator) {
            $productId = $this->route('id') ?? $this->input('product_id');
            $orderId = $this->input('order_id');
            $userId = auth()->id();

            // Verify product exists
            if ($productId) {
                $product = Product::find($productId);
                if (!$product) {
                    $validator->errors()->add('product_id', 'The selected product does not exist.');
                    return;
                }
            }

            // If verified purchase only, validate order
            if (config('reviews.verified_purchase_only') && $orderId) {
                $order = Order::with('items')->find($orderId);

                if (!$order) {
                    $validator->errors()->add('order_id', 'The selected order does not exist.');
                    return;
                }

                // Check if order belongs to authenticated user
                if ($userId && $order->user_id !== $userId) {
                    $validator->errors()->add('order_id', 'This order does not belong to you.');
                    return;
                }

                // Check if order contains the product
                if ($productId) {
                    $hasProduct = $order->items()->where('product_id', $productId)->exists();
                    if (!$hasProduct) {
                        $validator->errors()->add('order_id', 'This order does not contain the selected product.');
                        return;
                    }
                }
            }
        });
    }

    /**
     * Get custom messages for validator errors.
     */
    public function messages(): array
    {
        return [
            'rating.required' => 'Please select a rating.',
            'rating.integer' => 'Rating must be a number.',
            'rating.min' => 'Rating must be at least 1 star.',
            'rating.max' => 'Rating cannot exceed 5 stars.',
            'title.max' => 'Title cannot exceed 255 characters.',
            'body.max' => 'Review text cannot exceed 5000 characters.',
            'order_id.required' => 'Order ID is required for verified purchase reviews.',
            'order_id.exists' => 'The selected order does not exist.',
        ];
    }
}
