<?php

namespace App\Services\Exams;

use App\Models\ExamDraft;
use App\Models\TeacherClass;
use Illuminate\Support\Facades\DB;

class ExamDraftTeacherService
{
    public function __construct(
        private ExamDraftConfigService $configService,
        private ExamDraftFileService $fileService
    ) {
    }

    public function listForTeacher(int $teacherId): array
    {
        $context = $this->configService->context();
        $schoolYear = (string) ($context['school_year'] ?? '');
        $teacherUserColumn = (string) ($context['teacher_user_column'] ?? '');

        $assignments = TeacherClass::getClassAssignmentsByUserId($teacherId, $schoolYear);
        $classSectionIds = array_map(static fn ($a) => (int) $a['class_section_id'], $assignments);

        $drafts = [];
        if ($teacherUserColumn !== '') {
            $drafts = ExamDraft::query()
                ->where($teacherUserColumn, $teacherId)
                ->orderByDesc('created_at')
                ->get()
                ->toArray();
        }

        $legacyExams = [];
        if (($context['has_legacy'] ?? false) && !empty($classSectionIds)) {
            $legacyExams = DB::table('exam_drafts as ed')
                ->select('ed.*', 'cs.class_section_name')
                ->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'ed.class_section_id')
                ->whereIn('ed.class_section_id', $classSectionIds)
                ->where('ed.is_legacy', 1)
                ->whereNotNull('ed.final_file')
                ->orderBy('cs.class_section_name')
                ->orderByDesc('ed.created_at')
                ->get()
                ->map(fn ($r) => (array) $r)
                ->all();
        }

        return [
            'assignments' => $assignments,
            'drafts' => $drafts,
            'legacyExams' => $legacyExams,
            'examTypes' => ExamDraftConfigService::EXAM_TYPES,
            'statusOptions' => ExamDraftConfigService::STATUS_OPTIONS,
            'schoolYear' => $schoolYear,
            'semester' => (string) ($context['semester'] ?? ''),
        ];
    }

    public function store(int $teacherId, array $payload, ?\Illuminate\Http\UploadedFile $file): array
    {
        $context = $this->configService->context();
        $schoolYear = (string) ($context['school_year'] ?? '');
        $semester = (string) ($context['semester'] ?? '');

        $classSectionId = (int) ($payload['class_section_id'] ?? 0);
        $examType = trim((string) ($payload['exam_type'] ?? ''));
        $description = trim((string) ($payload['description'] ?? ''));

        if ($classSectionId <= 0) {
            return ['ok' => false, 'message' => 'Select a class section before submitting.'];
        }

        $assignment = TeacherClass::query()
            ->where('teacher_id', $teacherId)
            ->where('class_section_id', $classSectionId)
            ->first();

        if (!$assignment) {
            return ['ok' => false, 'message' => 'You are not assigned to the selected class section.'];
        }

        $teacherFile = null;
        $teacherFilename = null;
        if ($file) {
            $stored = $this->fileService->storeUploadedFile(
                $file,
                ExamDraftConfigService::TEACHER_UPLOAD_DIR,
                ExamDraftConfigService::ALLOWED_EXTENSIONS,
                ExamDraftConfigService::MAX_UPLOAD_BYTES
            );
            if ($stored === null) {
                return ['ok' => false, 'message' => 'Failed to store the uploaded file.'];
            }
            $teacherFile = $stored['stored'];
            $teacherFilename = $stored['original'];
        }

        $existingDraft = ExamDraft::query()
            ->where('class_section_id', $classSectionId)
            ->where('semester', $semester)
            ->where('school_year', $schoolYear)
            ->orderByDesc('version')
            ->when(
                (string) ($context['teacher_user_column'] ?? '') !== '',
                fn ($query) => $query->where((string) $context['teacher_user_column'], $teacherId)
            )
            ->first();

        $nextVersion = 1;
        $previousId = null;
        if ($existingDraft) {
            $nextVersion = ((int) ($existingDraft->version ?? 1)) + 1;
            $previousId = (int) ($existingDraft->id ?? 0) ?: null;
        }

        $title = $examType !== '' ? $examType : 'Exam Draft';

        $createPayload = [
            'class_section_id' => $classSectionId,
            'semester' => $semester,
            'school_year' => $schoolYear,
            'exam_type' => $examType !== '' ? $examType : null,
            'draft_title' => $title,
            'status' => 'submitted',
            'version' => $nextVersion,
        ];

        if (($context['teacher_user_column'] ?? null) === 'teacher_id') {
            $createPayload['teacher_id'] = $teacherId;
        }
        if (($context['teacher_user_column'] ?? null) === 'author_id') {
            $createPayload['author_id'] = $teacherId;
        }
        if (($context['teacher_comment_column'] ?? null) === 'description') {
            $createPayload['description'] = $description !== '' ? $description : null;
        }
        if (($context['teacher_comment_column'] ?? null) === 'author_comment') {
            $createPayload['author_comment'] = $description !== '' ? $description : null;
        }
        if (($context['teacher_file_column'] ?? null) === 'teacher_file') {
            $createPayload['teacher_file'] = $teacherFile;
        }
        if (($context['teacher_file_column'] ?? null) === 'author_file') {
            $createPayload['author_file'] = $teacherFile;
        }
        if (($context['teacher_filename_column'] ?? null) === 'teacher_filename') {
            $createPayload['teacher_filename'] = $teacherFilename;
        }
        if (($context['teacher_filename_column'] ?? null) === 'author_filename') {
            $createPayload['author_filename'] = $teacherFilename;
        }
        if ($context['has_previous_draft_id'] ?? false) {
            $createPayload['previous_draft_id'] = $previousId;
        }

        $draft = ExamDraft::query()->create($createPayload);

        return [
            'ok' => true,
            'draft' => $draft->toArray(),
        ];
    }
}
