<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Models\Student;
use App\Models\Exam;
use App\Models\ExamType;
use App\Models\Subject;
use App\Models\ResultMark;
use App\Models\FinalResult;
use App\Models\ExamSubjectRule;
use Illuminate\Support\Facades\DB;

class AddDemoResults extends Command
{
    protected $signature = 'demo:add-results';
    protected $description = 'Add demo results for 4 students in Class XII, Session 2023-2024, Test Exam 2025';

    public function handle()
    {
        $this->info('Creating demo results...');

        DB::beginTransaction();
        
        try {
            // Get or create exam
            $exam = $this->getOrCreateExam();
            
            // Get exam subjects
            $examSubjects = ExamSubjectRule::where('exam_id', $exam->id)
                ->with('subject')
                ->get();
            
            if ($examSubjects->isEmpty()) {
                $this->error('No subjects found for this exam. Please configure subjects for the exam first.');
                return;
            }
            
            // Create or get 4 students
            $students = $this->createOrGetStudents();
            
            // Process each student
            foreach ($students as $index => $student) {
                $this->info("Processing student: {$student->name} (Roll: {$student->roll})");
                
                // Generate marks for each subject
                $subjectMarks = [];
                $subjectGPAs = [];
                $hasFailed = false;
                
                foreach ($examSubjects as $examSubjectRule) {
                    $subject = $examSubjectRule->subject;
                    
                    // Generate realistic marks based on student position (higher marks for better position)
                    $baseMark = 85 - ($index * 5); // First student gets ~85, 4th gets ~70
                    $markVariation = rand(-5, 5);
                    $totalMarks = max(33, min(100, $baseMark + $markVariation));
                    
                    // Split marks based on subject configuration
                    $firstPaperMCQ = $subject->has_mcq && $subject->has_first_paper ? rand(20, 25) : null;
                    $firstPaperCQ = $subject->has_cq && $subject->has_first_paper ? ($totalMarks * 0.7) : null;
                    $firstPaperPractical = $subject->has_practical && $subject->has_first_paper ? rand(15, 20) : null;
                    
                    $secondPaperMCQ = $subject->has_mcq && $subject->has_second_paper ? rand(20, 25) : null;
                    $secondPaperCQ = $subject->has_cq && $subject->has_second_paper ? ($totalMarks * 0.7) : null;
                    $secondPaperPractical = $subject->has_practical && $subject->has_second_paper ? rand(15, 20) : null;
                    
                    // Calculate total marks if not set
                    if ($totalMarks < 33) {
                        $totalMarks = 33;
                        $hasFailed = true;
                    }
                    
                    // Calculate GPA and Grade
                    $subjectGPA = ResultMark::calculateGPA($totalMarks);
                    $subjectGrade = ResultMark::getGrade($totalMarks);
                    $isFailed = ($totalMarks < 33);
                    
                    if ($isFailed) {
                        $hasFailed = true;
                    }
                    
                    // Create or update result mark
                    $resultMark = ResultMark::updateOrCreate(
                        [
                            'exam_id' => $exam->id,
                            'student_id' => $student->id,
                            'subject_id' => $subject->id,
                        ],
                        [
                            'first_paper_mcq' => $firstPaperMCQ,
                            'first_paper_cq' => $firstPaperCQ,
                            'first_paper_practical' => $firstPaperPractical,
                            'second_paper_mcq' => $secondPaperMCQ,
                            'second_paper_cq' => $secondPaperCQ,
                            'second_paper_practical' => $secondPaperPractical,
                            'total_marks' => $totalMarks,
                            'subject_gpa' => $subjectGPA,
                            'subject_grade' => $subjectGrade,
                            'is_failed' => $isFailed,
                        ]
                    );
                    
                    $subjectMarks[] = $totalMarks;
                    $subjectGPAs[] = $subjectGPA;
                }
                
                // Calculate final GPA (average of all subject GPAs, or 0 if failed)
                $finalGPA = $hasFailed ? 0.00 : round(array_sum($subjectGPAs) / count($subjectGPAs), 2);
                $totalMarksSum = array_sum($subjectMarks);
                
                // Calculate final grade
                $finalGrade = ResultMark::getGrade($totalMarksSum / count($subjectMarks));
                if ($hasFailed) {
                    $finalGrade = 'F';
                }
                
                // Create or update final result
                FinalResult::updateOrCreate(
                    [
                        'exam_id' => $exam->id,
                        'student_id' => $student->id,
                    ],
                    [
                        'total_marks' => $totalMarksSum,
                        'gpa' => $finalGPA,
                        'grade' => $finalGrade,
                        'position' => null, // Will be calculated later
                        'remarks' => $this->getRemarks($finalGPA),
                        'is_published' => true,
                    ]
                );
                
                $this->info("  ✓ Added result: GPA {$finalGPA}, Grade {$finalGrade}, Total: {$totalMarksSum}");
            }
            
            // Calculate and update positions
            $this->calculatePositions($exam->id);
            
            DB::commit();
            
            $this->info("\n✅ Demo results created successfully!");
            $this->info("Exam: {$exam->name}");
            $this->info("Session: {$exam->session}");
            $this->info("Class: {$exam->class}");
            $this->info("Students: " . count($students));
            
        } catch (\Exception $e) {
            DB::rollBack();
            $this->error('Error: ' . $e->getMessage());
            $this->error($e->getTraceAsString());
            return 1;
        }
        
        return 0;
    }
    
    private function getOrCreateExam()
    {
        $exam = Exam::where('name', 'test exam 2025')
            ->where('session', '2023-2024')
            ->where('class', '12')
            ->first();
        
        if (!$exam) {
            $this->info('Exam "test exam 2025" not found. Creating...');
            
            // Get or create exam type
            $examType = ExamType::firstOrCreate(
                ['name' => 'Test'],
                ['description' => 'Test Examination']
            );
            
            // Get first exam template (if exists)
            $examTemplate = DB::table('exam_templates')->first();
            
            if (!$examTemplate) {
                throw new \Exception('No exam template found. Please create an exam template first.');
            }
            
            $exam = Exam::create([
                'name' => 'test exam 2025',
                'exam_type_id' => $examType->id,
                'exam_template_id' => $examTemplate->id,
                'class' => '12',
                'session' => '2023-2024',
                'year' => '2025',
                'status' => 'completed',
            ]);
            
            $this->info("  ✓ Created exam: {$exam->name}");
            
            // Copy template rules to exam (if template has rules)
            $templateRules = DB::table('exam_template_subject_rules')
                ->where('exam_template_id', $examTemplate->id)
                ->get();
            
            foreach ($templateRules as $templateRule) {
                ExamSubjectRule::create([
                    'exam_id' => $exam->id,
                    'subject_id' => $templateRule->subject_id,
                    'paper_mode' => $templateRule->paper_mode ?? 'merged',
                    'config' => $templateRule->config ?? [],
                    'total_marks' => $templateRule->total_marks ?? 100,
                    'pass_marks' => $templateRule->pass_marks ?? 33,
                ]);
            }
        } else {
            $this->info("✓ Found existing exam: {$exam->name}");
        }
        
        return $exam;
    }
    
    private function createOrGetStudents()
    {
        $session = '2023-2024';
        $class = '12';
        
        $students = Student::where('session', $session)
            ->where('current_class', $class)
            ->take(4)
            ->get();
        
        if ($students->count() < 4) {
            $this->info('Creating students...');
            
            // Create students if needed
            $names = ['Abdul Rahman', 'Fatima Begum', 'Mohammad Ali', 'Ayesha Khan'];
            $rolls = ['202301', '202302', '202303', '202304'];
            
            foreach ($names as $index => $name) {
                if ($students->count() < 4) {
                    $student = Student::firstOrCreate(
                        [
                            'roll' => $rolls[$index],
                            'session' => $session,
                        ],
                        [
                            'name' => $name,
                            'class' => $class,
                            'current_class' => $class,
                            'session' => $session,
                            'year' => '2024',
                            'status' => 'active',
                            'group' => 'Science',
                        ]
                    );
                    
                    if ($student->wasRecentlyCreated) {
                        $this->info("  ✓ Created student: {$student->name} (Roll: {$student->roll})");
                    }
                    
                    $students->push($student);
                }
            }
        }
        
        // Ensure we have exactly 4 students
        $students = $students->take(4);
        
        return $students;
    }
    
    private function calculatePositions($examId)
    {
        // Get all final results for this exam, ordered by GPA desc
        $results = FinalResult::where('exam_id', $examId)
            ->orderByDesc('gpa')
            ->orderByDesc('total_marks')
            ->get();
        
        $position = 1;
        foreach ($results as $result) {
            $result->position = $position;
            $result->save();
            $position++;
        }
        
        $this->info("✓ Calculated positions for all students");
    }
    
    private function getRemarks($gpa)
    {
        if ($gpa >= 5.00) {
            return 'Excellent performance. Outstanding achievement.';
        } elseif ($gpa >= 4.00) {
            return 'Very good performance. Keep up the good work.';
        } elseif ($gpa >= 3.50) {
            return 'Good performance. Continue to improve.';
        } elseif ($gpa >= 3.00) {
            return 'Satisfactory performance. More effort needed.';
        } else {
            return 'Need to improve performance. Study harder.';
        }
    }
}



