<?php

namespace App\Http\Controllers\Care;

use App\Http\Controllers\Care\Concerns\ScopesToAccount;
use App\Http\Controllers\Controller;
use App\Models\Patient;
use App\Services\Care\AssessmentService;
use App\Services\Care\CareFeatures;
use App\Services\Care\CarePermissions;
use App\Services\Care\OrganizationResolver;
use App\Services\Care\OutcomeTrendService;
use App\Services\Care\PlanService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class OutcomeController extends Controller
{
    use ScopesToAccount;

    public function __construct(
        protected OutcomeTrendService $trends,
        protected AssessmentService $assessments,
        protected CareFeatures $features,
        protected CarePermissions $permissions,
        protected PlanService $plans,
    ) {}

    /**
     * Per-patient outcome history + instrument score trends (free).
     */
    public function index(Request $request, Patient $patient): View
    {
        $this->assertEngineEnabled($request);
        $this->authorizeAbility($request, 'assessments.view');
        $this->authorizePatient($request, $patient);

        $branchScope = app(OrganizationResolver::class)->branchScope($this->member($request));
        $ownerRef = $this->ownerRef($request);

        $outcomeSeries = $this->trends->outcomeSeries($patient, $ownerRef, $branchScope);
        $scores = $this->trends->instrumentScores($patient, $ownerRef, $branchScope);
        $vitals = $this->trends->recentVitals($patient, $ownerRef);

        $canCapture = $this->permissions->can($this->member($request), 'assessments.capture')
            || $this->permissions->can($this->member($request), 'assessments.manage');

        // Org-level multi-patient analytics is Enterprise (KD-18); surface a notice only.
        $canOrgAnalytics = $this->plans->isEnterprise($this->organization($request));

        return view('care.outcomes.index', [
            'patient' => $patient,
            'outcomeSeries' => $outcomeSeries,
            'scores' => $scores,
            'vitals' => $vitals,
            'canCapture' => $canCapture,
            'canOrgAnalytics' => $canOrgAnalytics,
            'qolSeries' => $this->trends->numericOutcomeSeries($patient, $ownerRef, 'quality_of_life', $branchScope),
            'painSeries' => $this->trends->numericOutcomeSeries($patient, $ownerRef, 'pain_score', $branchScope),
            'statuses' => config('care.assessment_statuses'),
        ]);
    }

    /**
     * Start a new outcome_core draft for the patient.
     */
    public function store(Request $request, Patient $patient): RedirectResponse
    {
        $this->assertEngineEnabled($request);
        abort_unless(
            $this->permissions->can($this->member($request), 'assessments.capture')
            || $this->permissions->can($this->member($request), 'assessments.manage'),
            403,
        );
        $this->authorizePatient($request, $patient);

        $assessment = $this->assessments->start(
            $patient,
            OutcomeTrendService::OUTCOME_TEMPLATE_CODE,
            $this->ownerRef($request),
            $this->member($request),
            ['actor' => $this->ownerRef($request)],
        );

        return redirect()
            ->route('care.assessments.show', $assessment)
            ->with('success', 'Outcome assessment started.');
    }

    protected function assertEngineEnabled(Request $request): void
    {
        abort_unless(
            $this->features->enabled($this->organization($request), CareFeatures::ASSESSMENTS_ENGINE),
            404,
        );
        $this->features->ensureAssessmentCatalog();
    }

    protected function authorizePatient(Request $request, Patient $patient): void
    {
        $this->authorizeOwner($request, $patient);
        abort_unless($patient->organization_id === $this->organization($request)->id, 404);

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