<?php

namespace App\Console\Commands;

use App\Enums\PayrollPeriodStatus;
use App\Enums\PayrollStatus;
use App\Enums\Role;
use App\Models\Employee;
use App\Models\Payroll;
use App\Models\PayrollPeriod;
use Illuminate\Console\Command;

class GeneratePayrollCommand extends Command
{
    protected $signature = 'payroll:generate';

    protected $description = 'Generate payroll for all active employees (scheduled on 5th of each month)';

    public function handle(): int
    {
        $now = now();
        $year = $now->year;
        $month = $now->month;

        $period = PayrollPeriod::firstOrCreate(
            ['year' => $year, 'month' => $month],
            ['status' => PayrollPeriodStatus::OPEN]
        );

        if ($period->status !== PayrollPeriodStatus::OPEN) {
            $this->error("Periode gaji {$this->getMonthName($month)} {$year} sudah ditutup.");

            return Command::FAILURE;
        }

        $employees = Employee::whereHas('user', fn ($q) => $q->where('is_active', true))
            ->whereDoesntHave('user.roles', fn ($q) => $q->where('name', Role::ADMIN_BAHAN_BAKU))
            ->where(fn ($q) => $q->whereNull('resign_date')->orWhere('resign_date', '>=', $now->toDateString()))
            ->get();

        $existingPayrollEmployeeIds = Payroll::where('payroll_period_id', $period->id)
            ->pluck('employee_id')
            ->toArray();

        $newPayrolls = 0;

        foreach ($employees as $employee) {
            if (in_array($employee->id, $existingPayrollEmployeeIds)) {
                continue;
            }

            Payroll::create([
                'payroll_period_id' => $period->id,
                'employee_id' => $employee->id,
                'base_salary' => $employee->base_salary,
                'bonus_amount' => 0,
                'deduction_amount' => 0,
                'total_amount' => $employee->base_salary,
                'status' => PayrollStatus::UNPAID,
            ]);

            $newPayrolls++;
        }

        $this->info("Berhasil generate {$newPayrolls} gaji untuk periode {$this->getMonthName($month)} {$year}.");

        return Command::SUCCESS;
    }

    private function getMonthName(int $month): string
    {
        return [
            1 => 'Januari',
            2 => 'Februari',
            3 => 'Maret',
            4 => 'April',
            5 => 'Mei',
            6 => 'Juni',
            7 => 'Juli',
            8 => 'Agustus',
            9 => 'September',
            10 => 'Oktober',
            11 => 'November',
            12 => 'Desember',
        ][$month] ?? '';
    }
}
