<?php

namespace Tests\Feature;

use App\Models\Student;
use App\Models\User;
use App\Models\Teacher;
use App\Services\StudentIdService;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class StudentResourceTest extends TestCase
{
    use WithFaker;

    private User $adminUser;
    private Teacher $teacher;

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

        // 手动创建管理员用户（避免RefreshDatabase的问题）
        $this->adminUser = User::create([
            'user_id' => 'test_admin_' . uniqid(),
            'username' => 'admin_' . uniqid(),
            'full_name' => 'Admin User',
            'email' => 'admin' . uniqid() . '@test.com',
            'password_hash' => \Hash::make('password'),
            'role' => 'admin',
            'is_active' => 1,
        ]);

        // 手动创建老师用户和老师记录
        $teacherUser = User::create([
            'user_id' => 'test_teacher_user_' . uniqid(),
            'username' => 'teacher_' . uniqid(),
            'full_name' => 'Test Teacher',
            'email' => 'teacher' . uniqid() . '@test.com',
            'password_hash' => \Hash::make('password'),
            'role' => 'teacher',
            'is_active' => 1,
        ]);

        $this->teacher = Teacher::create([
            'teacher_id' => 'test_teacher_' . uniqid(),
            'user_id' => $teacherUser->user_id,
            'name' => 'Test Teacher',
            'subject' => '数学',
        ]);
    }

    /**
     * 测试学生ID生成服务
     */
    public function test_student_id_generation(): void
    {
        $studentId1 = StudentIdService::generateStudentId();
        $studentId2 = StudentIdService::generateStudentId();

        // 验证格式
        $this->assertTrue(StudentIdService::validateStudentIdFormat($studentId1));
        $this->assertTrue(StudentIdService::validateStudentIdFormat($studentId2));

        // 验证唯一性
        $this->assertNotEquals($studentId1, $studentId2);

        // 验证格式模式
        $this->assertMatchesRegularExpression('/^stu_\d+_\d+$/', $studentId1);
    }

    /**
     * 测试学生创建功能
     */
    public function test_create_student(): void
    {
        $studentData = [
            'name' => '测试学生',
            'grade' => '高一',
            'class_name' => '1班',
            'teacher_id' => $this->teacher->teacher_id,
            'remark' => '测试备注',
        ];

        $student = new Student();
        $student->fill($studentData);
        $student->save();

        // 验证学生记录
        $this->assertDatabaseHas('students', [
            'name' => '测试学生',
            'grade' => '高一',
            'class_name' => '1班',
            'teacher_id' => $this->teacher->teacher_id,
        ]);

        // 验证学生ID自动生成
        $this->assertNotNull($student->student_id);
        $this->assertTrue(StudentIdService::validateStudentIdFormat($student->student_id));

        // 验证对应的用户记录被创建
        $this->assertDatabaseHas('users', [
            'user_id' => $student->student_id,
            'username' => $student->student_id,
            'role' => 'student',
            'full_name' => '测试学生',
        ]);
    }

    /**
     * 测试创建学生时班级字段为可选
     */
    public function test_create_student_without_class(): void
    {
        $student = new Student();
        $student->name = '无班级学生';
        $student->grade = '高二';
        $student->teacher_id = $this->teacher->teacher_id;
        $student->save();

        $this->assertNull($student->class_name);
        $this->assertDatabaseHas('students', [
            'student_id' => $student->student_id,
            'class_name' => null,
        ]);
    }

    /**
     * 测试学生更新功能
     */
    public function test_update_student(): void
    {
        // 先创建一个学生
        $student = Student::create([
            'student_id' => StudentIdService::generateStudentId(),
            'name' => '原姓名',
            'grade' => '高一',
            'teacher_id' => $this->teacher->teacher_id,
        ]);

        // 更新学生信息
        $student->update([
            'name' => '新姓名',
            'grade' => '高二',
            'class_name' => '2班',
        ]);

        $this->assertDatabaseHas('students', [
            'student_id' => $student->student_id,
            'name' => '新姓名',
            'grade' => '高二',
            'class_name' => '2班',
        ]);
    }

    /**
     * 测试学生删除功能
     */
    public function test_delete_student(): void
    {
        $student = Student::create([
            'student_id' => StudentIdService::generateStudentId(),
            'name' => '待删除学生',
            'grade' => '高一',
            'teacher_id' => $this->teacher->teacher_id,
        ]);

        $studentId = $student->student_id;

        // 验证记录存在
        $this->assertDatabaseHas('students', ['student_id' => $studentId]);
        $this->assertDatabaseHas('users', ['user_id' => $studentId]);

        // 删除学生
        $student->delete();

        // 验证记录被删除
        $this->assertDatabaseMissing('students', ['student_id' => $studentId]);
        // 注意：由于外键约束，用户记录可能也会被删除
    }

    /**
     * 测试学生和老师的关系
     */
    public function test_student_teacher_relationship(): void
    {
        $student = Student::create([
            'student_id' => StudentIdService::generateStudentId(),
            'name' => '关联测试学生',
            'grade' => '高一',
            'teacher_id' => $this->teacher->teacher_id,
        ]);

        // 测试关系
        $this->assertEquals($this->teacher->teacher_id, $student->teacher_id);
        $this->assertInstanceOf(Teacher::class, $student->teacher);
    }

    /**
     * 测试空班级字段的显示
     */
    public function test_empty_class_name_display(): void
    {
        $student = Student::create([
            'student_id' => StudentIdService::generateStudentId(),
            'name' => '无班级学生',
            'grade' => '高三',
            'teacher_id' => $this->teacher->teacher_id,
        ]);

        // 测试班级字段为空时的处理
        $this->assertNull($student->class_name);

        // 模拟表格显示逻辑
        $displayValue = $student->class_name ?: '未分配';
        $this->assertEquals('未分配', $displayValue);
    }

    /**
     * 测试批量创建学生
     */
    public function test_bulk_create_students(): void
    {
        $students = [];
        for ($i = 1; $i <= 5; $i++) {
            $student = new Student();
            $student->name = "测试学生{$i}";
            $student->grade = '高一';
            $student->teacher_id = $this->teacher->teacher_id;
            $student->save();
            $students[] = $student;
        }

        // 验证所有学生都被创建
        $this->assertCount(5, $students);

        // 验证每个学生的ID都是唯一的
        $studentIds = array_map(fn($s) => $s->student_id, $students);
        $this->assertEquals(count($studentIds), count(array_unique($studentIds)));

        // 验证对应的用户记录都被创建
        foreach ($students as $student) {
            $this->assertDatabaseHas('users', [
                'user_id' => $student->student_id,
                'role' => 'student',
            ]);
        }
    }
}
