<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Api\Concerns\ScopesApiToAccount;
use App\Models\Consultation;
use App\Models\InvestigationRequest;
use App\Models\InvestigationType;
use App\Models\Prescription;
use App\Services\Care\InvestigationService;
use App\Services\Care\OrganizationResolver;
use App\Services\Care\PrescriptionService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class InvestigationController extends Controller
{
    use ScopesApiToAccount;

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

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

        $types = InvestigationType::owned($this->ownerRef($request))
            ->where('organization_id', $organization->id)
            ->where('is_active', true)
            ->orderBy('name')
            ->get();

        return response()->json(['data' => $types]);
    }

    public function index(Request $request): JsonResponse
    {
        $this->authorizeAbility($request, 'lab.view');
        $organization = $this->organization($request);
        $branchScope = app(OrganizationResolver::class)->branchScope($this->member($request));

        $requests = $this->investigations->list(
            $this->ownerRef($request),
            $organization->id,
            $request->only(['status', 'patient_id', 'per_page']),
            $branchScope,
        );

        return response()->json($requests);
    }

    public function queue(Request $request): JsonResponse
    {
        $this->authorizeAbility($request, 'lab.manage');

        $validated = $request->validate([
            'branch_id' => ['required', 'integer', 'exists:care_branches,id'],
            'status' => ['nullable', 'string'],
        ]);

        $queue = $this->investigations->workQueue(
            $this->ownerRef($request),
            (int) $validated['branch_id'],
            $validated['status'] ?? null,
        );

        return response()->json(['data' => $queue]);
    }

    public function store(Request $request, Consultation $consultation): JsonResponse
    {
        $this->authorizeAbility($request, 'investigations.request');
        $this->authorizeConsultation($request, $consultation);

        $validated = $request->validate([
            'investigation_type_ids' => ['required', 'array', 'min:1'],
            'investigation_type_ids.*' => ['integer', 'exists:care_investigation_types,id'],
            'clinical_notes' => ['nullable', 'string', 'max:2000'],
            'priority' => ['nullable', 'string', 'in:routine,urgent'],
        ]);

        $created = $this->investigations->requestFromConsultation(
            $consultation,
            $this->ownerRef($request),
            $validated['investigation_type_ids'],
            $validated['clinical_notes'] ?? null,
            $validated['priority'] ?? 'routine',
            $this->ownerRef($request),
        );

        return response()->json(['data' => $created], 201);
    }

    public function show(Request $request, InvestigationRequest $investigation): JsonResponse
    {
        $this->authorizeAbility($request, 'lab.view');
        $this->authorizeInvestigation($request, $investigation);

        return response()->json($investigation->load([
            'patient', 'investigationType', 'result.values', 'result.attachments',
        ]));
    }

    public function collectSample(Request $request, InvestigationRequest $investigation): JsonResponse
    {
        $this->authorizeAbility($request, 'lab.manage');
        $this->authorizeInvestigation($request, $investigation);

        $updated = $this->investigations->collectSample(
            $investigation,
            $this->ownerRef($request),
            $request->input('sample_barcode'),
            $this->ownerRef($request),
        );

        return response()->json($updated);
    }

    public function enterResults(Request $request, InvestigationRequest $investigation): JsonResponse
    {
        $this->authorizeAbility($request, 'lab.manage');
        $this->authorizeInvestigation($request, $investigation);

        $validated = $request->validate([
            'value' => ['nullable', 'string', 'max:255'],
            'result_summary' => ['nullable', 'string', 'max:5000'],
            'interpretation' => ['nullable', 'string', 'max:5000'],
            'values' => ['nullable', 'array'],
        ]);

        $result = $this->investigations->enterResults(
            $investigation,
            $this->ownerRef($request),
            $validated,
            $this->ownerRef($request),
        );

        return response()->json($result);
    }

    public function approve(Request $request, InvestigationRequest $investigation): JsonResponse
    {
        $this->authorizeAbility($request, 'pathology.result.approve');
        $this->authorizeInvestigation($request, $investigation);

        $updated = $this->investigations->approve($investigation, $this->ownerRef($request), $this->ownerRef($request));

        return response()->json($updated);
    }

    protected function authorizeConsultation(Request $request, Consultation $consultation): void
    {
        $this->authorizeOwner($request, $consultation);
        $consultation->loadMissing('visit');
        abort_unless($consultation->visit->organization_id === $this->organization($request)->id, 404);
    }

    protected function authorizeInvestigation(Request $request, InvestigationRequest $investigation): void
    {
        $this->authorizeOwner($request, $investigation);
        abort_unless($investigation->organization_id === $this->organization($request)->id, 404);

        $branchScope = app(OrganizationResolver::class)->branchScope($this->member($request));
        if ($branchScope !== null && $investigation->branch_id !== $branchScope) {
            abort(404);
        }
    }
}
