<?php

namespace App\Console\Commands;

use App\Models\EmployeePayroll;
use App\Models\EmployeePayrollComponent;
use App\Models\Payroll;
use App\Models\PayrollCycle;
use Illuminate\Console\Command;

class BackfillPayrollV2FromLegacyCommand extends Command
{
    protected $signature = 'payroll:backfill-v2
                            {--company= : Limit to company ID}
                            {--year= : Limit to year}
                            {--month= : Limit to month}
                            {--dry-run : Do not persist}';

    protected $description = 'Backfill payroll_cycles and employee_payrolls from legacy payrolls table.';

    public function handle(): int
    {
        $companyId = $this->option('company') ? (int) $this->option('company') : null;
        $year = $this->option('year') ? (int) $this->option('year') : null;
        $month = $this->option('month') ? (int) $this->option('month') : null;
        $dryRun = $this->option('dry-run');

        $query = Payroll::withoutGlobalScopes()->with(['user', 'payrollComponents']);
        if ($companyId) {
            $query->where('company_id', $companyId);
        }
        if ($year !== null) {
            $query->where('year', $year);
        }
        if ($month !== null) {
            $query->where('month', $month);
        }
        $legacy = $query->get()->groupBy(function ($p) {
            return $p->company_id . '_' . $p->year . '_' . $p->month;
        });

        $createdCycles = 0;
        $createdEmployeePayrolls = 0;

        foreach ($legacy as $key => $payrolls) {
            $first = $payrolls->first();
            $cid = $first->company_id;
            $y = $first->year;
            $m = $first->month;
            $start = \Carbon\Carbon::createFromDate($y, $m, 1)->startOfDay();
            $end = $start->copy()->endOfMonth();

            if ($dryRun) {
                $this->line("Would create cycle company={$cid} {$y}-{$m} with " . $payrolls->count() . " employee payrolls.");
                $createdCycles++;
                $createdEmployeePayrolls += $payrolls->count();
                continue;
            }

            $cycle = PayrollCycle::withoutGlobalScopes()->firstOrCreate(
                ['company_id' => $cid, 'year' => $y, 'month' => $m],
                [
                    'status' => 'completed',
                    'start_date' => $start,
                    'end_date' => $end,
                ]
            );
            if ($cycle->wasRecentlyCreated) {
                $createdCycles++;
            }

            foreach ($payrolls as $p) {
                $ep = EmployeePayroll::withoutGlobalScopes()->firstOrCreate(
                    ['payroll_cycle_id' => $cycle->id, 'user_id' => $p->user_id],
                    [
                        'company_id' => $cid,
                        'ctc_annual' => null,
                        'gross_monthly' => $p->salary_amount,
                        'net_monthly' => $p->net_salary,
                        'total_deductions' => ($p->salary_amount ?? 0) - ($p->net_salary ?? 0),
                        'lop_days' => 0,
                        'lop_amount' => 0,
                        'working_days' => $p->working_days ?? 0,
                        'paid_days' => $p->present_days ?? 0,
                        'status' => 'calculated',
                    ]
                );
                if ($ep->wasRecentlyCreated) {
                    $createdEmployeePayrolls++;
                }
                if ($ep->components()->count() === 0 && $p->payrollComponents->isNotEmpty()) {
                    $order = 0;
                    foreach ($p->payrollComponents as $c) {
                        EmployeePayrollComponent::withoutGlobalScopes()->create([
                            'company_id' => $cid,
                            'employee_payroll_id' => $ep->id,
                            'component_code' => strtoupper(substr(preg_replace('/\s+/', '_', $c->name), 0, 64)),
                            'name' => $c->name,
                            'category' => $c->is_earning ? 'earning' : 'deduction',
                            'amount' => $c->is_earning ? (float) $c->amount : -(float) abs($c->amount),
                            'display_order' => $order++,
                        ]);
                    }
                }
            }
        }

        $this->info("Cycles created/used: {$createdCycles}, Employee payrolls created: {$createdEmployeePayrolls}.");
        return self::SUCCESS;
    }
}
