<?php

namespace App\Http\Controllers\Care;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Care\Concerns\ScopesToAccount;
use App\Models\InvestigationType;
use App\Services\Care\InvestigationService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class InvestigationTypeController extends Controller
{
    use ScopesToAccount;

    public function __construct(
        protected InvestigationService $investigations,
    ) {}

    public function index(Request $request): View
    {
        $this->authorizeAbility($request, 'lab.catalog.manage');
        $organization = $this->organization($request);

        $types = InvestigationType::query()
            ->where('organization_id', $organization->id)
            ->orderBy('category')
            ->orderBy('name')
            ->paginate(30);

        return view('care.lab.catalog.index', [
            'organization' => $organization,
            'types' => $types,
            'categories' => config('care.investigation_categories'),
        ]);
    }

    public function create(Request $request): View
    {
        $this->authorizeAbility($request, 'lab.catalog.manage');

        return view('care.lab.catalog.create', [
            'categories' => config('care.investigation_categories'),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $this->authorizeAbility($request, 'lab.catalog.manage');

        $type = $this->investigations->createType(
            $this->organization($request),
            $this->ownerRef($request),
            $this->validatedTypeData($request),
        );

        return redirect()->route('care.lab.catalog.index')
            ->with('success', "Investigation type \"{$type->name}\" created.");
    }

    public function edit(Request $request, InvestigationType $investigationType): View
    {
        $this->authorizeAbility($request, 'lab.catalog.manage');
        $this->authorizeType($request, $investigationType);

        return view('care.lab.catalog.edit', [
            'type' => $investigationType,
            'categories' => config('care.investigation_categories'),
        ]);
    }

    public function update(Request $request, InvestigationType $investigationType): RedirectResponse
    {
        $this->authorizeAbility($request, 'lab.catalog.manage');
        $this->authorizeType($request, $investigationType);

        $this->investigations->updateType($investigationType, $this->ownerRef($request), $this->validatedTypeData($request));

        return redirect()->route('care.lab.catalog.index')
            ->with('success', 'Investigation type updated.');
    }

    protected function authorizeType(Request $request, InvestigationType $type): void
    {
        abort_unless($type->organization_id === $this->organization($request)->id, 404);
    }

    /**
     * @return array<string, mixed>
     */
    protected function validatedTypeData(Request $request): array
    {
        return $request->validate([
            'name' => ['required', 'string', 'max:255'],
            'code' => ['nullable', 'string', 'max:50'],
            'category' => ['required', 'string', 'in:'.implode(',', array_keys(config('care.investigation_categories')))],
            'description' => ['nullable', 'string', 'max:2000'],
            'unit' => ['nullable', 'string', 'max:50'],
            'reference_low' => ['nullable', 'numeric'],
            'reference_high' => ['nullable', 'numeric'],
            'reference_text' => ['nullable', 'string', 'max:255'],
            'price_minor' => ['nullable', 'integer', 'min:0'],
            'is_active' => ['nullable', 'boolean'],
        ]);
    }
}
