<?php

namespace Modules\MedWard\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\MedWard\Entities\MedwardAdmission;
use Modules\MedWard\Services\IcuService;

/**
 * ICU dashboard + flow-sheet charting (SIFA P6-T5). The dashboard shows a strip
 * per active ICU admission: latest flow-sheet vitals + any active critical alerts
 * (read fail-soft from ClinicCore clc_medical_alerts). Charting runs through
 * IcuService (auto MAP + critical-value alerts). Guarded by medward.icu.chart /
 * medward.board.view.
 */
class IcuController extends MedWardBaseController
{
    public function index()
    {
        $this->guard('medward.board.view');
        $businessId = $this->businessId();

        $admissions = MedwardAdmission::forBusiness($businessId)->icu()->active()
            ->with(['ward', 'bed'])
            ->orderByDesc('admitted_at')
            ->get();

        $strips = $admissions->map(function ($adm) use ($businessId) {
            $latest = $adm->flowsheets()->orderByDesc('recorded_at')->first();

            return [
                'admission'    => $adm,
                'patient_name' => $this->patientName((int) $adm->patient_id),
                'latest'       => $latest,
                'alerts'       => $this->activeCriticalAlerts($businessId, (int) $adm->patient_id),
            ];
        });

        return view('medward::icu.index', [
            'strips'         => $strips,
            'refreshSeconds' => (int) config('medward.board_refresh_seconds', 30),
        ]);
    }

    /** Chart a new ICU flow-sheet row for an ICU admission. */
    public function chart(Request $request, $id, IcuService $service)
    {
        $this->guard('medward.icu.chart');

        $admission = MedwardAdmission::forBusiness($this->businessId())->icu()->findOrFail($id);

        $data = $this->validate($request, [
            'gcs_total'     => 'nullable|integer|min:3|max:15',
            'rass'          => 'nullable|integer|min:-5|max:4',
            'pupils'        => 'nullable|string|max:100',
            'hr'            => 'nullable|integer|min:0|max:400',
            'bp_sys'        => 'nullable|integer|min:0|max:400',
            'bp_dia'        => 'nullable|integer|min:0|max:300',
            'spo2'          => 'nullable|numeric|min:0|max:100',
            'rr'            => 'nullable|integer|min:0|max:120',
            'temp'          => 'nullable|numeric|min:20|max:45',
            'fio2'          => 'nullable|numeric|min:21|max:100',
            'peep'          => 'nullable|numeric|min:0|max:40',
            'tidal_volume'  => 'nullable|numeric|min:0|max:2000',
            'interventions' => 'nullable|string',
            'labs_note'     => 'nullable|string',
            'vasoactives'   => 'nullable|array',
            'drains'        => 'nullable|array',
        ]);

        try {
            $flowsheet = $service->chart($admission, array_merge($data, [
                'recorded_by' => $this->userId(),
                'recorded_at' => now(),
            ]));

            return $this->ok(__('medward::lang.flowsheet_saved'), [
                'map'  => $flowsheet->map_calc,
            ]);
        } catch (\Exception $e) {
            \Log::emergency($e->getMessage());

            return $this->fail();
        }
    }

    /**
     * Active critical alerts for a patient (fail-soft read of ClinicCore
     * clc_medical_alerts). Returns a plain array of {title, details}.
     */
    private function activeCriticalAlerts(int $businessId, int $patientId): array
    {
        try {
            if (! Schema::hasTable('clc_medical_alerts')) {
                return [];
            }

            return DB::table('clc_medical_alerts')
                ->where('business_id', $businessId)
                ->where('patient_id', $patientId)
                ->where('is_active', true)
                ->where('severity', 'critical')
                ->orderByDesc('created_at')
                ->limit(5)
                ->get(['title', 'details'])
                ->map(fn ($a) => ['title' => $a->title, 'details' => $a->details])
                ->toArray();
        } catch (\Throwable $e) {
            return [];
        }
    }
}
