<?php

namespace Tests\Unit;

use App\Models\OCRRecord;
use App\Models\OCRQuestionResult;
use App\Models\Student;
use App\Models\Teacher;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class OCRRecordModelTest extends TestCase
{
    use RefreshDatabase;

    protected Student $student;

    protected function setUp(): void
    {
        parent::setUp();

        $teacher = Teacher::create([
            'teacher_id' => 'teacher_001',
            'name' => '测试教师',
        ]);

        $this->student = Student::create([
            'student_id' => 'stu_001',
            'name' => '张三',
            'grade' => '七年级',
            'class_name' => '1班',
            'teacher_id' => $teacher->teacher_id,
        ]);
    }

    /** @test */
    public function it_can_create_ocr_record()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test_exam.jpg',
            'image_path' => 'uploads/test_exam.jpg',
            'status' => 'pending',
            'total_questions' => 20,
            'processed_questions' => 0,
        ]);

        $this->assertInstanceOf(OCRRecord::class, $record);
        $this->assertDatabaseHas('ocr_records', [
            'student_id' => $this->student->student_id,
            'image_filename' => 'test_exam.jpg',
            'status' => 'pending',
        ]);
    }

    /** @test */
    public function it_has_student_relationship()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'pending',
            'total_questions' => 10,
        ]);

        $this->assertNotNull($record->student);
        $this->assertEquals($this->student->name, $record->student->name);
    }

    /** @test */
    public function it_has_questions_relationship()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'processing',
            'total_questions' => 2,
        ]);

        OCRQuestionResult::create([
            'ocr_record_id' => $record->id,
            'question_number' => 1,
            'kp_code' => 'KP001',
            'score_value' => 5,
        ]);

        OCRQuestionResult::create([
            'ocr_record_id' => $record->id,
            'question_number' => 2,
            'kp_code' => 'KP002',
            'score_value' => 10,
        ]);

        $this->assertCount(2, $record->questions);
    }

    /** @test */
    public function it_casts_qr_code_data_to_array()
    {
        $qrData = ['exam_id' => 'EXAM001', 'paper_code' => 'PAPER123'];

        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'pending',
            'total_questions' => 10,
            'qr_code_data' => json_encode($qrData),
        ]);

        $this->assertIsArray($record->qr_code_data);
        $this->assertEquals($qrData, $record->qr_code_data);
    }

    /** @test */
    public function it_calculates_progress_percentage()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'processing',
            'total_questions' => 20,
            'processed_questions' => 15,
        ]);

        $this->assertEquals(75, $record->progress_percentage);
    }

    /** @test */
    public function it_returns_zero_progress_when_total_is_zero()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'pending',
            'total_questions' => 0,
            'processed_questions' => 0,
        ]);

        $this->assertEquals(0, $record->progress_percentage);
    }

    /** @test */
    public function it_can_update_status()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'pending',
            'total_questions' => 10,
        ]);

        $record->update(['status' => 'completed']);

        $this->assertEquals('completed', $record->fresh()->status);
    }

    /** @test */
    public function it_can_update_confidence_average()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'processing',
            'total_questions' => 10,
            'confidence_avg' => null,
        ]);

        $record->update(['confidence_avg' => 0.8523]);

        $this->assertEquals(0.8523, $record->fresh()->confidence_avg);
    }

    /** @test */
    public function it_stores_processed_at_timestamp()
    {
        $now = now();

        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'completed',
            'total_questions' => 10,
            'processed_questions' => 10,
            'processed_at' => $now,
        ]);

        $this->assertNotNull($record->processed_at);
        $this->assertEquals($now->format('Y-m-d H:i:s'), $record->processed_at->format('Y-m-d H:i:s'));
    }

    /** @test */
    public function it_can_store_error_message()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'failed',
            'total_questions' => 0,
            'error_message' => 'OCR API timeout',
        ]);

        $this->assertEquals('OCR API timeout', $record->error_message);
    }

    /** @test */
    public function it_deletes_related_questions_on_cascade()
    {
        $record = OCRRecord::create([
            'student_id' => $this->student->student_id,
            'image_filename' => 'test.jpg',
            'status' => 'completed',
            'total_questions' => 1,
        ]);

        $question = OCRQuestionResult::create([
            'ocr_record_id' => $record->id,
            'question_number' => 1,
            'kp_code' => 'KP001',
        ]);

        $questionId = $question->id;
        $record->delete();

        $this->assertDatabaseMissing('ocr_question_results', ['id' => $questionId]);
    }
}
