<?php

namespace App\Services;

use App\Models\Subject;
use App\Models\GroupSubject;
use App\Models\SubjectBucket;
use App\Models\SubjectPolicy;

class SubjectRuleService
{
    /**
     * Get all eligible subjects for a specific version and group, structured for frontend.
     */
    public function getEligibleSubjects($versionId, $groupCode)
    {
        // 1. Fetch Electives (Optional Pools)
        $electives = \App\Models\SubjectElective::with('subject')
            ->where('academic_version_id', $versionId)
            ->where('group_code', $groupCode)
            ->get();

        $electiveSubjectIds = $electives->pluck('subject_id')->toArray();

        // 2. Fetch All Assigned Subjects for this Group
        $allAssigned = GroupSubject::with('subject')
            ->where('academic_version_id', $versionId)
            ->where('group_code', $groupCode)
            ->get();

        // 3. Filter Fixed: Assigned AND NOT Elective
        // Note: With the new logic, "Fixed" implies Mandatory.
        $fixedSubjects = $allAssigned->filter(function($gs) use ($electiveSubjectIds) {
            return !in_array($gs->subject_id, $electiveSubjectIds);
        })->map(function ($gs) {
            return [
                'id' => $gs->subject->id,
                'code' => $gs->subject->code,
                'name' => $gs->subject->name,
                'category' => $gs->category,
            ];
        })->values();

        // 4. Construct Virtual Bucket for Electives (if any exist)
        $formattedBuckets = collect();
        if ($electives->isNotEmpty()) {
            $formattedBuckets->push([
                'id' => 'elective_rule', // Virtual ID for the single rule
                'name' => '4th Subject',
                'min_select' => 0,
                'max_select' => 1,
                'ui_type' => 'radio',
                'options' => $electives->map(function ($elec) {
                    return [
                        'id' => $elec->subject->id,
                        'name' => $elec->subject->name,
                        'code' => $elec->subject->code,
                    ];
                }),
            ]);
        }

        return [
            'fixed' => $fixedSubjects,
            'buckets' => $formattedBuckets
        ];
    }

    /**
     * Validate the student's selection against buckets and policies.
     */
    public function validateSelection($versionId, $groupCode, $selections)
    {
        // Selections: ['elective_rule' => [subject_id]]
        
        // 1. Fetch Electives Rule
        $electives = \App\Models\SubjectElective::where('academic_version_id', $versionId)
            ->where('group_code', $groupCode)
            ->get();

        if ($electives->isEmpty()) {
            // No electives enabled, so no selections allowed for elective rule.
            // But frontend typically won't send if not rendered.
            return true;
        }

        // Check if virtual rule key exists in selections
        $selectedIds = $selections['elective_rule'] ?? [];
        if (!is_array($selectedIds)) $selectedIds = [$selectedIds];
        
        // Allowed: 0 or 1
        $count = count(array_filter($selectedIds));
        
        if ($count > 1) {
            throw new \Exception("You can only select 1 subject as 4th Subject.");
        }
        
        // Validate Subject ID
        foreach ($selectedIds as $subId) {
            if (!$subId) continue;
            // Must be one of the electives
            if (!$electives->where('subject_id', $subId)->count()) {
                throw new \Exception("Invalid subject selection.");
            }
        }

        // Cross-Check: Ensure not selecting a Mandatory subject (Shouldn't happen if UI filters correct, but strictly...)
        // Actually, if it's elective, it's NOT mandatory via getEligibleSubjects.
        // But let's check duplicates?
        // Logic handled by only allowing 1 selection from the pool.

        return true;
    }
}
