<?php

namespace App\Http\Controllers;

use App\Models\TeacherAttendance;
use App\Models\User;
use App\Support\BranchContext;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
use Illuminate\Support\Carbon;
use Illuminate\View\View;

class TeacherAttendanceController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            new Middleware('can:attendance.view', only: ['index', 'report']),
            new Middleware('can:attendance.create', only: ['store']),
        ];
    }

    public function index(Request $request, BranchContext $context): View
    {
        $date = $request->date('date') ?: Carbon::today();

        $staff = $this->staffQuery($context)->get();
        $existing = TeacherAttendance::whereIn('user_id', $staff->pluck('id'))
            ->whereDate('date', $date)->get()->keyBy('user_id');

        return view('attendance.teachers.index', [
            'staff' => $staff,
            'existing' => $existing,
            'date' => $date->toDateString(),
        ]);
    }

    public function store(Request $request, BranchContext $context): RedirectResponse
    {
        $data = $request->validate([
            'date' => ['required', 'date'],
            'status' => ['required', 'array'],
            'status.*' => ['in:'.implode(',', TeacherAttendance::STATUSES)],
            'remarks' => ['array'],
        ]);

        $branchId = $context->currentId() ?? auth()->user()->branch_id;

        foreach ($data['status'] as $userId => $status) {
            $user = User::find($userId);
            if (! $user) {
                continue;
            }

            TeacherAttendance::updateOrCreate(
                ['user_id' => $userId, 'date' => $data['date']],
                [
                    'branch_id' => $user->branch_id ?? $branchId,
                    'status' => $status,
                    'remarks' => $data['remarks'][$userId] ?? null,
                    'marked_by' => auth()->id(),
                ]
            );
        }

        return back()->with('success', 'Staff attendance saved for '.Carbon::parse($data['date'])->format('d M Y').'.');
    }

    public function report(Request $request, BranchContext $context): View
    {
        $month = $request->input('month', Carbon::today()->format('Y-m'));
        [$year, $m] = array_pad(explode('-', $month), 2, null);
        $start = Carbon::createFromDate((int) $year, (int) $m, 1)->startOfMonth();
        $end = (clone $start)->endOfMonth();

        $staff = $this->staffQuery($context)->get();
        $att = TeacherAttendance::whereIn('user_id', $staff->pluck('id'))
            ->whereBetween('date', [$start, $end])->get()->groupBy('user_id');

        $rows = $staff->map(function ($u) use ($att) {
            $records = $att->get($u->id, collect());

            return [
                'user' => $u,
                'present' => $records->where('status', 'present')->count(),
                'absent' => $records->where('status', 'absent')->count(),
                'leave' => $records->where('status', 'leave')->count(),
                'late' => $records->where('status', 'late')->count(),
                'total' => $records->count(),
            ];
        });

        return view('attendance.teachers.report', compact('rows', 'month'));
    }

    /** Active staff within the active-branch context (excludes Super Admins). */
    private function staffQuery(BranchContext $context)
    {
        return User::query()
            ->where('is_active', true)
            ->whereDoesntHave('roles', fn ($q) => $q->where('name', User::SUPER_ADMIN))
            ->when($context->currentId(), fn ($q, $id) => $q->where('branch_id', $id))
            ->when(! auth()->user()->isSuperAdmin(), fn ($q) => $q->whereIn('branch_id', auth()->user()->accessibleBranchIds()))
            ->orderBy('name');
    }
}
