<?php

namespace App\Filament\Pages;

use App\Models\PreQuestionCandidate;
use App\Services\QuestionReviewService;
use App\Services\QuestionGenerationService;
use App\Services\AiKnowledgeService;
use App\Services\AiSolutionService;
use Filament\Pages\Page;
use UnitEnum;

class QuestionReviewWorkbench extends Page
{
    protected static bool $shouldRegisterNavigation = true;

    protected static ?string $navigationLabel = '题目审核工作台';

    protected static UnitEnum|string|null $navigationGroup = '卷子导入流程';

    protected static ?int $navigationSort = 5;

    protected string $view = 'filament.pages.question-review-workbench';

    public ?int $selectedId = null;
    public array $selectedIds = [];
    public ?string $groupBy = 'paper';

    public function candidates()
    {
        return PreQuestionCandidate::query()
            ->with(['sourcePaper', 'part'])
            ->orderBy('sequence')
            ->limit(200)
            ->get();
    }

    public function groupedCandidates()
    {
        $candidates = $this->candidates();

        if ($this->groupBy === 'part') {
            return $candidates->groupBy(fn ($candidate) => $candidate->part?->title ?? '未分区块');
        }

        if ($this->groupBy === 'type') {
            return $candidates->groupBy(fn ($candidate) => $candidate->meta['question_type'] ?? '未标注题型');
        }

        return $candidates->groupBy(fn ($candidate) => $candidate->sourcePaper?->title ?? '未分卷');
    }

    public function stats(): array
    {
        $all = PreQuestionCandidate::query()->count();
        $pending = PreQuestionCandidate::query()->where('status', PreQuestionCandidate::STATUS_PENDING)->count();
        $reviewed = PreQuestionCandidate::query()->where('status', PreQuestionCandidate::STATUS_REVIEWED)->count();
        $accepted = PreQuestionCandidate::query()->where('status', PreQuestionCandidate::STATUS_ACCEPTED)->count();

        return compact('all', 'pending', 'reviewed', 'accepted');
    }

    public function selectCandidate(int $candidateId): void
    {
        $this->selectedId = $candidateId;
    }

    public function selectAllVisible(): void
    {
        $this->selectedIds = $this->candidates()->pluck('id')->toArray();
    }

    public function clearSelection(): void
    {
        $this->selectedIds = [];
    }

    public function approve(): void
    {
        $candidateId = $this->selectedId;
        if (!$candidateId) {
            return;
        }

        $service = app(QuestionReviewService::class);
        $service->promoteCandidateToQuestion($candidateId);
    }

    public function reject(): void
    {
        $candidateId = $this->selectedId;
        if (!$candidateId) {
            return;
        }

        PreQuestionCandidate::where('id', $candidateId)->update([
            'status' => PreQuestionCandidate::STATUS_REJECTED,
        ]);
    }

    public function bulkApprove(): void
    {
        $service = app(QuestionReviewService::class);
        foreach ($this->selectedIds as $candidateId) {
            $service->promoteCandidateToQuestion((int) $candidateId);
        }
    }

    public function bulkReject(): void
    {
        PreQuestionCandidate::query()
            ->whereIn('id', $this->selectedIds)
            ->update(['status' => PreQuestionCandidate::STATUS_REJECTED]);
    }

    public function aiAssist(): void
    {
        $candidate = $this->currentCandidate();
        if (!$candidate) {
            return;
        }

        $sourceText = $candidate->stem ?: (string) $candidate->raw_markdown;
        $result = app(QuestionGenerationService::class)->generateFromSource($sourceText);
        if (!($result['success'] ?? false)) {
            return;
        }

        $question = $result['question'] ?? [];
        $meta = $candidate->meta ?? [];
        $meta['question_type'] = $question['question_type'] ?? $meta['question_type'] ?? null;
        $meta['difficulty'] = $question['difficulty'] ?? $meta['difficulty'] ?? null;
        $meta['kp_codes'] = $question['knowledge_points'] ?? $meta['kp_codes'] ?? [];
        $meta['solution'] = $question['solution'] ?? $meta['solution'] ?? null;
        $meta['solution_steps'] = $question['solution_steps'] ?? $meta['solution_steps'] ?? [];

        $candidate->update([
            'stem' => $question['stem'] ?? $candidate->stem,
            'options' => $question['options'] ?? $candidate->options,
            'meta' => $meta,
        ]);
    }

    public function aiMatchKp(): void
    {
        $candidate = $this->currentCandidate();
        if (!$candidate) {
            return;
        }

        $text = $candidate->stem ?: (string) $candidate->raw_markdown;
        $matches = app(AiKnowledgeService::class)->matchKnowledgePointsByAi($text);
        $kpCodes = array_values(array_filter(array_map(fn ($item) => $item['kp_code'] ?? null, $matches)));

        $meta = $candidate->meta ?? [];
        $meta['kp_codes'] = $kpCodes;
        $candidate->update(['meta' => $meta]);
    }

    public function aiGenerateSolution(): void
    {
        $candidate = $this->currentCandidate();
        if (!$candidate) {
            return;
        }

        $result = app(AiSolutionService::class)->generateSolution($candidate->stem ?? '');
        $meta = $candidate->meta ?? [];
        $meta['solution'] = $result['solution'] ?? '';
        $meta['solution_steps'] = $result['steps'] ?? [];
        $candidate->update(['meta' => $meta]);
    }

    public function currentCandidate(): ?PreQuestionCandidate
    {
        return $this->selectedId ? PreQuestionCandidate::query()->find($this->selectedId) : null;
    }

    public function jumpToNextIssue(): void
    {
        $candidates = $this->candidates();
        $currentIndex = $candidates->search(fn ($item) => $item->id === $this->selectedId);

        $find = function ($start) use ($candidates) {
            for ($i = $start; $i < $candidates->count(); $i++) {
                $candidate = $candidates[$i];
                $meta = $candidate->meta ?? [];
                if (empty($meta['difficulty']) || empty($meta['kp_codes']) || empty($meta['answer']) || empty($meta['solution'])) {
                    return $candidate->id;
                }
            }
            return null;
        };

        $nextId = $find(($currentIndex !== false ? $currentIndex + 1 : 0)) ?? $find(0);
        if ($nextId) {
            $this->selectedId = $nextId;
        }
    }
}
