<?php

namespace Modules\MedWard\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

/**
 * Shared helpers for the MedWard back-office controllers: business scoping,
 * permission guards, the standard JSON response envelope and a fail-soft patient
 * name resolver. Mirrors Modules\MedBilling\Http\Controllers\MedBillingBaseController.
 */
abstract class MedWardBaseController extends Controller
{
    protected function businessId(): int
    {
        return (int) request()->session()->get('user.business_id');
    }

    protected function userId(): ?int
    {
        return request()->session()->get('user.id');
    }

    protected function guard(string $permission): void
    {
        if (! auth()->user()->can($permission)) {
            abort(403, 'Unauthorized action.');
        }
    }

    protected function ok(string $msg, array $extra = []): array
    {
        return array_merge(['success' => true, 'msg' => $msg], $extra);
    }

    protected function fail(?string $msg = null): array
    {
        return ['success' => false, 'msg' => $msg ?: __('messages.something_went_wrong')];
    }

    /**
     * Resolve a display name for a ClinicCore patient, fail-soft. Prefers the
     * linked ERP contact name, falling back to clc_patients.patient_name and then
     * a synthetic "Patient #id". Never throws if ClinicCore is absent.
     */
    protected function patientName(int $patientId): string
    {
        try {
            if ($patientId <= 0 || ! Schema::hasTable('clc_patients')) {
                return 'Patient #' . $patientId;
            }
            $row = DB::table('clc_patients')
                ->leftJoin('contacts', 'clc_patients.contact_id', '=', 'contacts.id')
                ->where('clc_patients.id', $patientId)
                ->first(['contacts.name as contact_name', 'clc_patients.patient_name']);

            $name = $row->contact_name ?? $row->patient_name ?? null;

            return $name ?: ('Patient #' . $patientId);
        } catch (\Throwable $e) {
            return 'Patient #' . $patientId;
        }
    }
}
