<?php

namespace App\Livewire\Results;

use Livewire\Component;
use App\Models\User;
use App\Models\SchoolSession;
use App\Models\Subject;
use App\Models\Setting;
use App\Services\ResultService;
use App\Traits\HasNotifications;
use Illuminate\Support\Facades\Auth;

class ByStudentForm extends Component
{
    use HasNotifications;

    public $selectedClass = '';
    public $selectedBatch = '';
    public $selectedStudent = '';
    public $selectedSession = '';
    public $searchTerm = '';
    public $searchResults = [];
    public $classes = [];
    public $batches = [];
    public $students = [];
    public $sessions = [];
    public $subjects = [];
    public $results = [];
    public $showSearchResults = false;
    public $loading = false;
    public $canUploadResults = true;
    public $uploadDisabledMessage = '';
    public $hasApprovedResults = false;
    public $canEditApprovedResults = false;

    public function mount()
    {
        $this->checkUploadPermission();
        $this->checkEditApprovedPermission();
        
        if ($this->canUploadResults) {
            $resultService = new ResultService();
            $this->classes = $resultService->getClassesForUser(Auth::user());
            $this->sessions = SchoolSession::orderBy('start_date', 'desc')->get();
            
            // Auto-select current active session
            $activeSession = SchoolSession::where('is_active', true)->first();
            if ($activeSession) {
                $this->selectedSession = $activeSession->id;
            }
        }
    }
    
    private function checkUploadPermission()
    {
        $user = Auth::user();
        
        if ($user->isAdmin() || $user->isHeadTeacher()) {
            $this->canUploadResults = Setting::get('allow_admin_result_upload', true);
            $this->uploadDisabledMessage = 'Result upload for administrators is currently disabled. Please contact the system administrator or enable it in Result Settings.';
        } elseif ($user->isTeacher()) {
            $this->canUploadResults = Setting::get('allow_teacher_result_upload', true);
            $this->uploadDisabledMessage = 'Result upload for teachers is currently disabled. Please contact the administrator or enable it in Result Settings.';
        } else {
            $this->canUploadResults = false;
            $this->uploadDisabledMessage = 'You do not have permission to upload results.';
        }
    }
    
    private function checkEditApprovedPermission()
    {
        $user = Auth::user();
        
        if ($user->isAdmin()) {
            $this->canEditApprovedResults = Setting::get('allow_admin_edit_approved_results', false);
        } elseif ($user->isHeadTeacher()) {
            $this->canEditApprovedResults = Setting::get('allow_head_teacher_edit_approved_results', false);
        } elseif ($user->isTeacher()) {
            $this->canEditApprovedResults = Setting::get('allow_teacher_edit_approved_results', false);
        }
    }
    
    private function checkApprovedResults()
    {
        if ($this->selectedStudent && $this->selectedSession) {
            $this->hasApprovedResults = \App\Models\ResultApproval::where('student_id', $this->selectedStudent)
                ->where('session_id', $this->selectedSession)
                ->exists();
        } else {
            $this->hasApprovedResults = false;
        }
    }

    public function updatedSelectedClass()
    {
        $this->selectedBatch = '';
        $this->batches = [];
        $this->students = [];
        $this->selectedStudent = '';
        $this->searchTerm = '';
        $this->searchResults = [];
        $this->showSearchResults = false;
        $this->clearResults();
        
        if ($this->selectedClass) {
            $this->loadBatches();
        }
    }
    
    public function loadBatches()
    {
        $this->batches = \App\Models\Batch::where('school_class_id', $this->selectedClass)
            ->where('is_active', true)
            ->where('graduated', false)
            ->orderBy('name')
            ->get();
    }
    
    public function updatedSelectedBatch()
    {
        $this->selectedStudent = '';
        $this->searchTerm = '';
        $this->searchResults = [];
        $this->showSearchResults = false;
        $this->clearResults();
        
        if ($this->selectedBatch) {
            $resultService = new ResultService();
            $this->students = $resultService->getStudentsByBatch($this->selectedBatch)->sortBy('firstname');
        } else {
            $this->students = [];
        }
    }

    public function updatedSearchTerm()
    {
        if (strlen($this->searchTerm) >= 2) {
            $resultService = new ResultService();
            $allStudents = $resultService->getAccessibleStudentsForUser(\Illuminate\Support\Facades\Auth::user());
            
            $this->searchResults = $allStudents->filter(function($student) {
                $isGraduated = $student->batch && $student->batch->graduated;
                return $student->active && !$isGraduated && (
                    str_contains(strtolower($student->firstname), strtolower($this->searchTerm)) ||
                    str_contains(strtolower($student->middlename ?? ''), strtolower($this->searchTerm)) ||
                    str_contains(strtolower($student->surname), strtolower($this->searchTerm)) ||
                    str_contains(strtolower($student->email ?? ''), strtolower($this->searchTerm)) ||
                    str_contains(strtolower($student->student_id ?? ''), strtolower($this->searchTerm))
                );
            })->take(10);
            $this->showSearchResults = true;
        } else {
            $this->searchResults = [];
            $this->showSearchResults = false;
        }
    }

    public function selectStudent($studentId)
    {
        $student = User::find($studentId);
        $this->selectedStudent = $studentId;
        $this->searchTerm = $student->name;
        $this->showSearchResults = false;
        
        // Automatically set the class and batch based on student's batch
        if ($student->batch && $student->batch->schoolClass) {
            $this->selectedClass = $student->batch->school_class_id;
            $this->selectedBatch = $student->batch_id;
            $this->loadBatches();
            // Load students for this batch
            $resultService = new ResultService();
            $this->students = $resultService->getStudentsByBatch($this->selectedBatch)->sortBy('firstname');
        }
        
        $this->clearResults();
        $this->checkApprovedResults();
        
        // Auto-load results if session is selected
        if ($this->selectedSession) {
            $this->loadResults();
        }
    }

    public function updatedSelectedStudent()
    {
        if ($this->selectedStudent) {
            $student = User::find($this->selectedStudent);
            $this->searchTerm = $student->name;
        }
        $this->clearResults();
        $this->checkApprovedResults();
        
        // Auto-load results if session is selected
        if ($this->selectedStudent && $this->selectedSession) {
            $this->loadResults();
        }
    }
    
    public function updatedSelectedSession()
    {
        $this->clearResults();
        $this->checkApprovedResults();
        
        // Auto-load results if student is selected
        if ($this->selectedStudent && $this->selectedSession) {
            $this->loadResults();
        }
    }

    private function clearResults()
    {
        $this->results = [];
        $this->subjects = [];
    }

    public function loadResults()
    {
        $this->loading = true;
        
        if ($this->selectedStudent && $this->selectedSession) {
            $this->checkApprovedResults();
            $this->loadSubjects();
        }
        
        $this->loading = false;
    }

    public function processPendingUpdates()
    {
        $session = SchoolSession::find($this->selectedSession);
        $caMax = $session->ca_max_score ?? 100;
        $examMax = $session->exam_max_score ?? 100;
        $resultService = new ResultService();
        
        foreach ($this->results as $subjectId => $result) {
            $caFilled = !empty($result['ca_score']) || ($result['ca_absent'] ?? false);
            $examFilled = !empty($result['exam_score']) || ($result['exam_absent'] ?? false);
            
            if ($caFilled && $examFilled) {
                $caScore = $result['ca_score'] ?? 0;
                $examScore = $result['exam_score'] ?? 0;
                
                if ($caScore >= 0 && $caScore <= $caMax && $examScore >= 0 && $examScore <= $examMax) {
                    $resultService->createOrUpdateResult([
                        'student_id' => $this->selectedStudent,
                        'session_id' => $this->selectedSession,
                        'subject_id' => $subjectId,
                        'ca_score' => $caScore,
                        'exam_score' => $examScore,
                        'ca_absent' => $result['ca_absent'] ?? false,
                        'exam_absent' => $result['exam_absent'] ?? false,
                    ]);
                }
            }
        }
    }





    public function loadSubjects()
    {
        $student = User::find($this->selectedStudent);
        if ($student && $student->batch && $student->batch->schoolClass) {
            $resultService = new ResultService();
            $this->subjects = $resultService->getSubjectsByClass($student->batch->school_class_id)->sortBy('display_name');
            
            // Load existing results
            $existingResults = $resultService->getStudentResults($this->selectedStudent, $this->selectedSession);
            $this->results = [];
            
            foreach ($this->subjects as $subject) {
                $existingResult = $existingResults->where('subject_id', $subject->id)->first();
                $this->results[$subject->id] = [
                    'ca_score' => $existingResult ? intval($existingResult->ca_score) : '',
                    'exam_score' => $existingResult ? intval($existingResult->exam_score) : '',
                    'ca_absent' => $existingResult ? $existingResult->ca_absent : false,
                    'exam_absent' => $existingResult ? $existingResult->exam_absent : false,
                ];
            }
        }
    }

    public function saveResults()
    {
        // Process any pending updates before final save
        $this->processPendingUpdates();
        
        if (!$this->canUploadResults) {
            $this->showToast('error', $this->uploadDisabledMessage, 'Upload Disabled');
            return;
        }
        
        if ($this->hasApprovedResults && !$this->canEditApprovedResults) {
            $this->showToast('error', 'Cannot modify approved results. Please unapprove the results first or contact an administrator.', 'Edit Restricted');
            return;
        }
        
        // Check if all fields are filled (excluding absent ones)
        foreach ($this->results as $subjectId => $result) {
            $caRequired = !($result['ca_absent'] ?? false);
            $examRequired = !($result['exam_absent'] ?? false);
            
            if (($caRequired && empty($result['ca_score'])) || ($examRequired && empty($result['exam_score']))) {
                $this->showToast('error', 'Please fill all CA and Exam scores before saving.', 'Incomplete Results');
                return;
            }
        }

        $this->validate([
            'selectedStudent' => 'required',
            'selectedSession' => 'required',
            'results.*.ca_score' => 'required|numeric|min:0|max:100',
            'results.*.exam_score' => 'required|numeric|min:0|max:100',
        ]);

        $resultService = new ResultService();
        
        foreach ($this->results as $subjectId => $result) {
            if ($result['ca_score'] + $result['exam_score'] > 100) {
                $this->showToast('error', 'Total score cannot exceed 100 for any subject.', 'Invalid Score');
                return;
            }

            $resultService->createOrUpdateResult([
                'student_id' => $this->selectedStudent,
                'session_id' => $this->selectedSession,
                'subject_id' => $subjectId,
                'ca_score' => $result['ca_score'],
                'exam_score' => $result['exam_score'],
                'ca_absent' => $result['ca_absent'],
                'exam_absent' => $result['exam_absent'],
            ]);
        }

        $this->showToast('success', 'Results saved successfully!', 'Student Results');
    }

    public function render()
    {
        return view('livewire.results.by-student-form');
    }
}