<?php

namespace App\Models;

use Config\Lookups;

/**
 * Maintenance module — see CreateMaintenanceWorkOrdersTable. "Overdue" is
 * never a stored status (see that migration's doc comment) — it's
 * open/in_progress work whose due_date has passed, computed here.
 */
class MaintenanceWorkOrderModel extends TenantModel
{
    protected $table            = 'maintenance_work_orders';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'object';
    protected $useTimestamps    = true;

    protected $allowedFields = [
        'title',
        'asset',
        'room_id',
        'priority',
        'status',
        'reported_by',
        'assigned_to',
        'due_date',
        'completed_at',
        'notes',
    ];

    public function __construct()
    {
        parent::__construct();

        $lookups = new Lookups();

        $this->validationRules = [
            'title'    => 'required|max_length[150]',
            'priority' => 'permit_empty|in_list[' . implode(',', array_keys($lookups->taskPriorities)) . ']',
            'status'   => 'permit_empty|in_list[' . implode(',', array_keys($lookups->workOrderStatuses)) . ']',
        ];
    }

    public function withDetails()
    {
        return $this->select('maintenance_work_orders.*, rooms.room_number, reporter.full_name as reported_by_name, assignee.full_name as assigned_to_name')
            ->join('rooms', 'rooms.id = maintenance_work_orders.room_id', 'left')
            ->join('users reporter', 'reporter.id = maintenance_work_orders.reported_by', 'left')
            ->join('users assignee', 'assignee.id = maintenance_work_orders.assigned_to', 'left');
    }

    public function countByStatus(string $status): int
    {
        return $this->where('status', $status)->countAllResults();
    }

    public function countCompletedOn(string $date): int
    {
        return $this->where('DATE(completed_at)', $date)->where('status', 'completed')->countAllResults();
    }

    /**
     * Open/in-progress work orders whose due date has already passed.
     */
    public function countOverdue(): int
    {
        return $this->whereIn('status', ['open', 'in_progress'])
            ->where('due_date IS NOT NULL', null, false)
            ->where('due_date <', date('Y-m-d'))
            ->countAllResults();
    }

    public function isOverdue(object $workOrder): bool
    {
        return in_array($workOrder->status, ['open', 'in_progress'], true)
            && $workOrder->due_date !== null
            && $workOrder->due_date < date('Y-m-d');
    }

    public function countByPriority(string $priority): int
    {
        return $this->whereIn('status', ['open', 'in_progress'])->where('priority', $priority)->countAllResults();
    }

    /** Used by StaffPerformanceController — resolved work orders per assignee in a date range. */
    public function resolvedCountByAssignee(string $from, string $to): array
    {
        $rows = $this->select('assigned_to, COUNT(*) as resolved_count')
            ->where('status', 'completed')
            ->where('completed_at >=', $from . ' 00:00:00')
            ->where('completed_at <=', $to . ' 23:59:59')
            ->where('assigned_to IS NOT NULL')
            ->groupBy('assigned_to')
            ->findAll();

        $byUser = [];

        foreach ($rows as $row) {
            $byUser[$row->assigned_to] = (int) $row->resolved_count;
        }

        return $byUser;
    }
}
