<?php

namespace App\Models;

use App\Models\BaseModel;
use Illuminate\Support\Facades\DB;

class MissingScoreOverride extends BaseModel
{
    protected $table = 'missing_score_overrides';

    // ✅ CI: useTimestamps = true (created_at/updated_at)
    public $timestamps = true;

    protected $fillable = [
        'student_id',
        'class_section_id',
        'semester',
        'school_year',
        'item_type',
        'item_index',
        'is_allowed',
        'updated_by',
        'created_at',
        'updated_at',
    ];

    protected $casts = [
        'student_id'       => 'integer',
        'class_section_id' => 'integer',
        'item_index'       => 'integer',
        'is_allowed'       => 'boolean',
        'updated_by'       => 'integer',
    ];

    /**
     * Equivalent of CI getOverridesMap()
     * Returns: [student_id => [item_index => true]]
     */
    public static function getOverridesMap(int $classSectionId, string $semester, string $schoolYear, string $itemType): array
    {
        if ($classSectionId <= 0 || $semester === '' || $schoolYear === '' || $itemType === '') {
            return [];
        }

        $rows = static::query()
            ->select(['student_id', 'item_index'])
            ->where('class_section_id', $classSectionId)
            ->where('semester', $semester)
            ->where('school_year', $schoolYear)
            ->where('item_type', $itemType)
            ->where('is_allowed', 1)
            ->get();

        $map = [];
        foreach ($rows as $row) {
            $sid = (int) $row->student_id;
            $idx = $row->item_index === null ? 0 : (int) $row->item_index;
            if ($sid > 0) {
                $map[$sid][$idx] = true;
            }
        }

        return $map;
    }

    /**
     * Equivalent of CI replaceOverrides()
     * Deletes matching overrides then inserts checked items.
     */
    public static function replaceOverrides(
        int $classSectionId,
        string $semester,
        string $schoolYear,
        string $itemType,
        array $studentIds,
        ?array $itemIndexes,
        array $checkedItems,
        ?int $updatedBy,
        bool $nullIndex = false
    ): void {
        if ($classSectionId <= 0 || $semester === '' || $schoolYear === '' || $itemType === '') {
            return;
        }

        DB::transaction(function () use (
            $classSectionId,
            $semester,
            $schoolYear,
            $itemType,
            $studentIds,
            $itemIndexes,
            $checkedItems,
            $updatedBy,
            $nullIndex
        ) {
            // 1) Delete existing rows in the target scope
            $q = static::query()
                ->where('class_section_id', $classSectionId)
                ->where('semester', $semester)
                ->where('school_year', $schoolYear)
                ->where('item_type', $itemType);

            if (!empty($studentIds)) {
                $q->whereIn('student_id', array_map('intval', $studentIds));
            }

            if ($itemIndexes !== null) {
                if (!empty($itemIndexes)) {
                    $q->whereIn('item_index', array_map('intval', $itemIndexes));
                } else {
                    // CI behavior: if itemIndexes is provided but empty, do nothing.
                    return;
                }
            } elseif ($nullIndex) {
                $q->whereNull('item_index');
            }

            $q->delete();

            // 2) Insert checked rows
            if (empty($checkedItems)) {
                return;
            }

            $now = now();
            $rows = [];

            foreach ($checkedItems as $item) {
                $sid = (int) ($item['student_id'] ?? 0);
                if ($sid <= 0) continue;

                $rows[] = [
                    'student_id'       => $sid,
                    'class_section_id' => $classSectionId,
                    'semester'         => $semester,
                    'school_year'      => $schoolYear,
                    'item_type'        => $itemType,
                    'item_index'       => array_key_exists('item_index', $item) ? $item['item_index'] : null,
                    'is_allowed'       => 1,
                    'updated_by'       => $updatedBy,
                    'created_at'       => $now,
                    'updated_at'       => $now,
                ];
            }

            if (!empty($rows)) {
                DB::table((new static)->getTable())->insert($rows);
            }
        });
    }
}