<?php

namespace Database\Seeders;

use App\Domain\Accounting\Models\LedgerAccount;
use App\Domain\Expenses\Models\ExpenseApprovalRule;
use App\Domain\Expenses\Models\ExpenseCategory;
use App\Domain\Organization\Models\Company;
use Illuminate\Database\Seeder;

/**
 * Expense categories and the approval matrix from §40.
 *
 * The bands are the spec's example, in minor units. They are data, so an
 * agency edits them rather than asking for a code change.
 */
class ExpenseSetupSeeder extends Seeder
{
    /** [code, name, ledger account code]. */
    private const CATEGORIES = [
        ['office_rent', 'Office Rent', '6150'],
        ['utilities', 'Utilities', '6200'],
        ['internet', 'Internet', '6250'],
        ['marketing', 'Marketing', '6300'],
        ['travel', 'Travel', '6350'],
        ['transport', 'Transport', '6400'],
        ['printing', 'Printing', '6450'],
        ['software', 'Software', '6500'],
        ['legal', 'Legal', '6550'],
        ['professional_fees', 'Professional Fees', '6600'],
        ['bank_charges', 'Bank Charges', '6650'],
        ['maintenance', 'Repair & Maintenance', '6700'],
        ['office_supplies', 'Office Supplies', '6750'],
        ['medical_cost', 'Medical Cost', '5100'],
        ['visa_cost', 'Visa Cost', '5200'],
        ['government_fee', 'Government Fee', '5400'],
        ['ticket_cost', 'Ticket Cost', '5700'],
        ['miscellaneous', 'Miscellaneous', '6900'],
    ];

    /** [ceiling in minor units or null, approver role]. */
    private const BANDS = [
        [1_000_000, 'branch-manager'],
        [5_000_000, 'branch-manager'],
        [20_000_000, 'accounts-manager'],
        [null, 'director'],
    ];

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

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

        $currency = config('mams.money.base_currency');

        foreach (self::CATEGORIES as [$code, $name, $accountCode]) {
            $account = LedgerAccount::where('company_id', $company->getKey())
                ->where('code', $accountCode)
                ->first();

            ExpenseCategory::firstOrCreate(
                ['company_id' => $company->getKey(), 'code' => $code],
                [
                    'name' => $name,
                    'ledger_account_id' => $account?->getKey(),
                    'requires_receipt' => true,
                    'is_active' => true,
                ],
            );
        }

        foreach (self::BANDS as $index => [$ceiling, $role]) {
            ExpenseApprovalRule::firstOrCreate(
                [
                    'company_id' => $company->getKey(),
                    'currency' => $currency,
                    'sort_order' => $index,
                ],
                [
                    'up_to_amount' => $ceiling,
                    'approver_role' => $role,
                    'is_active' => true,
                ],
            );
        }
    }
}
