<?php

namespace App\Forms\Components;

use App\Models\Student;
use App\Models\Teacher;
use Filament\Forms\Components\Field;
use Filament\Forms\Components\Select;
use Illuminate\Support\Collection;

class TeacherStudentSelector extends Field
{
    protected string $view = 'forms.components.teacher-student-selector';

    protected array $teacherOptions = [];
    protected array $studentOptions = [];
    protected bool $enableTeacherFilter = true;
    protected bool $required = false;
    protected string $teacherLabel = '选择老师';
    protected string $studentLabel = '选择学生';
    protected string $teacherPlaceholder = '请选择老师...';
    protected string $studentPlaceholder = '请选择学生...';
    protected ?string $teacherHelperText = null;
    protected ?string $studentHelperText = null;

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

        $this->afterStateUpdated(function (TeacherStudentSelector $component, string|int|null $state) {
            // 当老师选择变化时，清空学生选择并更新学生选项
            if ($this->isTeacherField()) {
                $component->getContainer()->getComponent('student_id')->state('');
            }
        });

        // 初始化老师选项
        $this->loadTeacherOptions();
    }

    protected function isTeacherField(): bool
    {
        return $this->getName() === 'teacher_id';
    }

    protected function loadTeacherOptions(): void
    {
        try {
            $teachers = Teacher::query()
                ->leftJoin('users as u', 'teachers.teacher_id', '=', 'u.user_id')
                ->select(
                    'teachers.teacher_id',
                    'teachers.name',
                    'teachers.subject',
                    'u.username',
                    'u.email'
                )
                ->orderBy('teachers.name')
                ->get();

            // 检查是否有学生没有对应的老师记录
            $teacherIds = $teachers->pluck('teacher_id')->toArray();
            $missingTeacherIds = Student::query()
                ->distinct()
                ->whereNotIn('teacher_id', $teacherIds)
                ->pluck('teacher_id')
                ->toArray();

            $teachersArray = $teachers->all();

            if (!empty($missingTeacherIds)) {
                foreach ($missingTeacherIds as $missingId) {
                    $teachersArray[] = (object) [
                        'teacher_id' => $missingId,
                        'name' => '未知老师 (' . $missingId . ')',
                        'subject' => '未知',
                        'username' => null,
                        'email' => null
                    ];
                }

                usort($teachersArray, function($a, $b) {
                    return strcmp($a->name, $b->name);
                });
            }

            $this->teacherOptions = collect($teachersArray)->mapWithKeys(function ($teacher) {
                return [
                    $teacher->teacher_id => trim($teacher->name .
                        ($teacher->subject ? " ({$teacher->subject})" : ''))
                ];
            })->toArray();

        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('加载老师列表失败', [
                'error' => $e->getMessage()
            ]);
            $this->teacherOptions = [];
        }
    }

    protected function loadStudentOptions(?string $teacherId = null): array
    {
        if (empty($teacherId)) {
            return [];
        }

        try {
            return Student::query()
                ->leftJoin('users as u', 'students.student_id', '=', 'u.user_id')
                ->where('students.teacher_id', $teacherId)
                ->select(
                    'students.student_id',
                    'students.name',
                    'students.grade',
                    'students.class_name',
                    'u.username',
                    'u.email'
                )
                ->orderBy('students.grade')
                ->orderBy('students.class_name')
                ->orderBy('students.name')
                ->get()
                ->mapWithKeys(function ($student) {
                    return [
                        $student->student_id => trim($student->name .
                            " ({$student->grade} - {$student->class_name})")
                    ];
                })
                ->toArray();
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('加载学生列表失败', [
                'teacher_id' => $teacherId,
                'error' => $e->getMessage()
            ]);
            return [];
        }
    }

    public function teacherOptions(array $options): static
    {
        $this->teacherOptions = $options;
        return $this;
    }

    public function studentOptions(array $options): static
    {
        $this->studentOptions = $options;
        return $this;
    }

    public function enableTeacherFilter(bool $condition = true): static
    {
        $this->enableTeacherFilter = $condition;
        return $this;
    }

    public function teacherLabel(string $label): static
    {
        $this->teacherLabel = $label;
        return $this;
    }

    public function studentLabel(string $label): static
    {
        $this->studentLabel = $label;
        return $this;
    }

    public function teacherPlaceholder(string $placeholder): static
    {
        $this->teacherPlaceholder = $placeholder;
        return $this;
    }

    public function studentPlaceholder(string $placeholder): static
    {
        $this->studentPlaceholder = $placeholder;
        return $this;
    }

    public function teacherHelperText(?string $text): static
    {
        $this->teacherHelperText = $text;
        return $this;
    }

    public function studentHelperText(?string $text): static
    {
        $this->studentHelperText = $text;
        return $this;
    }

    public function getTeacherOptions(): array
    {
        return $this->teacherOptions;
    }

    public function getStudentOptions(?string $teacherId = null): array
    {
        return $this->enableTeacherFilter ?
            $this->loadStudentOptions($teacherId) :
            $this->studentOptions;
    }

    public function isRequired(): bool
    {
        return $this->required;
    }

    public function isTeacherFilterEnabled(): bool
    {
        return $this->enableTeacherFilter;
    }

    public function getTeacherLabel(): string
    {
        return $this->teacherLabel;
    }

    public function getStudentLabel(): string
    {
        return $this->studentLabel;
    }

    public function getTeacherPlaceholder(): string
    {
        return $this->teacherPlaceholder;
    }

    public function getStudentPlaceholder(): string
    {
        return $this->studentPlaceholder;
    }

    public function getTeacherHelperText(): ?string
    {
        return $this->teacherHelperText;
    }

    public function getStudentHelperText(): ?string
    {
        return $this->studentHelperText;
    }
}