<?php

namespace Database\Seeders;

use App\Domain\Accounting\Models\LedgerAccount;
use App\Domain\Organization\Models\Company;
use App\Domain\Payroll\Models\SalaryComponent;
use Illuminate\Database\Seeder;

/**
 * The salary components from §51, ready to be attached to a structure.
 *
 * Percentages are basis points: a 40% house allowance is 4000, never 0.4.
 */
class SalaryComponentSeeder extends Seeder
{
    /** [code, name, type, mode, rate, expense account, payable account]. */
    private const COMPONENTS = [
        ['house_allowance', 'House Allowance', 'earning', 'percent_of_basic', 4000, '6100', null],
        ['medical_allowance', 'Medical Allowance', 'earning', 'percent_of_basic', 1000, '6100', null],
        ['transport_allowance', 'Transport Allowance', 'earning', 'fixed', 0, '6100', null],
        ['other_allowance', 'Other Allowance', 'earning', 'fixed', 0, '6100', null],
        ['bonus', 'Bonus', 'earning', 'fixed', 0, '6100', null],
        ['incentive', 'Incentive', 'earning', 'fixed', 0, '6100', null],
        ['overtime', 'Overtime', 'earning', 'overtime', 0, '6100', null],
        ['commission', 'Commission', 'earning', 'fixed', 0, '6100', null],
        ['arrears', 'Arrears', 'earning', 'fixed', 0, '6100', null],

        ['absence_deduction', 'Absence Deduction', 'deduction', 'attendance', 0, null, '2900'],
        ['late_deduction', 'Late Deduction', 'deduction', 'fixed', 0, null, '2900'],
        ['advance_recovery', 'Advance Recovery', 'deduction', 'fixed', 0, null, '1500'],
        ['income_tax', 'Income Tax', 'deduction', 'percent_of_gross', 500, null, '2400'],
        ['other_deduction', 'Other Deduction', 'deduction', 'fixed', 0, null, '2900'],

        ['provident_fund', 'Provident Fund (employee)', 'deduction', 'percent_of_basic', 1000, null, '2200'],
        ['provident_fund_employer', 'Provident Fund (employer)', 'employer_contribution', 'percent_of_basic', 1000, '6100', '2200'],
    ];

    public function run(): void
    {
        $company = Company::query()->first();

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

        $account = fn (?string $code) => $code === null
            ? null
            : LedgerAccount::where('company_id', $company->getKey())->where('code', $code)->value('id');

        foreach (self::COMPONENTS as $index => [$code, $name, $type, $mode, $rate, $expense, $payable]) {
            SalaryComponent::firstOrCreate(
                ['company_id' => $company->getKey(), 'code' => $code],
                [
                    'name' => $name,
                    'component_type' => $type,
                    'calculation_mode' => $mode,
                    'rate_basis_points' => $rate,
                    'ledger_account_id' => $account($expense),
                    'payable_account_id' => $account($payable),
                    'is_taxable' => $type === 'earning',
                    'is_active' => true,
                    'sort_order' => $index * 10,
                ],
            );
        }
    }
}
