<?php

namespace Modules\ClinicCore\Http\Controllers;

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

/**
 * Item #4a — admin CRUD for the body-system finding catalogues.
 *
 *   GET    /clinic/system-findings                      - landing (list keys + counts)
 *   GET    /clinic/system-findings/{system_key}         - list findings for a system
 *   GET    /clinic/system-findings/{system_key}/create  - new finding form
 *   POST   /clinic/system-findings                      - store
 *   GET    /clinic/system-findings/edit/{id}            - edit form
 *   POST   /clinic/system-findings/edit/{id}            - update
 *   DELETE /clinic/system-findings/{id}                 - delete (business-owned)
 *
 *   GET    /clinic/system-findings/catalogue/{system_key}.json
 *          - public JSON consumed by the appointment Objective panel
 *
 * System-default rows (business_id NULL) are read-only.
 */
class ClcSystemFindingController extends Controller
{
    private const KNOWN_KEYS = [
        'heart','lungs','eyes','ears','nose_throat','mouth_teeth_gums',
        'abdomen','musculoskeletal','skin_hair_coat','neurological',
    ];

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

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

    /** Public-ish JSON: the appointment page hits this. Read-only. */
    public function catalogue($systemKey)
    {
        $rows = ClcSystemFinding::catalogueFor($this->bizId(), $systemKey);
        return response()->json(['success' => true, 'system_key' => $systemKey, 'items' => $rows]);
    }

    /** Landing page lists every system_key with counts. */
    public function index()
    {
        $this->guard();
        $counts = [];
        foreach (self::KNOWN_KEYS as $k) {
            $counts[$k] = [
                'system' => ClcSystemFinding::whereNull('business_id')->where('system_key', $k)->where('status','active')->count(),
                'biz'    => ClcSystemFinding::where('business_id', $this->bizId())->where('system_key', $k)->where('status','active')->count(),
            ];
        }
        return view('clinicCore::system-findings.index', compact('counts'));
    }

    /** List findings for one system_key, system rows + biz overrides side-by-side. */
    public function list($systemKey)
    {
        $this->guard();
        if (!in_array($systemKey, self::KNOWN_KEYS, true)) abort(404);
        $rows = ClcSystemFinding::forBusiness($this->bizId())
            ->where('system_key', $systemKey)
            ->orderBy('sort_order')->orderBy('label')->get();
        return view('clinicCore::system-findings.list', compact('rows', 'systemKey'));
    }

    public function create($systemKey)
    {
        $this->guard();
        if (!in_array($systemKey, self::KNOWN_KEYS, true)) abort(404);
        $row = new ClcSystemFinding(['system_key' => $systemKey, 'status' => 'active', 'sort_order' => 99]);
        return view('clinicCore::system-findings.edit', compact('row'));
    }

    public function store(Request $request)
    {
        $this->guard();
        $data = $this->validated($request);
        $data['business_id'] = $this->bizId();
        ClcSystemFinding::create($data);
        return redirect()->route('clinic.system-findings.list', $data['system_key'])
            ->with('status', ['success' => 1, 'msg' => 'Finding added.']);
    }

    public function edit($id)
    {
        $this->guard();
        $row = ClcSystemFinding::findOrFail($id);
        if ($row->business_id !== $this->bizId()) {
            abort(403, 'System defaults are read-only — create a business override (same value) instead.');
        }
        return view('clinicCore::system-findings.edit', compact('row'));
    }

    public function update(Request $request, $id)
    {
        $this->guard();
        $row = ClcSystemFinding::findOrFail($id);
        if ($row->business_id !== $this->bizId()) {
            abort(403, 'System defaults are read-only.');
        }
        $row->update($this->validated($request));
        return redirect()->route('clinic.system-findings.list', $row->system_key)
            ->with('status', ['success' => 1, 'msg' => 'Finding updated.']);
    }

    public function destroy($id)
    {
        $this->guard();
        $row = ClcSystemFinding::findOrFail($id);
        if ($row->business_id !== $this->bizId()) {
            abort(403, 'System defaults are read-only.');
        }
        $key = $row->system_key;
        $row->delete();
        return redirect()->route('clinic.system-findings.list', $key)
            ->with('status', ['success' => 1, 'msg' => 'Finding removed.']);
    }

    private function validated(Request $request): array
    {
        $request->validate([
            'system_key'        => 'required|in:' . implode(',', self::KNOWN_KEYS),
            'value'             => 'required|string|max:60',
            'label'             => 'required|string|max:160',
            'supports_severity' => 'nullable|boolean',
            'supports_lr'       => 'nullable|boolean',
            'is_critical'       => 'nullable|boolean',
            'sort_order'        => 'nullable|integer|min:0|max:999',
            'status'            => 'nullable|in:active,inactive',
        ]);
        return [
            'system_key'        => $request->system_key,
            'value'             => preg_replace('/[^a-z0-9_]/', '_', strtolower(trim($request->value))),
            'label'             => trim($request->label),
            'supports_severity' => $request->boolean('supports_severity'),
            'supports_lr'       => $request->boolean('supports_lr'),
            'is_critical'       => $request->boolean('is_critical'),
            'sort_order'        => (int) ($request->sort_order ?? 99),
            'status'            => $request->status ?: 'active',
        ];
    }
}
