<?php

namespace App\Http\Controllers;

use App\Models\AcademicVersion;
use App\Models\Subject;
use App\Models\GroupSubject;
use App\Models\SubjectBucket;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;

class SubjectConfigurationController extends Controller
{
    public function index(Request $request)
    {
        // 1. Auto-Seed if System is Empty (Self-Healing)
        if (AcademicVersion::withTrashed()->count() === 0) {
            AcademicVersion::create([
                'name' => 'AC_v1',
                'effective_from' => now(),
                'is_current' => true
            ]);
        }

        // Fetch ALL versions including trashed for the Manager UI
        $versions = AcademicVersion::withTrashed()->latest()->get();
        
        // Determine Current Version to View
        $currentVersion = null;
        if ($request->has('version_id')) {
            $currentVersion = $versions->find($request->version_id);
        }
        
        // Fallback: If requested ID invalid or not provided, get current Active or Latest
        if (!$currentVersion) {
            $currentVersion = $versions->where('is_current', true)->first() ?? $versions->first();
        }

        // Final Fallback: If ABSOLUTELY NO versions exist (deleted or otherwise), Create One
        if (!$currentVersion) {
            $newVersion = AcademicVersion::create([
                'name' => 'AC_v1',
                'effective_from' => now(),
                'is_current' => true
            ]);
            return redirect()->route('subjects.config.index', ['version_id' => $newVersion->id]);
        }
        
        $groups = ['science', 'commerce', 'arts'];
        $subjects = \App\Models\Subject::orderBy('code')->get(); // Fetch all for Matrix

        // Pre-fetch configuration for efficient matrix rendering
        $matrix = [];
        // Config defaults
        $config = [
            'science' => ['electives' => collect()],
            'commerce' => ['electives' => collect()],
            'arts' => ['electives' => collect()],
        ];

        // Only load if valid currentVersion exists
        if ($currentVersion) {
            $assignments = GroupSubject::where('academic_version_id', $currentVersion->id)->get();
            foreach ($assignments as $a) {
                // Key format: subject_id-group_code
                $matrix[$a->subject_id][$a->group_code] = true;
                if ($a->category === 'core') {
                    $matrix[$a->subject_id]['core'] = true;
                }
            }
            
            // Fetch Electives
            $electives = \App\Models\SubjectElective::with('subject')
                ->where('academic_version_id', $currentVersion->id)
                ->get()
                ->groupBy('group_code');

            $config = [
                'science' => ['electives' => $electives->get('science') ?? collect()],
                'commerce' => ['electives' => $electives->get('commerce') ?? collect()],
                'arts' => ['electives' => $electives->get('arts') ?? collect()],
            ];
        }

        return view('admin.subjects.configuration', compact('versions', 'currentVersion', 'subjects', 'matrix', 'config', 'groups'));
    }

    public function activateVersion($id)
    {
        $version = AcademicVersion::withTrashed()->findOrFail($id);
        
        DB::transaction(function() use ($version) {
            AcademicVersion::query()->update(['is_current' => false]);
            $version->update(['is_current' => true]);
        });
        
        return back()->with('success', "Version '{$version->name}' is now Active.");
    }

    public function deleteVersion($id)
    {
        $version = AcademicVersion::findOrFail($id);
        if ($version->is_current) {
            return back()->with('error', 'Cannot delete the Active version. Activate another one first.');
        }
        
        $version->delete();
        return back()->with('success', "Version '{$version->name}' deleted.");
    }

    public function restoreVersion($id)
    {
        $version = AcademicVersion::withTrashed()->findOrFail($id);
        $version->restore();
        return back()->with('success', "Version '{$version->name}' restored.");
    }


    public function toggleFixed(Request $request)
    {
        $request->validate([
            'version_id' => 'required',
            'subject_id' => 'required',
            'group_code' => 'required',
            'active' => 'required|boolean'
        ]);

        $targetVersion = $this->ensureMutableVersion($request->version_id);
        
        $exists = GroupSubject::where('academic_version_id', $targetVersion->id)
            ->where('subject_id', $request->subject_id)
            ->where('group_code', $request->group_code)
            ->exists();

        // If request is ACTIVE (Checked)
        if ($request->active) {
            if (!$exists) {
                GroupSubject::create([
                    'academic_version_id' => $targetVersion->id,
                    'subject_id' => $request->subject_id,
                    'group_code' => $request->group_code,
                    'category' => 'group_main', // Default category
                    'is_mandatory' => true
                ]);
            }
        } 
        // If request is INACTIVE (Unchecked)
        else {
            if ($exists) {
                GroupSubject::where('academic_version_id', $targetVersion->id)
                    ->where('subject_id', $request->subject_id)
                    ->where('group_code', $request->group_code)
                    ->delete();
            }
        }

        return response()->json([
            'success' => true, 
            'message' => 'Matrix updated.',
            'new_version_id' => $targetVersion->id,
            'version_changed' => $targetVersion->id != $request->version_id
        ]);
    }

    public function storeBucket(Request $request)
    {
        $request->validate([
            'version_id' => 'required',
            'group_code' => 'required',
            'subject_ids' => 'required|array'
        ]);

        $targetVersion = $this->ensureMutableVersion($request->version_id);

        // 1. Clear existing electives for this group/version
        \App\Models\SubjectElective::where('academic_version_id', $targetVersion->id)
            ->where('group_code', $request->group_code)
            ->delete();

        // 2. Insert new electives
        $data = [];
        foreach ($request->subject_ids as $subId) {
            $data[] = [
                'academic_version_id' => $targetVersion->id,
                'group_code' => $request->group_code,
                'subject_id' => $subId,
                'created_at' => now(),
                'updated_at' => now(),
            ];
        }
        
        if (!empty($data)) {
            \App\Models\SubjectElective::insert($data);
        }

        $msg = '4th Subject rule updated.';
        if ($targetVersion->id != $request->version_id) {
            $msg .= ' (New Version Created: ' . $targetVersion->name . ')';
        }

        return back()->with('success', $msg);
    }

    public function deleteBucket($group_code)
    {
        $currentVersion = \App\Models\AcademicVersion::where('is_current', true)->first(); 
        if ($currentVersion) {
            $targetVersion = $this->ensureMutableVersion($currentVersion->id);
            
            \App\Models\SubjectElective::where('academic_version_id', $targetVersion->id)
                ->where('group_code', $group_code)
                ->delete();
                
            $msg = '4th Subject rule removed.';
            if ($targetVersion->id != $currentVersion->id) {
                $msg .= ' (New Version Created: ' . $targetVersion->name . ')';
            }
            return back()->with('success', $msg);
        }

        return back()->with('error', 'No active version found.');
    }
    /**
     * Helper: Ensure we are editing a mutable version.
     * If current version has students, create a new clone and return its ID.
     */
    private function ensureMutableVersion($versionId)
    {
        $version = \App\Models\AcademicVersion::findOrFail($versionId);
        
        // Check if students exist in this version
        $hasStudents = \App\Models\Student::where('academic_version_id', $versionId)->exists();
        
        if (!$hasStudents) {
            return $version;
        }

        // --- Create New Version (Clone) ---
        // New Naming Logic: AC_v1, AC_v2, AC_v3...
        // Find highest version number
        $latest = \App\Models\AcademicVersion::withTrashed()
            ->where('name', 'LIKE', 'AC_v%')
            ->orderByRaw('LENGTH(name) DESC') // distinct length sort first
            ->orderBy('name', 'DESC')
            ->first();
            
        $nextNum = 1;
        if ($latest) {
            // Extract number from AC_vX
            if (preg_match('/AC_v(\d+)/', $latest->name, $matches)) {
                $nextNum = (int)$matches[1] + 1;
            }
        }
        
        $newName = 'AC_v' . $nextNum;
        
        DB::beginTransaction();
        try {
            // 1. Create New Version
            $newVersion = \App\Models\AcademicVersion::create([
                'name' => $newName,
                'effective_from' => now(),
                'is_current' => true
            ]);

            // 2. Archive Old Version
            $version->update(['is_current' => false]);
            
            // 3. Clone Group Subjects (Mandatory)
            $groupSubjects = \App\Models\GroupSubject::where('academic_version_id', $versionId)->get();
            foreach ($groupSubjects as $gs) {
                $check = \App\Models\GroupSubject::where('academic_version_id', $newVersion->id)
                    ->where('subject_id', $gs->subject_id)
                    ->where('group_code', $gs->group_code)
                    ->exists();
                    
                if(!$check) {
                    $gs->replicate()->fill([
                        'academic_version_id' => $newVersion->id
                    ])->save();
                }
            }

            // 4. Clone Electives (4th Subject Rules)
            $electives = \App\Models\SubjectElective::where('academic_version_id', $versionId)->get();
            foreach ($electives as $elec) {
                $elec->replicate()->fill([
                    'academic_version_id' => $newVersion->id
                ])->save();
            }

            DB::commit();
            return $newVersion;

        } catch (\Exception $e) {
            DB::rollBack();
            throw $e;
        }
    }
}
