<?php

use App\Http\Controllers\ActivityLogController;
use App\Http\Controllers\Auth\LoginController;
use App\Http\Controllers\Auth\PasswordResetController;
use App\Http\Controllers\BranchController;
use App\Http\Controllers\BranchSwitchController;
use App\Http\Controllers\CommunicationController;
use App\Http\Controllers\AcademicSessionController;
use App\Http\Controllers\AccountController;
use App\Http\Controllers\AccountingReportController;
use App\Http\Controllers\AdmissionController;
use App\Http\Controllers\ClassSubjectController;
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\ExamController;
use App\Http\Controllers\ExamPaperController;
use App\Http\Controllers\FamilyController;
use App\Http\Controllers\GradeScaleController;
use App\Http\Controllers\MarksController;
use App\Http\Controllers\ResultController;
use App\Http\Controllers\FeeChallanController;
use App\Http\Controllers\FeeConcessionController;
use App\Http\Controllers\FeePaymentController;
use App\Http\Controllers\FeeStructureController;
use App\Http\Controllers\FeeTypeController;
use App\Http\Controllers\InquiryController;
use App\Http\Controllers\JournalEntryController;
use App\Http\Controllers\LearningMaterialController;
use App\Http\Controllers\NoticeController;
use App\Http\Controllers\ParentPortal\HomeworkController as ParentHomeworkController;
use App\Http\Controllers\SubmissionController;
use App\Http\Controllers\ParentPortal\AttendanceController as ParentAttendanceController;
use App\Http\Controllers\ParentPortal\DashboardController as ParentDashboardController;
use App\Http\Controllers\ParentPortal\FeeController as ParentFeeController;
use App\Http\Controllers\ParentPortal\NoticeController as ParentNoticeController;
use App\Http\Controllers\ParentPortal\ProfileController as ParentProfileController;
use App\Http\Controllers\ParentPortal\ResultController as ParentResultController;
use App\Http\Controllers\StudentPortal\AttendanceController as StudentAttendancePortalController;
use App\Http\Controllers\StudentPortal\DashboardController as StudentDashboardController;
use App\Http\Controllers\StudentPortal\FeeController as StudentFeePortalController;
use App\Http\Controllers\StudentPortal\HomeworkController as StudentHomeworkController;
use App\Http\Controllers\StudentPortal\NoticeController as StudentNoticeController;
use App\Http\Controllers\StudentPortal\ProfileController as StudentProfileController;
use App\Http\Controllers\StudentPortal\ResultController as StudentResultPortalController;
use App\Http\Controllers\SiblingDiscountController;
use App\Http\Controllers\SchoolClassController;
use App\Http\Controllers\SectionController;
use App\Http\Controllers\StudentAttendanceController;
use App\Http\Controllers\SubjectController;
use App\Http\Controllers\TeacherAttendanceController;
use App\Http\Controllers\ProfileController;
use App\Http\Controllers\ReportController;
use App\Http\Controllers\RoleController;
use App\Http\Controllers\StudentController;
use App\Http\Controllers\StudentDocumentController;
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Guest (unauthenticated) routes
|--------------------------------------------------------------------------
*/
Route::middleware('guest')->group(function () {
    Route::get('login', [LoginController::class, 'show'])->name('login');
    Route::post('login', [LoginController::class, 'login']);

    Route::get('forgot-password', [PasswordResetController::class, 'requestForm'])->name('password.request');
    Route::post('forgot-password', [PasswordResetController::class, 'sendLink'])->name('password.email');
    Route::get('reset-password/{token}', [PasswordResetController::class, 'resetForm'])->name('password.reset');
    Route::post('reset-password', [PasswordResetController::class, 'reset'])->name('password.update');
});

/*
|--------------------------------------------------------------------------
| Authenticated routes
|--------------------------------------------------------------------------
*/
Route::middleware('auth')->group(function () {
    Route::post('logout', [LoginController::class, 'logout'])->name('logout');

    Route::get('/', fn () => redirect()->route('dashboard'));
    Route::get('dashboard', [DashboardController::class, 'index'])->name('dashboard');

    // Active-branch switcher (Super Admin only — enforced in the controller).
    Route::post('branch/switch', BranchSwitchController::class)->name('branch.switch');

    // Global top-bar search (students + families).
    Route::get('search', \App\Http\Controllers\GlobalSearchController::class)->name('search');

    // ITA AI assistant (database-driven, no external API).
    Route::post('ai-assistant', [\App\Http\Controllers\AiAssistantController::class, 'ask'])->name('ai.ask');

    // Yearly Planner (per class/section/subject teaching plans with image + notes).
    Route::resource('yearly-plans', \App\Http\Controllers\YearlyPlanController::class);

    // Database backups (Super Admin only).
    Route::get('backups', [\App\Http\Controllers\BackupController::class, 'index'])->name('backups.index');
    Route::post('backups', [\App\Http\Controllers\BackupController::class, 'create'])->name('backups.create');
    Route::get('backups/{file}/download', [\App\Http\Controllers\BackupController::class, 'download'])->name('backups.download');
    Route::delete('backups/{file}', [\App\Http\Controllers\BackupController::class, 'destroy'])->name('backups.destroy');
    Route::post('backups/restore', [\App\Http\Controllers\BackupController::class, 'restore'])->name('backups.restore');
    Route::post('backups/schedule', [\App\Http\Controllers\BackupController::class, 'schedule'])->name('backups.schedule');

    // Payment methods / accounts (Cash, Bank, JazzCash 0333-…, etc.)
    Route::post('payment-methods/{paymentMethod}/toggle', [\App\Http\Controllers\PaymentMethodController::class, 'toggle'])->name('payment-methods.toggle');
    Route::resource('payment-methods', \App\Http\Controllers\PaymentMethodController::class)->except('show');

    // Profile
    Route::get('profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::patch('profile/password', [ProfileController::class, 'updatePassword'])->name('profile.password');

    // Phase 2 — Families & Students
    Route::post('families/quick', [FamilyController::class, 'quickStore'])->name('families.quick-store');
    Route::get('families/father-names', [FamilyController::class, 'fatherNames'])->name('families.father-names');
    Route::post('families/father-names', [FamilyController::class, 'saveFatherNames'])->name('families.father-names.save');
    Route::resource('families', FamilyController::class);
    Route::post('families/{family}/create-login', [FamilyController::class, 'createLogin'])->name('families.create-login');

    // Notice board (admin)
    Route::resource('notices', NoticeController::class)->except('show');

    Route::get('students-import', [\App\Http\Controllers\StudentImportController::class, 'form'])->name('students.import');
    Route::get('students-import/template', [\App\Http\Controllers\StudentImportController::class, 'template'])->name('students.import.template');
    Route::post('students-import', [\App\Http\Controllers\StudentImportController::class, 'import'])->name('students.import.run');
    // Bulk promotion (must be declared before the {student} resource routes).
    Route::get('students-promote', [StudentController::class, 'promoteForm'])->name('students.promote-form');
    Route::post('students-promote', [StudentController::class, 'promoteBulk'])->name('students.promote-bulk');
    Route::resource('students', StudentController::class);
    Route::post('students/{student}/status', [StudentController::class, 'changeStatus'])->name('students.status');
    Route::post('students/{student}/transfer', [StudentController::class, 'transfer'])->name('students.transfer');
    Route::post('students/{student}/promote', [StudentController::class, 'promote'])->name('students.promote');
    Route::post('students/{student}/create-login', [StudentController::class, 'createLogin'])->name('students.create-login');
    Route::get('students/{student}/id-card', [StudentController::class, 'idCard'])->name('students.id-card');
    Route::put('students/{student}/fee-heads', [StudentController::class, 'updateFeeHeads'])->name('students.fee-heads.update');
    Route::post('students/{student}/documents', [StudentDocumentController::class, 'store'])->name('students.documents.store');
    Route::delete('students/{student}/documents/{document}', [StudentDocumentController::class, 'destroy'])->name('students.documents.destroy');

    // Admission & Inquiry management
    Route::get('admissions-form', [AdmissionController::class, 'blankForm'])->name('admissions.blank-form');
    Route::resource('inquiries', InquiryController::class)->except('show');
    Route::post('inquiries/{inquiry}/convert', [InquiryController::class, 'convert'])->name('inquiries.convert');

    Route::resource('admissions', AdmissionController::class)->parameters(['admissions' => 'admission']);
    Route::post('admissions/{admission}/approve', [AdmissionController::class, 'approve'])->name('admissions.approve');
    Route::post('admissions/{admission}/reject', [AdmissionController::class, 'reject'])->name('admissions.reject');
    Route::post('admissions/{admission}/waitlist', [AdmissionController::class, 'waitlist'])->name('admissions.waitlist');
    Route::post('admissions/{admission}/enroll', [AdmissionController::class, 'enroll'])->name('admissions.enroll');

    // Phase 3 — Academic management
    Route::resource('sessions', AcademicSessionController::class)->except('show');
    Route::resource('subjects', SubjectController::class)->except('show');
    Route::resource('classes', SchoolClassController::class);
    Route::post('classes/{class}/sections', [SectionController::class, 'store'])->name('classes.sections.store');
    Route::put('sections/{section}', [SectionController::class, 'update'])->name('sections.update');
    Route::delete('sections/{section}', [SectionController::class, 'destroy'])->name('sections.destroy');
    Route::get('timetable', [\App\Http\Controllers\TimetableController::class, 'index'])->name('timetable.index');
    Route::post('classes/{class}/subjects', [ClassSubjectController::class, 'store'])->name('classes.subjects.store');
    Route::put('classes/{class}/subjects', [ClassSubjectController::class, 'update'])->name('classes.subjects.update');
    Route::delete('classes/{class}/subjects/{subject}', [ClassSubjectController::class, 'destroy'])->name('classes.subjects.destroy');

    // Phase 3 — Attendance
    Route::get('attendance/students', [StudentAttendanceController::class, 'index'])->name('attendance.students.index');
    Route::post('attendance/students', [StudentAttendanceController::class, 'store'])->name('attendance.students.store');
    Route::get('attendance/students/report', [StudentAttendanceController::class, 'report'])->name('attendance.students.report');
    Route::get('attendance/teachers', [TeacherAttendanceController::class, 'index'])->name('attendance.teachers.index');
    Route::post('attendance/teachers', [TeacherAttendanceController::class, 'store'])->name('attendance.teachers.store');
    Route::get('attendance/teachers/report', [TeacherAttendanceController::class, 'report'])->name('attendance.teachers.report');

    // Phase 4 — Fee Management
    Route::resource('fee-types', FeeTypeController::class)->except('show');
    Route::get('fee-structure', [FeeStructureController::class, 'index'])->name('fee-structure.index');
    Route::post('fee-structure', [FeeStructureController::class, 'store'])->name('fee-structure.store');
    Route::get('sibling-discounts', [SiblingDiscountController::class, 'index'])->name('sibling-discounts.index');
    Route::post('sibling-discounts', [SiblingDiscountController::class, 'store'])->name('sibling-discounts.store');
    Route::delete('sibling-discounts/{siblingDiscount}', [SiblingDiscountController::class, 'destroy'])->name('sibling-discounts.destroy');
    Route::resource('concessions', FeeConcessionController::class)->only(['index', 'create', 'store', 'destroy']);

    Route::get('fees/defaulters', [FeeChallanController::class, 'defaulters'])->name('fees.defaulters');
    Route::get('challans-lookup', [FeeChallanController::class, 'lookup'])->name('challans.lookup');
    Route::get('print-challans', [FeeChallanController::class, 'printChallansForm'])->name('challans.print-form');
    Route::get('print-challans/output', [FeeChallanController::class, 'printChallans'])->name('challans.print-bulk');
    Route::get('students/{student}/fee-card', [\App\Http\Controllers\FeeCardController::class, 'show'])->name('students.fee-card');
    Route::resource('challans', FeeChallanController::class)->only(['index', 'create', 'store', 'show', 'destroy']);
    Route::get('challans/{challan}/print', [FeeChallanController::class, 'print'])->name('challans.print');
    Route::post('challans/{challan}/waive', [FeeChallanController::class, 'waive'])->name('challans.waive');
    Route::post('challans/{challan}/payments', [FeePaymentController::class, 'store'])->name('challans.payments.store');
    Route::put('challans/{challan}/payments/{payment}', [FeePaymentController::class, 'update'])->name('challans.payments.update');
    Route::delete('challans/{challan}/payments/{payment}', [FeePaymentController::class, 'destroy'])->name('challans.payments.destroy');

    // Phase 5 — Accounting
    Route::resource('accounts', AccountController::class)->except('show');
    Route::get('journals/income', [JournalEntryController::class, 'income'])->name('journals.income');
    Route::post('journals/income', [JournalEntryController::class, 'storeIncome'])->name('journals.income.store');
    Route::get('journals/expense', [JournalEntryController::class, 'expense'])->name('journals.expense');
    Route::post('journals/expense', [JournalEntryController::class, 'storeExpense'])->name('journals.expense.store');
    Route::resource('journals', JournalEntryController::class)->only(['index', 'create', 'store', 'show', 'destroy']);
    Route::get('reports/ledger', [AccountingReportController::class, 'ledger'])->name('reports.ledger');
    Route::get('reports/cash-book', [AccountingReportController::class, 'cashBook'])->name('reports.cashbook');
    Route::get('reports/bank-book', [AccountingReportController::class, 'bankBook'])->name('reports.bankbook');
    Route::get('reports/trial-balance', [AccountingReportController::class, 'trialBalance'])->name('reports.trial-balance');
    Route::get('reports/profit-loss', [AccountingReportController::class, 'profitLoss'])->name('reports.profit-loss');
    Route::get('reports/balance-sheet', [AccountingReportController::class, 'balanceSheet'])->name('reports.balance-sheet');

    // Phase 8 — LMS (homework / assignments / notes)
    Route::resource('materials', LearningMaterialController::class);
    Route::post('submissions/{submission}/grade', [SubmissionController::class, 'grade'])->name('submissions.grade');

    // Phase 6 — Examinations
    Route::resource('exams', ExamController::class);
    Route::post('exams/{exam}/publish', [ExamController::class, 'publish'])->name('exams.publish');
    Route::post('exams/{exam}/papers', [ExamPaperController::class, 'generate'])->name('exams.papers.generate');
    Route::delete('exam-papers/{paper}', [ExamPaperController::class, 'destroy'])->name('exam-papers.destroy');
    Route::get('marks', [MarksController::class, 'index'])->name('marks.index');
    Route::post('marks', [MarksController::class, 'store'])->name('marks.store');
    Route::resource('grade-scale', GradeScaleController::class)->only(['index', 'store', 'destroy'])->parameters(['grade-scale' => 'gradeScale']);
    Route::get('results/card', [ResultController::class, 'card'])->name('results.card');
    Route::get('results/gazette', [ResultController::class, 'gazette'])->name('results.gazette');
    Route::get('results/positions', [ResultController::class, 'positions'])->name('results.positions');

    // Phase 10 — Communication
    Route::get('communication', [CommunicationController::class, 'index'])->name('communication.index');
    Route::get('communication/compose', [CommunicationController::class, 'compose'])->name('communication.compose');
    Route::post('communication/send', [CommunicationController::class, 'send'])->name('communication.send');

    // Phase 9 — Reports & Analytics
    Route::prefix('reports')->name('reports.')->group(function () {
        Route::get('/', [ReportController::class, 'index'])->name('index');
        Route::get('students', [ReportController::class, 'students'])->name('students');
        Route::get('admissions', [ReportController::class, 'admissions'])->name('admissions');
        Route::get('fee-collection', [ReportController::class, 'feeCollection'])->name('fee-collection');
        Route::get('defaulters', [ReportController::class, 'defaulters'])->name('defaulters');
        Route::get('branch-summary', [ReportController::class, 'branchSummary'])->name('branch-summary');
    });

    // Transport
    Route::resource('transport-routes', \App\Http\Controllers\TransportRouteController::class)->parameters(['transport-routes' => 'transportRoute']);
    Route::post('transport-routes/{transportRoute}/stops', [\App\Http\Controllers\TransportStopController::class, 'store'])->name('transport-routes.stops.store');
    Route::delete('transport-stops/{stop}', [\App\Http\Controllers\TransportStopController::class, 'destroy'])->name('transport-stops.destroy');
    Route::resource('vehicles', \App\Http\Controllers\VehicleController::class)->except('show');
    Route::get('transport-assign', [\App\Http\Controllers\TransportAssignmentController::class, 'index'])->name('transport-assign.index');
    Route::post('transport-assign', [\App\Http\Controllers\TransportAssignmentController::class, 'store'])->name('transport-assign.store');

    // Certificates
    Route::get('certificates/generate', [\App\Http\Controllers\CertificateController::class, 'generate'])->name('certificates.generate');
    Route::get('certificates/print', [\App\Http\Controllers\CertificateController::class, 'print'])->name('certificates.print');
    Route::resource('certificates', \App\Http\Controllers\CertificateController::class)->only(['index', 'create', 'store', 'edit', 'update', 'destroy']);

    // Visitors
    Route::resource('visitors', \App\Http\Controllers\VisitorController::class)->only(['index', 'create', 'store', 'destroy']);
    Route::get('visitors/{visitor}/pass', [\App\Http\Controllers\VisitorController::class, 'pass'])->name('visitors.pass');
    Route::post('visitors/{visitor}/checkout', [\App\Http\Controllers\VisitorController::class, 'checkout'])->name('visitors.checkout');

    // Help & Training (documentation) — viewing open to all staff, editing Super Admin only
    Route::get('docs', [\App\Http\Controllers\DocController::class, 'index'])->name('docs.index');
    Route::get('docs/create', [\App\Http\Controllers\DocController::class, 'create'])->name('docs.create');
    Route::post('docs', [\App\Http\Controllers\DocController::class, 'store'])->name('docs.store');
    Route::post('docs/upload-image', [\App\Http\Controllers\DocController::class, 'uploadImage'])->name('docs.upload-image');
    Route::get('docs/{doc}', [\App\Http\Controllers\DocController::class, 'show'])->name('docs.show');
    Route::get('docs/{doc}/edit', [\App\Http\Controllers\DocController::class, 'edit'])->name('docs.edit');
    Route::put('docs/{doc}', [\App\Http\Controllers\DocController::class, 'update'])->name('docs.update');
    Route::delete('docs/{doc}', [\App\Http\Controllers\DocController::class, 'destroy'])->name('docs.destroy');

    // Phase 1 — Administration
    Route::resource('branches', BranchController::class);
    Route::resource('users', UserController::class)->except('show');
    Route::resource('roles', RoleController::class)->except('show');
    Route::get('activity-log', [ActivityLogController::class, 'index'])->name('activity-log.index');

    // Phase 7 — Parent Portal (parents only)
    Route::middleware('role:Parent')->prefix('parent')->name('parent.')->group(function () {
        Route::get('dashboard', [ParentDashboardController::class, 'index'])->name('dashboard');
        Route::get('attendance', [ParentAttendanceController::class, 'index'])->name('attendance');
        Route::get('results', [ParentResultController::class, 'index'])->name('results');
        Route::get('fees', [ParentFeeController::class, 'index'])->name('fees');
        Route::get('fees/{challan}', [ParentFeeController::class, 'show'])->name('fees.show');
        Route::get('notices', [ParentNoticeController::class, 'index'])->name('notices');
        Route::get('homework', [ParentHomeworkController::class, 'index'])->name('homework');
        Route::post('homework/{material}/submit', [ParentHomeworkController::class, 'submit'])->name('homework.submit');
        Route::get('profile', [ParentProfileController::class, 'index'])->name('profile');
        Route::patch('profile/password', [ParentProfileController::class, 'updatePassword'])->name('profile.password');
    });

    // Student Portal (students only)
    Route::middleware('role:Student')->prefix('student-portal')->name('student.')->group(function () {
        Route::get('dashboard', [StudentDashboardController::class, 'index'])->name('dashboard');
        Route::get('attendance', [StudentAttendancePortalController::class, 'index'])->name('attendance');
        Route::get('results', [StudentResultPortalController::class, 'index'])->name('results');
        Route::get('homework', [StudentHomeworkController::class, 'index'])->name('homework');
        Route::post('homework/{material}/submit', [StudentHomeworkController::class, 'submit'])->name('homework.submit');
        Route::get('fees', [StudentFeePortalController::class, 'index'])->name('fees');
        Route::get('notices', [StudentNoticeController::class, 'index'])->name('notices');
        Route::get('profile', [StudentProfileController::class, 'index'])->name('profile');
        Route::patch('profile/password', [StudentProfileController::class, 'updatePassword'])->name('profile.password');
    });
});

/*
|----------------------------------------------------------------------------
| ⚠ TEMPORARY MAINTENANCE ROUTE — DELETE THIS WHOLE BLOCK AFTER USE.
|----------------------------------------------------------------------------
| Lets a Super Admin run a few whitelisted artisan commands from the browser
| on shared hosting that has no SSH (e.g. the one-time sibling-by-CNIC merge,
| clearing caches, creating the storage symlink).
|
| Protected by: (1) must be logged in as Super Admin, AND (2) a secret ?key=.
| CHANGE the secret below before uploading. Remove this block when done.
|
|   Preview merge : /_maintenance?key=SECRET&action=merge-preview
|   Apply  merge : /_maintenance?key=SECRET&action=merge-commit&confirm=yes
|   Clear caches : /_maintenance?key=SECRET&action=optimize-clear
|   Storage link : /_maintenance?key=SECRET&action=storage-link
*/
Route::middleware(['auth', 'role:Super Admin'])->get('/_maintenance', function (\Illuminate\Http\Request $request) {
    // 🔑 CHANGE THIS before uploading, then remove the whole block after use.
    $SECRET = 'sms-maint-7Kq2Zp9xR4vLtB6nW3';

    abort_unless(hash_equals($SECRET, (string) $request->query('key', '')), 403, 'Invalid maintenance key.');

    $key = urlencode($SECRET);
    $action = (string) $request->query('action', '');

    // Inline sibling-merge (does NOT depend on an artisan command being
    // registered — avoids command-discovery issues on shared hosting).
    $runMerge = function (bool $commit): string {
        $families = \App\Models\Family::withoutGlobalScopes()
            ->whereNotNull('father_cnic')->where('father_cnic', '!=', '')->get();

        $groups = $families
            ->groupBy(fn ($f) => $f->branch_id.'|'.preg_replace('/\D/', '', (string) $f->father_cnic))
            ->filter(fn ($g, $key) => count($g) > 1 && ! str_ends_with($key, '|'));

        if ($groups->isEmpty()) {
            return 'No duplicate families by father CNIC. Nothing to merge.';
        }

        $lines = [($commit ? 'MERGING' : 'DRY RUN — no changes will be saved').
            ' · '.$groups->count().' CNIC group(s) with duplicates', ''];
        $tD = $tS = $tC = $tA = 0;

        if ($commit) {
            \Illuminate\Support\Facades\DB::beginTransaction();
        }
        try {
            foreach ($groups as $group) {
                $sorted = $group->sortBy('id')->values();
                $primary = $sorted->first();
                $dupes = $sorted->slice(1);
                $lines[] = "CNIC {$primary->father_cnic}  →  keep #{$primary->id} ({$primary->family_code}), merge ".
                    $dupes->pluck('id')->map(fn ($id) => '#'.$id)->implode(', ');

                foreach ($dupes as $dup) {
                    $s = \App\Models\Student::withoutGlobalScopes()->where('family_id', $dup->id)->count();
                    $c = \App\Models\FeeChallan::withoutGlobalScopes()->where('family_id', $dup->id)->count();
                    $a = \App\Models\AdmissionApplication::withoutGlobalScopes()->where('family_id', $dup->id)->count();
                    $lines[] = "    #{$dup->id}: {$s} student(s), {$c} challan(s), {$a} application(s)";
                    $tD++; $tS += $s; $tC += $c; $tA += $a;

                    if ($commit) {
                        \App\Models\Student::withoutGlobalScopes()->where('family_id', $dup->id)->update(['family_id' => $primary->id]);
                        \App\Models\FeeChallan::withoutGlobalScopes()->where('family_id', $dup->id)->update(['family_id' => $primary->id]);
                        \App\Models\AdmissionApplication::withoutGlobalScopes()->where('family_id', $dup->id)->update(['family_id' => $primary->id]);
                        foreach (['father_name', 'father_mobile', 'mother_name', 'mother_mobile', 'guardian_name', 'address', 'email', 'user_id'] as $f) {
                            if (blank($primary->$f) && filled($dup->$f)) {
                                $primary->$f = $dup->$f;
                            }
                        }
                        $primary->save();
                        $dup->delete();
                    }
                }
            }
            if ($commit) {
                \Illuminate\Support\Facades\DB::commit();
            }
        } catch (\Throwable $e) {
            if ($commit) {
                \Illuminate\Support\Facades\DB::rollBack();
            }
            return 'ERROR: '.$e->getMessage();
        }

        $lines[] = '';
        $lines[] = ($commit ? 'Merged' : 'Would merge').": {$tD} duplicate famil(ies) → ".
            "reassigned {$tS} student(s), {$tC} challan(s), {$tA} application(s).";
        if (! $commit) {
            $lines[] = '';
            $lines[] = 'This was a DRY RUN. Click "APPLY" to commit (back up the DB first).';
        }

        return implode("\n", $lines);
    };

    $builtins = ['optimize-clear' => 'optimize:clear', 'view-clear' => 'view:clear', 'storage-link' => 'storage:link'];

    $output = '';
    $ran = '';
    if ($action === 'merge-preview') {
        $output = $runMerge(false);
        $ran = 'sibling merge (dry run)';
    } elseif ($action === 'merge-commit') {
        if ($request->query('confirm') !== 'yes') {
            $output = 'Refused: add &confirm=yes to actually apply the merge.';
        } else {
            $output = $runMerge(true);
            $ran = 'sibling merge (APPLIED)';
        }
    } elseif (isset($builtins[$action])) {
        try {
            \Illuminate\Support\Facades\Artisan::call($builtins[$action]);
            $output = \Illuminate\Support\Facades\Artisan::output() ?: 'Done.';
        } catch (\Throwable $e) {
            $output = 'ERROR: '.$e->getMessage();
        }
        $ran = $builtins[$action];
    }

    $btn = fn (string $a, string $label, string $extra = '') =>
        '<a class="b" href="/_maintenance?key='.$key.'&action='.$a.$extra.'">'.$label.'</a>';

    $out = e($output);
    $ranLine = $ran ? '<p class="ran">Ran: <code>'.e($ran).'</code></p>' : '';

    $html = <<<HTML
<!doctype html><html><head><meta charset="utf-8"><title>Maintenance</title>
<style>
 body{font-family:system-ui,Arial,sans-serif;background:#0f2438;color:#e7edf3;margin:0;padding:28px}
 .wrap{max-width:900px;margin:0 auto}
 h1{font-size:20px;margin:0 0 4px} .sub{color:#9fb3c8;font-size:13px;margin:0 0 18px}
 .b{display:inline-block;background:#16324f;color:#fff;text-decoration:none;padding:9px 14px;border-radius:8px;margin:0 8px 8px 0;font-size:14px;border:1px solid #24557f}
 .b:hover{background:#1d4269}
 .b.danger{background:#7a1f1f;border-color:#a33}
 .b.warn{background:#7a4a12;border-color:#b4771a}
 pre{background:#0a1a29;border:1px solid #24557f;border-radius:10px;padding:16px;white-space:pre-wrap;word-break:break-word;font-size:13px;line-height:1.5;min-height:60px}
 .ran{color:#7fd18f;font-size:13px} code{background:#0a1a29;padding:2px 6px;border-radius:5px}
 .note{color:#f0b37e;font-size:12.5px;margin-top:20px;border-top:1px solid #24557f;padding-top:12px}
</style></head><body><div class="wrap">
 <h1>SMS ERP · Maintenance</h1>
 <p class="sub">Temporary tool. Delete the route block from <code>routes/web.php</code> when finished.</p>
 <div>
   {$btn('merge-preview', '1 · Preview sibling merge (dry run)')}
   <a class="b danger" href="/_maintenance?key={$key}&action=merge-commit&confirm=yes" onclick="return confirm('Apply the merge now? Make sure you have a database backup.')">2 · APPLY sibling merge</a>
 </div>
 <div style="margin-top:6px">
   {$btn('optimize-clear', 'Clear caches (config/route/view)')}
   {$btn('view-clear', 'Clear compiled views')}
   {$btn('storage-link', 'Create storage link')}
 </div>
 {$ranLine}
 <pre>{$out}</pre>
 <p class="note">Security: this page requires a Super Admin login <b>and</b> the secret key. Remove the route block after use.</p>
</div></body></html>
HTML;

    return response($html);
});
