<?php

namespace App\Services\Admin\Finance\Payroll;

use App\Enums\PayrollAdjustmentType;
use App\Enums\PayrollStatus;
use App\Models\Payroll;
use App\Models\PayrollAdjustment;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

class PayrollAdjustmentService
{
    public function store(Payroll $payroll, array $data): PayrollAdjustment
    {
        if ($payroll->status !== PayrollStatus::UNPAID) {
            throw ValidationException::withMessages([
                'payroll' => 'Hanya gaji berstatus belum dibayar yang bisa diadjust.',
            ]);
        }

        return DB::transaction(function () use ($payroll, $data) {
            $adjustment = PayrollAdjustment::create([
                'payroll_id' => $payroll->id,
                'created_by_id' => auth()->id(),
                'attendance_id' => $data['attendance_id'] ?? null,
                'type' => $data['type'],
                'amount' => $data['amount'],
                'description' => $data['description'],
            ]);

            $this->recalculatePayroll($payroll);

            return $adjustment;
        });
    }

    public function destroy(PayrollAdjustment $adjustment): bool
    {
        $payroll = $adjustment->payroll;

        if ($payroll->status !== PayrollStatus::UNPAID) {
            throw ValidationException::withMessages([
                'payroll' => 'Hanya gaji berstatus belum dibayar yang bisa diadjust.',
            ]);
        }

        return DB::transaction(function () use ($adjustment, $payroll) {
            $result = $adjustment->delete();

            $this->recalculatePayroll($payroll);

            return $result;
        });
    }

    private function recalculatePayroll(Payroll $payroll): void
    {
        $payroll->refresh();

        $bonuses = $payroll->payrollAdjustments()
            ->where('type', PayrollAdjustmentType::BONUS)
            ->sum('amount');

        $deductions = $payroll->payrollAdjustments()
            ->where('type', PayrollAdjustmentType::DEDUCTION)
            ->sum('amount');

        $total = $payroll->base_salary + $bonuses - $deductions;

        $payroll->update([
            'bonus_amount' => $bonuses,
            'deduction_amount' => $deductions,
            'total_amount' => $total,
        ]);
    }
}
