<?php

namespace App\Services;

use App\Models\Student;
use App\Models\Subject;
use App\Models\GroupSubject;
use App\Models\AuditLog;
use App\Models\AcademicVersion;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use App\Services\SubjectRuleService;

class StudentAdmissionService
{
    protected $ruleService;

    public function __construct(SubjectRuleService $ruleService)
    {
        $this->ruleService = $ruleService;
    }

    /**
     * Create a new student with version-safe subject assignment.
     */
    public function createStudent(array $data): Student
    {
        return DB::transaction(function () use ($data) {
            // 1. Handle Batch Logic (Auto-create if not exists)
            // 1. Handle Batch Logic (Fix: Derive from SSC Batch if not explicitly provided)
            $sscBatch = $data['ssc_batch'];
            
            // Calculate HSC Year (SSC + 2)
            $hscYear = $data['hsc_batch'] ?? ($sscBatch + 2);
            $batchName = "HSC {$hscYear}";
            
            // Ensure Batch model is imported
            $batch = \App\Models\Batch::firstOrCreate(
                ['name' => $batchName],
                ['is_active' => true]
            );
            
            $data['batch_id'] = $batch->id;
            // Also ensure the calculated hsc_batch is set for student creation
            $data['hsc_batch'] = $hscYear;

            // 2. Generate System IDs (Roll, Reg, etc if needed)
            
            // 2. Generate System IDs
            
            // $sscBatch already defined above
            $groupCode = $data['group_code']; // 1=Arts, 2=Commerce, 3=Science (Mapped in Controller)
            $class = $data['class'];
            $versionId = $data['academic_version_id'];
            
            // Map numeric group to code
            $groupMap = [3 => 'science', 2 => 'commerce', 1 => 'arts'];
            $groupStr = $groupMap[$groupCode] ?? 'arts';

            // 1. Generate Roll (Same logic)
            // ... (Roll logic omitted for brevity as it was working, can keep it)
            // Re-implementing simplified roll for completeness
            $maxSerial = Student::where('ssc_batch', $sscBatch)
                ->where('group_code', $groupCode)
                ->withTrashed()
                ->max('serial');
            $serial = $maxSerial ? $maxSerial + 1 : 1;
            $sscLastTwo = substr((string)$sscBatch, -2);
            $roll = $sscLastTwo . $groupCode . str_pad($serial, 2, '0', STR_PAD_LEFT); 

            $student = Student::create([
                'ssc_reg_no' => $data['ssc_reg_no'],
                'name' => $data['name'],
                'ssc_batch' => $sscBatch,
                'hsc_batch' => $data['hsc_batch'], // Use the calculated one
                'group_code' => $groupCode,
                'class' => $class,
                'serial' => $serial,
                'class_roll' => $roll,
                'academic_version_id' => $versionId,
                'batch_id' => $data['batch_id'] ?? null,
                'phone' => $data['phone'] ?? null,
                'email' => $data['email'] ?? null,
                'address' => $data['address'] ?? null,
                'status' => 'active',
                'photo' => $data['photo_path'] ?? null
            ]);

            // 2. Validate Selections
            // Prepare selections array: bucket_id => [subject_id]
            $selections = $data['bucket_selections'] ?? [];
            
            // Validate via Rule Service
            $this->ruleService->validateSelection($versionId, $groupStr, $selections);

            // 3. Assign Fixed Subjects
            $fixedSubjects = GroupSubject::where('academic_version_id', $versionId)
                ->where(function($q) use ($groupStr) {
                    $q->where('group_code', $groupStr)
                      ->orWhere('category', 'core');
                })
                ->where('is_mandatory', true)
                ->get();

            $syncData = [];
            foreach ($fixedSubjects as $gs) {
                // Determine 4th? Fixed are usually not 4th.
                $syncData[$gs->subject_id] = [
                    'academic_version_id' => $versionId,
                    'is_optional' => false // Main/Core
                ];
            }

            // 4. Assign Bucket Selections (Optional/Fourth)
            foreach ($selections as $bucketId => $subIds) {
                if (!is_array($subIds)) $subIds = [$subIds];
                
                // New Logic: Check if it's our virtual 'elective_rule'
                $isElectiveRule = ($bucketId === 'elective_rule');
                
                foreach ($subIds as $subId) {
                    if (!$subId) continue;
                    
                    // Allow overriding if subject already in list
                    $syncData[$subId] = [
                        'academic_version_id' => $versionId,
                        'is_optional' => $isElectiveRule // true for 4th subject
                    ];
                }
            }

            $student->subjects()->sync($syncData);

            // 5. Audit
            AuditLog::create([
                'action' => 'create',
                'module' => 'student',
                'target_id' => $student->id,
                'user_id' => Auth::id() ?? 1,
                'new_values' => $student->toArray(),
                'ip_address' => request()->ip()
            ]);

            return $student;
        });
    }

    // Restore/Archive methods remain...
    public function archiveStudent(Student $student) { $student->delete(); }
    public function restoreStudent(Student $student) { $student->restore(); }
}
