<?php

namespace App\Models;

class ShiftModel extends TenantModel
{
    protected $table            = 'shifts';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'object';
    protected $useTimestamps    = true;

    protected $allowedFields = [
        'user_id',
        'shift_date',
        'shift_block',
        'standard_hours',
        'actual_hours',
        'status',
        'notes',
        'created_by',
    ];

    public function withStaff()
    {
        return $this->select('shifts.*, users.full_name as staff_name, users.role as staff_role')
            ->join('users', 'users.id = shifts.user_id', 'left');
    }

    /** The week grid a manager sees — every shift for every staff member across 7 days, oldest block first. */
    public function forWeek(string $startDate): array
    {
        $end = date('Y-m-d', strtotime($startDate . ' +6 days'));

        return $this->withStaff()
            ->where('shifts.shift_date >=', $startDate)
            ->where('shifts.shift_date <=', $end)
            ->orderBy('shifts.shift_date')
            ->orderBy("FIELD(shifts.shift_block, 'morning','afternoon','night')", '', false)
            ->findAll();
    }

    /** "My Shifts" — a single staff member's own upcoming (and recent) schedule. */
    public function forUser(int $userId, string $fromDate): array
    {
        return $this->withStaff()
            ->where('shifts.user_id', $userId)
            ->where('shifts.shift_date >=', $fromDate)
            ->orderBy('shifts.shift_date')
            ->findAll();
    }

    /** Overtime is never inferred — only real when a shift's actual_hours has been logged. */
    public function overtimeHours(object $shift): float
    {
        if ($shift->actual_hours === null) {
            return 0.0;
        }

        return max(0.0, (float) $shift->actual_hours - (float) $shift->standard_hours);
    }

    /** Used by StaffPerformanceController — total overtime logged per staff member in a date range, real data only. */
    public function overtimeByUser(string $fromDate, string $toDate): array
    {
        $rows = $this->select('user_id, SUM(GREATEST(0, actual_hours - standard_hours)) as overtime_hours')
            ->where('shift_date >=', $fromDate)
            ->where('shift_date <=', $toDate)
            ->where('actual_hours IS NOT NULL')
            ->groupBy('user_id')
            ->findAll();

        $byUser = [];

        foreach ($rows as $row) {
            $byUser[$row->user_id] = (float) $row->overtime_hours;
        }

        return $byUser;
    }
}
