<?php

namespace Modules\ClinicCore\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Modules\ClinicCore\Entities\ClcAppointment;
use Modules\ClinicCore\Entities\ClcClinicLocation;
use Modules\ClinicCore\Entities\ClcDoctor;

/**
 * SIFA P3-T7 — "Today's queue" daily flow board. No new table: it's a live view
 * over clc_appointments for today, per location / doctor, grouped into status
 * columns:
 *
 *   waiting     — pending / confirmed and NOT yet checked in
 *   in_queue    — checked in (check_in_time set) and confirmed / in_progress
 *   with_doctor — in_progress
 *   completed   — completed today
 *
 * Rows ordered by check_in_time then appointment_time. Buttons reuse the Wave B
 * check-in endpoint and the existing status endpoint (start = in_progress,
 * complete = completed). Gated by clinic.queue.view.
 */
class ClcQueueController extends Controller
{
    public function index(Request $request)
    {
        if (!auth()->user()->can('clinic.queue.view')) {
            abort(403, 'Unauthorized action.');
        }
        $businessId = $request->session()->get('user.business_id');

        $locations = ClcClinicLocation::where('business_id', $businessId)->active()->orderBy('name')->get(['id', 'name']);
        $doctors   = ClcDoctor::where('business_id', $businessId)->active()->orderBy('name')->get(['id', 'name']);

        return view('clinicCore::queue.index', compact('locations', 'doctors'));
    }

    /** JSON board data for today, grouped into flow columns. */
    public function board(Request $request)
    {
        if (!auth()->user()->can('clinic.queue.view')) {
            abort(403, 'Unauthorized action.');
        }
        $businessId = $request->session()->get('user.business_id');
        $today      = now()->toDateString();

        $query = ClcAppointment::with(['pet', 'doctor', 'department'])
            ->where('business_id', $businessId)
            ->whereDate('appointment_date', $today)
            ->whereNotIn('status', ['cancelled', 'no_show']);

        if ($request->filled('location_id')) {
            $query->where('location_id', $request->location_id);
        }
        if ($request->filled('doctor_id')) {
            $query->where('doctor_id', $request->doctor_id);
        }

        $appointments = $query
            ->orderByRaw('check_in_time IS NULL, check_in_time asc')
            ->orderBy('appointment_time')
            ->get();

        $columns = ['waiting' => [], 'in_queue' => [], 'with_doctor' => [], 'completed' => []];

        foreach ($appointments as $a) {
            $col = $this->columnFor($a);
            $columns[$col][] = [
                'id'            => $a->id,
                'ref_no'        => $a->ref_no,
                'patient'       => optional($a->pet)->patient_name,
                'doctor'        => optional($a->doctor)->name,
                'department'    => optional($a->department)->name,
                'time'          => $a->appointment_time ? substr((string) $a->appointment_time, 0, 5) : null,
                'checked_in_at' => $a->check_in_time ? $a->check_in_time->format('H:i') : null,
                'status'        => $a->status,
                'show_url'      => route('clinic.appointments.show', $a->id),
            ];
        }

        return response()->json([
            'columns' => $columns,
            'counts'  => [
                'waiting'     => count($columns['waiting']),
                'in_queue'    => count($columns['in_queue']),
                'with_doctor' => count($columns['with_doctor']),
                'completed'   => count($columns['completed']),
            ],
        ]);
    }

    /** Map an appointment to its flow column. */
    private function columnFor(ClcAppointment $a): string
    {
        if ($a->status === 'completed') {
            return 'completed';
        }
        if ($a->status === 'in_progress') {
            return 'with_doctor';
        }
        // Checked-in (check_in_time set) + still confirmed → in the queue.
        if ($a->check_in_time && in_array($a->status, ['confirmed', 'in_progress'], true)) {
            return 'in_queue';
        }
        // pending / confirmed and not yet checked in → waiting.
        return 'waiting';
    }
}
