<?php

namespace App\Services\Ai;

use App\Enums\DifficultyLevelEnums;
use App\Enums\QuestionTypeEnum;
use App\Exceptions\CustomWebException;
use App\Models\Contest;
use App\Models\Language;
use App\Models\Quiz;
use Illuminate\Http\Request;

class AiService implements Ai
{
    protected $aiServiceInstance;

    public function __construct()
    {
        $this->setup();
    }

    public function setup(?string $providerName = null): self
    {
        $ai_providers = config('services.ai');

        // If no provider specified, find the active one
        if (! $providerName) {
            foreach ($ai_providers as $key => $config) {
                if (isset($config['is_active']) && $config['is_active'] === true) {
                    $providerName = $key;
                    break;
                }
            }
        }

        if (! $providerName) {
            throw new CustomWebException(__('No active AI service found!'));
        }

        $provider = $ai_providers[$providerName] ?? null;

        if (! isset($provider['is_active']) || ! $provider['is_active']) {
            throw new CustomWebException("AI service '{$providerName}' is not active");
        }

        $class = $this->getServiceClass($providerName);

        if (! class_exists($class)) {
            throw new CustomWebException('AI service class not found');
        }

        $this->aiServiceInstance = app($class);

        return $this;
    }

    public function getPrompt(): ?string
    {
        return $this->aiServiceInstance->getPrompt();
    }

    public function process(?string $prompt = null): array
    {
        return $this->aiServiceInstance->process($prompt);
    }

    public function buildQuestionPrompt(QuestionTypeEnum $type, string $topic, string $topic_details, DifficultyLevelEnums $level, int $questionCount, ?string $language = 'English'): self
    {
        $this->aiServiceInstance->buildQuestionPrompt($type, $topic, $topic_details, $level, $questionCount, $language);

        return $this;
    }

    public function buildQuestionTranslationPrompt(array $attributes): self
    {
        $this->aiServiceInstance->buildQuestionTranslationPrompt($attributes);

        return $this;
    }

    /**
     * Given a service name gemini, returns the fully qualified class name for the service
     * (e.g. App\Services\Ai\GeminiService)
     */
    private function getServiceClass(string $service): string
    {
        return match ($service) {
            'gemini' => \App\Services\Ai\GeminiService::class,
            'openai' => \App\Services\Ai\OpenAiService::class,
            'deepseek' => \App\Services\Ai\DeepSeekService::class,
            default => throw new CustomWebException('AI service not configured'),
        };
    }

    public function storeQuestion(array $questions, Contest|Quiz $contest, Language $language, Request $request)
    {
        $order = $contest->questions()->max('order') + 1;
        foreach ($questions as $question) {
            $questionModal = $contest->questions()->create([
                ...$question,
                'score' => $request->score,
                'time_limit' => $request->time_limit,
                'question_type' => $request->question_type,
                'order' => $order++,
            ]);

            $questionModal->translations()->updateOrCreate(
                [
                    'locale' => $language->code,
                ],
                [
                    'question_text' => $question['question_text'],
                    'question_explanation' => $question['question_explanation'],
                    'hints' => $question['hints'],
                    'answer_explanation' => $question['answer_explanation'],
                ]
            );
        }
    }

    public function updateQuestionLanguages(Contest|Quiz $contest, Language $language, Request $request)
    {
        $attributes = [
            'source_language' => 'English',
            'target_language' => $language->name,
            'questions' => $contest->questions->map(function ($question) {
                return [
                    'id' => $question->id,
                    'question_text' => $question->translation?->question_text,
                    'question_explanation' => $question->translation?->question_explanation,
                    'hints' => $question->translation?->hints,
                    'answer_explanation' => $question->translation?->answer_explanation,
                ];
            }),
        ];

        $translation = $this->buildQuestionTranslationPrompt($attributes)->process();

        if (! $translation) {
            throw new CustomWebException(__('Translation not found'));
        }

        foreach ($contest->questions as $question) {
            $translation_values = collect($translation)->where('id', $question->id)->first();
            $question->translations()->updateOrCreate(
                [
                    'locale' => $language->code,
                ],
                [
                    'question_text' => $translation_values['question_text'],
                    'question_explanation' => $translation_values['question_explanation'],
                    'hints' => $translation_values['hints'],
                    'answer_explanation' => $translation_values['answer_explanation'],
                ]
            );
        }
    }
}
