<?php

namespace Modules\ClinicLab\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\ClinicCore\Entities\ClcPatient;
use Modules\LabCore\Entities\LabDevice;
use Modules\LabCore\Entities\LabWorklist;
use Modules\ClinicLab\Entities\Services\ClinicLabService;

/**
 * Order LabCore tests from a ClinicCore patient and view results — the bridge's
 * UI, served entirely under /clinic-lab.
 */
class ClinicLabController extends Controller
{
    protected function guard(): void
    {
        $u = auth()->user();
        if (! $u || ! ($u->can('clinic.manage_appointments') || $u->can('lab.access_module') || $u->can('clinic.manage_pets'))) {
            abort(403, 'Unauthorized action.');
        }
    }

    protected function bizId()
    {
        return request()->session()->get('user.business_id');
    }

    protected function patient($id): ClcPatient
    {
        return ClcPatient::where('business_id', $this->bizId())->findOrFail($id);
    }

    public function index()
    {
        $this->guard();
        $orders = LabWorklist::where('business_id', $this->bizId())
            ->whereNotNull('clc_patient_id')
            ->orderByDesc('id')->limit(100)->get();

        // SIFA P4-T4 — decorate the worklist with specimen + review status so the
        // clinic team can see, at a glance, where each order is in the pipeline.
        // Read-only lookups keyed off worklist_id / sample_no; both cll_ tables
        // are guarded so the legacy screen still renders pre-migration.
        $specimenByWorklist = collect();
        $reviewBySample = collect();
        try {
            $ids = $orders->pluck('id')->all();
            if (\Schema::hasTable('cll_specimens') && !empty($ids)) {
                $specimenByWorklist = \Modules\ClinicLab\Entities\CllSpecimen::forBusiness($this->bizId())
                    ->whereIn('worklist_id', $ids)->get()->keyBy('worklist_id');
            }
            $samples = $orders->pluck('sample_no')->filter()->all();
            if (\Schema::hasTable('cll_result_reviews') && \Schema::hasTable('lab_test_sessions') && !empty($samples)) {
                $reviewBySample = \Modules\ClinicLab\Entities\CllResultReview::forBusiness($this->bizId())
                    ->join('lab_test_sessions', 'lab_test_sessions.id', '=', 'cll_result_reviews.test_session_id')
                    ->whereIn('lab_test_sessions.sample_no', $samples)
                    ->get(['cll_result_reviews.status', 'lab_test_sessions.sample_no as sample_no'])
                    ->keyBy('sample_no');
            }
        } catch (\Throwable $e) {
            // Legacy screen must render even if the P4-T4 tables aren't present yet.
        }

        return view('clinicLab::index', compact('orders', 'specimenByWorklist', 'reviewBySample'));
    }

    public function order($patientId)
    {
        $this->guard();
        $patient = $this->patient($patientId);
        $devices = LabDevice::where('business_id', $this->bizId())->orderBy('name')->get();
        return view('clinicLab::order', compact('patient', 'devices'));
    }

    public function store($patientId, Request $request, ClinicLabService $service)
    {
        $this->guard();
        $patient = $this->patient($patientId);

        $data = $request->validate([
            'device_id' => 'nullable|integer|exists:lab_devices,id',
            'vendor'    => 'nullable|string|max:30',
            'sample_no' => 'nullable|string|max:30',
            'tests'     => 'nullable|string|max:2000',
            'clc_appointment_id' => 'nullable|integer',
        ]);

        $device = !empty($data['device_id']) ? LabDevice::find($data['device_id']) : null;
        $service->createOrder($patient, [
            'device_id'          => $device?->id,
            'agent_id'           => $device?->agent_id,
            'vendor'             => $device?->vendor ?: ($data['vendor'] ?: 'manual'),
            'sample_no'          => $data['sample_no'] ?? null,
            'tests'              => $data['tests'] ?? null,
            'clc_appointment_id' => $data['clc_appointment_id'] ?? null,
        ]);

        return redirect()->route('clinic-lab.results', $patient->id)
            ->with('status', ['success' => 1, 'msg' => 'Lab order created — queued for the analyzer.']);
    }

    public function results($patientId, ClinicLabService $service)
    {
        $this->guard();
        $patient = $this->patient($patientId);
        $sessions = $service->resultsForPatient($patient);
        $orders = $service->ordersForPatient($patient);
        return view('clinicLab::results', compact('patient', 'sessions', 'orders'));
    }
}
