<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        foreach (['homework', 'quiz', 'project', 'participation', 'midterm_exam', 'final_exam'] as $table) {
            if (!Schema::hasTable($table)) {
                continue;
            }

            Schema::table($table, function (Blueprint $tableBlueprint) use ($table) {
                if (!Schema::hasColumn($table, 'max_points')) {
                    $tableBlueprint->decimal('max_points', 8, 2)->default(100)->after('score');
                }
                if (!Schema::hasColumn($table, 'status')) {
                    $tableBlueprint->string('status', 30)->nullable()->after('max_points');
                }
                if (!Schema::hasColumn($table, 'excused_reason')) {
                    $tableBlueprint->text('excused_reason')->nullable()->after('status');
                }
                if (!Schema::hasColumn($table, 'locked_at')) {
                    $tableBlueprint->timestamp('locked_at')->nullable()->after('excused_reason');
                }
                if (!Schema::hasColumn($table, 'locked_by')) {
                    $tableBlueprint->unsignedBigInteger('locked_by')->nullable()->after('locked_at');
                }
            });

            DB::table($table)
                ->whereNull('status')
                ->update([
                    'status' => DB::raw("CASE WHEN score IS NULL THEN 'pending' ELSE 'scored' END"),
                ]);
        }

        if (Schema::hasTable('semester_scores')) {
            Schema::table('semester_scores', function (Blueprint $table) {
                if (!Schema::hasColumn('semester_scores', 'calculation_mode')) {
                    $table->string('calculation_mode', 30)->default('legacy')->after('semester_score');
                }
                if (!Schema::hasColumn('semester_scores', 'calculation_policy_version')) {
                    $table->string('calculation_policy_version', 50)->default('legacy_v1')->after('calculation_mode');
                }
                if (!Schema::hasColumn('semester_scores', 'snapshot_id')) {
                    $table->unsignedBigInteger('snapshot_id')->nullable()->after('calculation_policy_version');
                }
            });

            DB::table('semester_scores')->whereNull('calculation_mode')->update(['calculation_mode' => 'legacy']);
            DB::table('semester_scores')->whereNull('calculation_policy_version')->update(['calculation_policy_version' => 'legacy_v1']);
        }

        if (!Schema::hasTable('semester_score_snapshots')) {
            Schema::create('semester_score_snapshots', function (Blueprint $table) {
                $table->id();
                $table->unsignedBigInteger('student_id');
                $table->unsignedBigInteger('school_id')->nullable();
                $table->unsignedBigInteger('class_section_id');
                $table->string('semester', 50);
                $table->string('school_year', 50);
                $table->unsignedBigInteger('grading_profile_id')->nullable();
                $table->string('grading_profile_version', 50)->nullable();
                $table->string('calculation_mode', 30)->default('strong');
                $table->string('calculation_policy_version', 50)->default('strong_v1');
                $table->json('input_json')->nullable();
                $table->json('calculation_json')->nullable();
                $table->decimal('semester_score', 8, 2)->nullable();
                $table->unsignedBigInteger('calculated_by')->nullable();
                $table->timestamp('calculated_at')->nullable();
                $table->timestamps();

                $table->index(['student_id', 'class_section_id', 'semester', 'school_year'], 'semester_snapshot_student_term_idx');
                $table->index(['calculation_mode', 'calculation_policy_version'], 'semester_snapshot_policy_idx');
            });
        }
    }

    public function down(): void
    {
        Schema::dropIfExists('semester_score_snapshots');

        if (Schema::hasTable('semester_scores')) {
            Schema::table('semester_scores', function (Blueprint $table) {
                foreach (['snapshot_id', 'calculation_policy_version', 'calculation_mode'] as $column) {
                    if (Schema::hasColumn('semester_scores', $column)) {
                        $table->dropColumn($column);
                    }
                }
            });
        }

        foreach (['homework', 'quiz', 'project', 'participation', 'midterm_exam', 'final_exam'] as $tableName) {
            if (!Schema::hasTable($tableName)) {
                continue;
            }
            Schema::table($tableName, function (Blueprint $table) use ($tableName) {
                foreach (['locked_by', 'locked_at', 'excused_reason', 'status', 'max_points'] as $column) {
                    if (Schema::hasColumn($tableName, $column)) {
                        $table->dropColumn($column);
                    }
                }
            });
        }
    }
};
