<?php

namespace App\Http\Requests\Admin\Contest;

use App\Enums\QuestionExplanationTypeEnum;
use App\Enums\QuestionInputTypeEnum;
use App\Enums\QuestionTypeEnum;
use App\Exceptions\CustomWebException;
use App\Traits\MediaUploader;
use Illuminate\Foundation\Http\FormRequest;

class ContestQuestionRequest extends FormRequest
{
    use MediaUploader;

    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return auth('admin')->check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        $rules = [
            'locale' => 'required|string',
            'question_input_type' => 'required|in:'.implode(',', QuestionInputTypeEnum::values()),
            'hints' => 'nullable|string|max:2000',
            'answer_explanation' => 'nullable|string|max:2000',
            'explanation_type' => 'required|in:'.implode(',', QuestionExplanationTypeEnum::values()),
            'question_explanation' => 'nullable',
            'time_limit' => 'required|numeric|min:0',
            'options' => 'required|array',
            'options.*.label' => 'required|string',
            'options.*.value' => 'required|string',
            'question_type' => 'required|in:'.implode(',', QuestionTypeEnum::values()),
            'correct_answers' => 'required|array',
            'score' => 'required|numeric|min:0',
        ];

        if ($this->question_input_type === QuestionInputTypeEnum::VIDEO->value) {
            $rules['question_explanation'] = 'required|file|mimes:mp4|max:15360'; // 10MB
        }

        if ($this->question_input_type === QuestionInputTypeEnum::AUDIO->value) {
            $rules['question_explanation'] = 'required|file|mimes:mp3|max:15360'; // 10MB
        }

        if ($this->question_input_type === QuestionInputTypeEnum::TEXT->value) {
            $rules['question_explanation'] = 'required|string';
        }

        // Add conditional validation based on explanation_type
        if ($this->explanation_type === QuestionExplanationTypeEnum::VIDEO->value) {
            $rules['question_explanation'] = 'nullable|file|mimes:mp4|max:15360'; // 10MB
        }

        if ($this->explanation_type === QuestionExplanationTypeEnum::AUDIO->value) {
            $rules['question_explanation'] = 'nullable|file|mimes:mp3|max:15360'; // 10MB
        }

        if ($this->explanation_type === QuestionExplanationTypeEnum::TEXT->value) {
            $rules['question_explanation'] = 'nullable|string|max:500';
        }

        // If updating (PUT/PATCH), make some rules nullable
        if ($this->isMethod('put') || $this->isMethod('patch')) {
            $rules = array_merge($rules, [
                'explanation_type' => 'nullable|in:'.implode(',', QuestionExplanationTypeEnum::values()),
                'time_limit' => 'nullable|numeric|min:0',
                'options' => 'nullable|array',
                'options.*.label' => 'nullable|string',
                'options.*.value' => 'nullable|string',
                'question_type' => 'nullable|in:'.implode(',', QuestionTypeEnum::values()),
                'correct_answers' => 'nullable|array',
                'score' => 'nullable|numeric|min:0',
            ]);
        }

        return $rules;
    }

    public function prepareForValidation()
    {
        if (request('locale') != 'en' && ! $this->route('question')) {
            throw new CustomWebException('At first you need to create english question');
        }
    }

    public function questionValidatedData(): array
    {
        $validatedData = $this->validated();
        if ($validatedData['locale'] !== 'en') {
            return [];
        }

        return [
            'explanation_type' => $validatedData['explanation_type'],
            'time_limit' => $validatedData['time_limit'],
            'options' => $validatedData['options'],
            'question_type' => $validatedData['question_type'],
            'correct_answers' => $validatedData['correct_answers'],
            'score' => $validatedData['score'],
        ];
    }

    public function langValidated($key = null, $value = null): array
    {
        $data = $this->validated($key, $value);

        if (isset($data['explanation_type']) && in_array($data['explanation_type'], [QuestionExplanationTypeEnum::VIDEO->value, QuestionExplanationTypeEnum::AUDIO->value]) && isset($data['question_explanation'])) {
            $data['question_explanation'] = $this->upload($data['question_explanation']);
        }

        if (isset($data['question_input_type']) && in_array($data['question_input_type'], [QuestionInputTypeEnum::VIDEO->value, QuestionInputTypeEnum::AUDIO->value])) {
            $data['question_text'] = $this->upload($data['question_text']);
        }

        return [
            'question_text' => $data['question_text'] ?? null,
            'question_explanation' => $data['question_explanation'] ?? null,
            'hints' => $data['hints'] ?? null,
            'answer_explanation' => $data['answer_explanation'] ?? null,
        ];
    }

    public function messages(): array
    {
        return [
            'question_text.required_if' => 'Question text is required.',
            'question_text.string' => 'Question text must be a string.',
            'question_explanation.string' => 'Question explanation must be a string.',
            'hints.max' => 'Hints must not exceed 2000 characters.',
            'answer_explanation.max' => 'Answer explanation must not exceed 2000 characters.',
            'options.required' => 'Options are required.',
            'correct_answers.required' => 'Correct answers are required.',
            'question_explanation.required' => 'Question explanation is required.',
            'explanation_type.required' => 'Explanation type is required.',
            'time_limit.required' => 'Time limit is required.',
            'time_limit.numeric' => 'Time limit must be a number.',
            'time_limit.min' => 'Time limit must be at least 0.',
            'question_type.required' => 'Question type is required.',
            'score.required' => 'Score is required.',
            'score.min' => 'Score must be at least 0.',
        ];
    }
}
