<?php

namespace Modules\Leave\Services;

use App\Models\ActivityLogModel;
use App\Models\EmployeeModel;
use App\Models\LeaveBalanceModel;
use App\Models\LeaveTypeModel;

class LeaveBalanceService
{
    protected LeaveBalanceModel $balances;
    protected LeaveTypeModel $types;
    protected EmployeeModel $employees;
    protected ActivityLogModel $activity;

    public function __construct()
    {
        $this->balances  = new LeaveBalanceModel();
        $this->types     = new LeaveTypeModel();
        $this->employees = new EmployeeModel();
        $this->activity  = new ActivityLogModel();
    }

    public function ensureBalancesForEmployee(int $employeeId, int $year): void
    {
        $types = $this->types->getActive();
        foreach ($types as $type) {
            $this->balances->findOrCreate(
                $employeeId,
                (int) $type['id'],
                $year,
                (float) $type['days_per_year']
            );
        }
    }

    public function ensureAllEmployeeBalances(int $year): int
    {
        $employees = $this->employees->where('status', 'active')->findAll();
        foreach ($employees as $emp) {
            $this->ensureBalancesForEmployee((int) $emp['id'], $year);
        }

        return count($employees);
    }

    public function updateEntitlement(int $id, float $entitled, ?int $actingUserId): array
    {
        $balance = $this->balances->find($id);
        if (! $balance) {
            return ['success' => false, 'errors' => ['id' => 'Leave balance not found.']];
        }

        if ($entitled < (float) $balance['used']) {
            return ['success' => false, 'errors' => ['entitled' => 'Entitlement cannot be less than used days.']];
        }

        $this->balances->update($id, ['entitled' => $entitled]);
        $this->activity->log(
            'leave_balances',
            'updated',
            $actingUserId,
            "Updated leave balance #{$id} entitlement to {$entitled}",
            (string) $id
        );

        return ['success' => true];
    }
}
