<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ActivityLog;
use App\Models\AppNotification;
use App\Models\Student;
use Illuminate\Http\Request;

// Trash, activity log and notifications endpoints. Trash currently aggregates
// soft-deleted students + evaluations; each new soft-deletable module plugs in
// here in its own phase.
class SystemController extends Controller
{
    /** module key => [Model class, label resolver]. */
    private function trashMap(): array
    {
        return [
            'students' => [\App\Models\Student::class, fn ($m) => $m->full_name],
            'teachers' => [\App\Models\Staff::class, fn ($m) => $m->name],
            'parents' => [\App\Models\Guardian::class, fn ($m) => $m->name],
            'classes' => [\App\Models\SchoolClass::class, fn ($m) => $m->name],
            'evaluations' => [\App\Models\Evaluation::class, fn ($m) => $m->title_en ?: ('Evaluation #'.$m->id)],
            'exams' => [\App\Models\Exam::class, fn ($m) => $m->name],
            'notices' => [\App\Models\Notice::class, fn ($m) => $m->title],
            'branches' => [\App\Models\Branch::class, fn ($m) => $m->name],
            'eval-templates' => [\App\Models\EvaluationTemplate::class, fn ($m) => $m->name],
            'invitations' => [\App\Models\Invitation::class, fn ($m) => $m->title],
            'vehicles' => [\App\Models\Vehicle::class, fn ($m) => $m->name],
        ];
    }

    public function trash(Request $request)
    {
        $rows = collect();
        foreach ($this->trashMap() as $module => [$class, $label]) {
            // Staff carries teachers + employees; label the module by type.
            $class::onlyTrashed()->get()->each(function ($m) use (&$rows, $module, $label) {
                $mod = $module;
                if ($m instanceof \App\Models\Staff) {
                    $mod = $m->type === 'employee' ? 'employees' : 'teachers';
                }
                $rows->push([
                    'id' => $m->id,
                    'key' => $mod.'-'.$m->id,
                    'module' => $mod,
                    'label' => $label($m),
                    'deleted_at' => $m->deleted_at,
                    'deleted_by' => null,
                ]);
            });
        }

        return response()->json(['data' => $rows->sortByDesc('deleted_at')->values()]);
    }

    private function resolveTrashed(Request $request, $id)
    {
        $module = $request->query('module') ?: $request->input('module');
        $map = $this->trashMap();
        // Employees live in the Staff model too.
        $class = $map[$module][0] ?? ($module === 'employees' ? \App\Models\Staff::class : null);
        if (! $class) {
            return null;
        }

        return $class::onlyTrashed()->find($id);
    }

    public function restoreTrash(Request $request, $id)
    {
        $model = $this->resolveTrashed($request, $id);
        $model?->restore();
        if ($model) {
            ActivityLog::record('restore', 'trash', 'Restored '.class_basename($model)." #{$id}");
        }

        return response()->json(['success' => (bool) $model]);
    }

    public function purgeTrash(Request $request, $id)
    {
        $model = $this->resolveTrashed($request, $id);
        $model?->forceDelete();
        if ($model) {
            ActivityLog::record('delete', 'trash', 'Permanently deleted '.class_basename($model)." #{$id}");
        }

        return response()->json(['success' => (bool) $model]);
    }

    public function logs(Request $request)
    {
        return response()->json(['data' => ActivityLog::orderByDesc('created_at')->limit(500)->get()]);
    }

    public function notifications(Request $request)
    {
        $userId = $request->user()?->id;

        return response()->json([
            'data' => AppNotification::where(fn ($q) => $q->whereNull('user_id')->orWhere('user_id', $userId))
                ->orderByDesc('created_at')->limit(100)->get(),
        ]);
    }

    public function readNotification($id)
    {
        AppNotification::where('id', $id)->update(['read_at' => now()]);

        return response()->json(['success' => true]);
    }

    public function readAllNotifications(Request $request)
    {
        AppNotification::whereNull('read_at')->update(['read_at' => now()]);

        return response()->json(['success' => true]);
    }
}
