<?php

namespace App\Models;

/**
 * One row per staff member per payroll run — money fields and
 * full_name_snapshot are frozen, not derived live from `users`. See
 * CreatePayslipsTable's migration comment.
 */
class PayslipModel extends TenantModel
{
    protected $table            = 'payslips';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'object';
    protected $useTimestamps    = true;
    protected $createdField     = 'created_at';
    protected $updatedField     = 'updated_at';

    protected $allowedFields = [
        'payroll_run_id',
        'user_id',
        'full_name_snapshot',
        'basic_salary',
        'total_allowances',
        'total_deductions',
        'net_pay',
    ];

    protected $validationRules = [
        'payroll_run_id' => 'required|integer',
        'full_name_snapshot' => 'required',
    ];

    public function forRun(int $payrollRunId): array
    {
        return $this->where('payroll_run_id', $payrollRunId)->orderBy('full_name_snapshot', 'asc')->findAll();
    }

    /** Salary History tab on the staff profile page. */
    public function forUser(int $userId): array
    {
        return $this->where('user_id', $userId)->orderBy('created_at', 'desc')->findAll();
    }

    /**
     * Recomputes and persists this payslip's totals/net pay from its own
     * line items — basic + allowances - deductions, via the shared
     * money_*() helpers so nothing drifts to raw float math.
     */
    public function recalculate(int $payslipId): void
    {
        $payslip = $this->find($payslipId);

        if ($payslip === null) {
            return;
        }

        $lineItems = (new PayslipLineItemModel())->forPayslip($payslipId);

        $allowances = '0.00';
        $deductions = '0.00';

        foreach ($lineItems as $item) {
            if ($item->type === 'allowance') {
                $allowances = money_add($allowances, $item->amount);
            } else {
                $deductions = money_add($deductions, $item->amount);
            }
        }

        $netPay = money_subtract(money_add($payslip->basic_salary, $allowances), $deductions);

        $this->update($payslipId, [
            'total_allowances' => $allowances,
            'total_deductions' => $deductions,
            'net_pay'          => $netPay,
        ]);
    }
}
