<?php

namespace App\Services;

use App\Domain\Questions\QuestionPipeline;
use App\Models\PreQuestionCandidate;
use App\Models\Question;
use App\Models\QuestionMeta;
use Illuminate\Support\Facades\DB;

class QuestionReviewService
{
    public function __construct(private readonly QuestionPipeline $pipeline)
    {
    }

    public function promoteCandidateToQuestion(int $candidateId): ?Question
    {
        $candidate = PreQuestionCandidate::find($candidateId);
        if (!$candidate) {
            return null;
        }

        return DB::transaction(function () use ($candidate) {
            $payload = $this->pipeline->run([
                'raw' => $candidate->raw_markdown ?? $candidate->raw_text ?? '',
                'options' => $candidate->options ?? [],
            ]);

            $questionType = $payload['question_type'] ?? $this->inferQuestionType($candidate);

            $question = Question::create([
                'question_code' => $this->buildQuestionCode($candidate),
                'question_type' => $questionType,
                'stem' => $payload['stem'] ?? $candidate->stem ?? $candidate->raw_text ?? '',
                'options' => $payload['options'] ?? $candidate->options ?? null,
                'answer' => null,
                'solution' => null,
                'difficulty' => $payload['difficulty'] ?? 1,
                'source_file_id' => $candidate->source_file_id,
                'source_paper_id' => $candidate->source_paper_id,
                'paper_part_id' => $candidate->part_id,
                'meta' => [
                    'candidate_id' => $candidate->id,
                ],
            ]);

            QuestionMeta::updateOrCreate(
                ['question_id' => $question->id],
                [
                    'abilities' => [],
                    'generation_info' => [
                        'source' => 'candidate',
                        'candidate_id' => $candidate->id,
                    ],
                    'review_status' => 'pending',
                ]
            );

            $candidate->status = PreQuestionCandidate::STATUS_ACCEPTED;
            $candidate->save();

            return $question;
        });
    }

    private function inferQuestionType(PreQuestionCandidate $candidate): string
    {
        if (!empty($candidate->options)) {
            return 'choice';
        }

        return 'answer';
    }

    private function buildQuestionCode(PreQuestionCandidate $candidate): string
    {
        return sprintf('Q-%s-%d', date('Ymd'), $candidate->id);
    }
}
