<?php

namespace Modules\VetAdmission\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Carbon\Carbon;
use Modules\VetAdmission\Entities\VaAdmission;
use Modules\VetAdmission\Entities\VaAdmissionFluid;
use Modules\VetAdmission\Entities\VaFluidBagChange;

class VaFluidController extends Controller
{
    private function biz() { return request()->session()->get('user.business_id'); }

    private function canLog() {
        return auth()->user()->can('vet_admission.log_care')
            || auth()->user()->can('vet_admission.manage_admissions');
    }

    public function index(Request $request, $admissionId)
    {
        if (!$this->canLog()) abort(403);
        $admission = VaAdmission::forBusiness($this->biz())->findOrFail($admissionId);

        $fluids = VaAdmissionFluid::with('bagChanges')
            ->where('admission_id', $admission->id)
            ->orderByDesc('active')->orderByDesc('id')->get();

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

    public function store(Request $request, $admissionId)
    {
        if (!auth()->user()->can('vet_admission.manage_admissions')) abort(403);

        $request->validate([
            'fluid_type'      => 'required|string|max:80',
            'rate_ml_per_hr'  => 'required|numeric|gt:0',
            'rate_ml_per_kg_per_hr' => 'nullable|numeric|gt:0',
            'bag_size_ml'     => 'required|numeric|gt:0',
            'started_at'      => 'required|date',
            'notes'           => 'nullable|string|max:500',
        ]);

        $admission = VaAdmission::forBusiness($this->biz())->findOrFail($admissionId);

        $started = Carbon::parse($request->started_at);
        $hoursRun = (float) $request->bag_size_ml / (float) $request->rate_ml_per_hr;
        $estEnd = $started->copy()->addMinutes((int) round($hoursRun * 60));

        $fluid = VaAdmissionFluid::create([
            'admission_id'           => $admission->id,
            'fluid_type'             => $request->fluid_type,
            'rate_ml_per_hr'         => $request->rate_ml_per_hr,
            'rate_ml_per_kg_per_hr'  => $request->rate_ml_per_kg_per_hr,
            'bag_size_ml'            => $request->bag_size_ml,
            'started_at'             => $started,
            'estimated_end_at'       => $estEnd,
            'notes'                  => $request->notes,
            'active'                 => true,
            'created_by'             => auth()->id(),
        ]);

        return response()->json(['success' => true, 'msg' => 'Fluid started.', 'fluid_id' => $fluid->id]);
    }

    /** Record a bag change (or finishing the current bag). */
    public function changeBag(Request $request, $fluidId)
    {
        if (!$this->canLog()) abort(403);

        $request->validate([
            'new_bag_size_ml' => 'required|numeric|gt:0',
            'volume_consumed_ml' => 'nullable|numeric|gte:0',
            'notes' => 'nullable|string|max:500',
        ]);

        $fluid = VaAdmissionFluid::findOrFail($fluidId);
        $admission = VaAdmission::forBusiness($this->biz())->findOrFail($fluid->admission_id);

        $changedAt = now();
        $consumed = $request->volume_consumed_ml !== null
            ? (float) $request->volume_consumed_ml
            : (float) $fluid->bag_size_ml; // assume previous bag fully consumed

        VaFluidBagChange::create([
            'fluid_id'           => $fluid->id,
            'changed_at'         => $changedAt,
            'new_bag_size_ml'    => $request->new_bag_size_ml,
            'volume_consumed_ml' => $consumed,
            'given_by'           => auth()->id(),
            'notes'              => $request->notes,
        ]);

        $hoursRun = (float) $request->new_bag_size_ml / (float) $fluid->rate_ml_per_hr;

        $fluid->update([
            'bag_size_ml'             => $request->new_bag_size_ml,
            'started_at'              => $changedAt,
            'estimated_end_at'        => $changedAt->copy()->addMinutes((int) round($hoursRun * 60)),
            'total_volume_given_ml'   => (float) $fluid->total_volume_given_ml + $consumed,
        ]);

        return response()->json(['success' => true, 'msg' => 'Bag changed.']);
    }

    public function stop(Request $request, $fluidId)
    {
        if (!auth()->user()->can('vet_admission.manage_admissions')) abort(403);

        $fluid = VaAdmissionFluid::findOrFail($fluidId);
        $admission = VaAdmission::forBusiness($this->biz())->findOrFail($fluid->admission_id);

        $fluid->update(['active' => false, 'ended_at' => now()]);
        return response()->json(['success' => true, 'msg' => 'Fluid stopped.']);
    }
}
