<?php

namespace Modules\ClinicCore\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\ClinicCore\Entities\ClcVitalRange;

/**
 * Item #1 — admin UI for the reference ranges that drive vital-sign
 * critical flagging (item 1.3) and the Medical Critical Check report
 * (item 4.1).
 *
 *   GET    /clinic/vital-ranges                   - list (system + business)
 *   GET    /clinic/vital-ranges/create            - create form
 *   POST   /clinic/vital-ranges                   - store (business-scoped row)
 *   GET    /clinic/vital-ranges/{id}/edit         - edit form
 *   POST   /clinic/vital-ranges/{id}              - update
 *   DELETE /clinic/vital-ranges/{id}              - delete (business-owned only)
 *
 * System rows (business_id = null) are read-only; clinics override by
 * inserting a business-scoped row for the same species+life_stage.
 */
class ClcVitalRangeController extends Controller
{
    private function bizId(): int
    {
        return (int) request()->session()->get('user.business_id');
    }

    private function guard(): void
    {
        if (!auth()->user()->can('clinic.view_reports')
            && !auth()->user()->can('clinic.manage_appointments')) {
            abort(403, 'Not authorised.');
        }
    }

    private function guardManage(): void
    {
        if (!auth()->user()->can('clinic.manage_pets')
            && !auth()->user()->can('clinic.view_reports')) {
            abort(403, 'Not authorised to manage vital ranges.');
        }
    }

    public function index()
    {
        $this->guard();
        // Show every system-default range + every range this business owns.
        // Sort: species first, then a stable life-stage order so the list
        // reads consistently.
        $stageOrder = ['pediatric' => 1, 'adult' => 2, 'senior' => 3, 'all' => 4];
        $rows = ClcVitalRange::query()
            ->where(function ($q) {
                $q->whereNull('business_id')->orWhere('business_id', $this->bizId());
            })
            ->orderBy('species')->orderBy('life_stage')->get()
            ->sortBy(function ($r) use ($stageOrder) {
                return $r->species . '|' . str_pad((string) ($stageOrder[$r->life_stage] ?? 99), 2, '0', STR_PAD_LEFT);
            })
            ->values();
        $bizId = $this->bizId();
        return view('clinicCore::vital-ranges.index', compact('rows', 'bizId'));
    }

    public function create()
    {
        $this->guardManage();
        $row = new ClcVitalRange(['life_stage' => 'all']);
        return view('clinicCore::vital-ranges.edit', compact('row'));
    }

    public function store(Request $request)
    {
        $this->guardManage();
        $data = $this->validated($request);
        $data['business_id'] = $this->bizId();
        ClcVitalRange::create($data);
        return redirect()->route('clinic.vital-ranges.index')
            ->with('status', ['success' => 1, 'msg' => 'Reference range saved.']);
    }

    public function edit($id)
    {
        $this->guardManage();
        $row = ClcVitalRange::findOrFail($id);
        if ($row->business_id !== $this->bizId()) {
            abort(403, 'System-default ranges are read-only; create a business override instead.');
        }
        return view('clinicCore::vital-ranges.edit', compact('row'));
    }

    public function update(Request $request, $id)
    {
        $this->guardManage();
        $row = ClcVitalRange::findOrFail($id);
        if ($row->business_id !== $this->bizId()) {
            abort(403, 'System-default ranges are read-only.');
        }
        $row->update($this->validated($request));
        return redirect()->route('clinic.vital-ranges.index')
            ->with('status', ['success' => 1, 'msg' => 'Reference range updated.']);
    }

    public function destroy($id)
    {
        $this->guardManage();
        $row = ClcVitalRange::findOrFail($id);
        if ($row->business_id !== $this->bizId()) {
            abort(403, 'System-default ranges are read-only.');
        }
        $row->delete();
        return back()->with('status', ['success' => 1, 'msg' => 'Reference range removed.']);
    }

    private function validated(Request $request): array
    {
        $request->validate([
            'species'               => 'required|string|max:40',
            'life_stage'            => 'required|in:pediatric,adult,senior,all',
            'temperature_low'       => 'nullable|numeric|min:0|max:50',
            'temperature_high'      => 'nullable|numeric|min:0|max:50',
            'heart_rate_low'        => 'nullable|integer|min:0|max:600',
            'heart_rate_high'       => 'nullable|integer|min:0|max:600',
            'respiratory_rate_low'  => 'nullable|integer|min:0|max:200',
            'respiratory_rate_high' => 'nullable|integer|min:0|max:200',
            'weight_low_kg'         => 'nullable|numeric|min:0|max:9999',
            'weight_high_kg'        => 'nullable|numeric|min:0|max:9999',
        ]);
        // Normalise species via the alias map so "Dog" / "dog" / "canine"
        // all canonicalise to the same key the resolver looks for.
        return [
            'species'               => ClcVitalRange::normaliseSpecies($request->species),
            'life_stage'            => $request->life_stage,
            'temperature_low'       => $request->temperature_low,
            'temperature_high'      => $request->temperature_high,
            'heart_rate_low'        => $request->heart_rate_low,
            'heart_rate_high'       => $request->heart_rate_high,
            'respiratory_rate_low'  => $request->respiratory_rate_low,
            'respiratory_rate_high' => $request->respiratory_rate_high,
            'weight_low_kg'         => $request->weight_low_kg,
            'weight_high_kg'        => $request->weight_high_kg,
        ];
    }
}
