<?php

namespace App\Http\Controllers;

use App\Http\Requests\PayComponentRequest;
use App\Models\PayComponent;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class PayComponentController extends Controller
{
    private const TYPES = [PayComponent::TYPE_EARNING, PayComponent::TYPE_DEDUCTION, PayComponent::TYPE_STATUTORY];

    private const METHODS = [
        PayComponent::CALC_FIXED, PayComponent::CALC_PERCENT_OF,
        PayComponent::CALC_GRADE_TABLE, PayComponent::CALC_FORMULA, PayComponent::CALC_LOAN,
    ];

    public function index(): Response
    {
        return Inertia::render('config/components/index', [
            'components' => PayComponent::orderBy('type')->orderBy('display_order')->get()->map(fn (PayComponent $c) => [
                'id' => $c->id,
                'code' => $c->code,
                'name' => $c->name,
                'type' => $c->type,
                'calc_method' => $c->calc_method,
                'rate' => $c->rate !== null ? (float) $c->rate : null,
                'amount' => $c->amount !== null ? (float) $c->amount : null,
                'taxable' => $c->taxable,
                'pensionable' => $c->pensionable,
                'active' => $c->active,
                'enrolments_count' => $c->enrolments()->count(),
            ]),
        ]);
    }

    public function create(): Response
    {
        return Inertia::render('config/components/form', [
            'mode' => 'create',
            'component' => null,
            'options' => ['types' => self::TYPES, 'methods' => self::METHODS],
        ]);
    }

    public function store(PayComponentRequest $request): RedirectResponse
    {
        $data = $request->validated();
        $data['display_order'] ??= (PayComponent::max('display_order') ?? 0) + 10;
        PayComponent::create($data);

        return redirect()->route('config.components.index')->with('success', 'Pay component created.');
    }

    public function edit(PayComponent $component): Response
    {
        return Inertia::render('config/components/form', [
            'mode' => 'edit',
            'component' => [
                'id' => $component->id,
                'code' => $component->code,
                'name' => $component->name,
                'type' => $component->type,
                'calc_method' => $component->calc_method,
                'base_reference' => $component->base_reference,
                'rate' => $component->rate !== null ? (float) $component->rate : null,
                'amount' => $component->amount !== null ? (float) $component->amount : null,
                'formula' => $component->formula,
                'taxable' => $component->taxable,
                'pensionable' => $component->pensionable,
                'tax_exempt' => $component->tax_exempt,
                'prorate' => $component->prorate,
                'gl_account' => $component->gl_account,
                'display_order' => $component->display_order,
                'active' => $component->active,
                'effective_from' => $component->effective_from?->toDateString(),
                'effective_to' => $component->effective_to?->toDateString(),
            ],
            'options' => ['types' => self::TYPES, 'methods' => self::METHODS],
        ]);
    }

    public function update(PayComponentRequest $request, PayComponent $component): RedirectResponse
    {
        // Code is immutable after creation.
        $component->update($request->safe()->except('code'));

        return redirect()->route('config.components.index')->with('success', 'Pay component updated.');
    }

    public function toggle(Request $request, PayComponent $component): RedirectResponse
    {
        abort_unless($request->user()?->hasAnyRole(['ADMIN', 'BURSARY']) ?? false, 403);
        $component->update(['active' => ! $component->active]);

        return back()->with('success', $component->active ? 'Component activated.' : 'Component deactivated.');
    }
}
