<?php

namespace App\Livewire\Results;

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

class ByClassForm extends Component
{
    use HasNotifications;

    public $selectedClass = '';
    public $selectedBatch = '';
    public $selectedSession = '';
    public $classes = [];
    public $batches = [];
    public $sessions = [];
    public $students = [];
    public $subjects = [];
    public $results = [];
    public $loading = false;
    public $canUploadResults = true;
    public $uploadDisabledMessage = '';
    public $excludedStudentsCount = 0;

    public function mount()
    {
        $this->checkUploadPermission();
        
        if ($this->canUploadResults) {
            $resultService = new ResultService();
            $this->classes = $resultService->getClassesForUser(Auth::user());
            $this->sessions = SchoolSession::orderBy('is_active', 'desc')->orderBy('created_at', 'desc')->get();
            
            // Auto-select the currently active session
            $activeSession = $this->sessions->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.';
        }
    }

    public function updatedSelectedClass()
    {
        $this->selectedBatch = '';
        $this->batches = [];
        $this->students = [];
        $this->subjects = [];
        $this->results = [];
        
        if ($this->selectedClass) {
            $this->loadBatches();
        }
    }
    
    public function updatedSelectedBatch()
    {
        $this->students = [];
        $this->subjects = [];
        $this->results = [];
    }
    
    public function updatedSelectedSession()
    {
        $this->students = [];
        $this->subjects = [];
        $this->results = [];
    }
    
    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 loadResults()
    {
        $this->loading = true;
        
        // Clear existing data first
        $this->results = [];
        $this->students = [];
        $this->subjects = [];
        
        if ($this->selectedClass && $this->selectedBatch && $this->selectedSession) {
            $this->loadStudentsAndSubjects();
        }
        
        $this->loading = false;
    }

    public function loadStudentsAndSubjects()
    {
        $resultService = new ResultService();
        $allStudents = $resultService->getStudentsByBatch($this->selectedBatch)->sortBy('firstname');
        
        // Exclude students with approved results for the selected session
        $approvedStudentIds = \App\Models\ResultApproval::where('session_id', $this->selectedSession)
            ->pluck('student_id')
            ->toArray();
        
        $this->students = $allStudents->reject(function ($student) use ($approvedStudentIds) {
            return in_array($student->id, $approvedStudentIds);
        });
        
        $this->excludedStudentsCount = $allStudents->count() - $this->students->count();
        
        $this->subjects = $resultService->getSubjectsByClass($this->selectedClass)->sortBy('display_name');
        
        // Initialize results array
        $this->results = [];
        foreach ($this->students as $student) {
            $existingResults = $resultService->getStudentResults($student->id, $this->selectedSession);
            
            // Ensure student array is initialized
            if (!isset($this->results[$student->id])) {
                $this->results[$student->id] = [];
            }
            
            foreach ($this->subjects as $subject) {
                $existingResult = $existingResults->where('subject_id', $subject->id)->first();
                $this->results[$student->id][$subject->id] = [
                    'ca_score' => $existingResult ? intval($existingResult->ca_score) : '',
                    'exam_score' => $existingResult ? intval($existingResult->exam_score) : '',
                    'ca_absent' => $existingResult ? (bool)$existingResult->ca_absent : false,
                    'exam_absent' => $existingResult ? (bool)$existingResult->exam_absent : 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 $studentId => $studentResults) {
            foreach ($studentResults 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' => $studentId,
                            '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 saveResults()
    {
        // Process any pending updates before final save
        $this->processPendingUpdates();
        
        if (!$this->canUploadResults) {
            $this->showToast('error', $this->uploadDisabledMessage, 'Upload Disabled');
            return;
        }
        
        // Check if all fields are filled (excluding absent ones)
        foreach ($this->results as $studentId => $studentResults) {
            foreach ($studentResults 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([
            'selectedClass' => 'required',
            'selectedBatch' => '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 $studentId => $studentResults) {
            foreach ($studentResults 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' => $studentId,
                    '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!', 'Class Results');
    }

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