<?php

namespace App\Services\Care;

/**
 * Canonical Care → Ladill Queue department / specialty contexts.
 *
 * Mapping:
 * - Department/service → Queue ServiceQueue (+ Queue Department)
 * - Service point (room/desk/counter) → Queue Counter
 * - Staff assignment → Counter staff_ref / staff_display_name
 */
class CareQueueContexts
{
    public const RECEPTION = 'reception';

    public const TRIAGE = 'triage';

    public const CONSULTATION = 'consultation';

    public const PHARMACY = 'pharmacy';

    public const LABORATORY = 'laboratory';

    public const BILLING = 'billing';

    public const IMAGING = 'imaging';

    public const ROUTING_ROUTED = 'routed';

    public const ROUTING_UNRESOLVED = 'unresolved';

    /**
     * Core department queues provisioned for every branch when Queue integration is on.
     * Consultation/triage stay assigned_only (doctor/nurse-specific).
     * Pharmacy/lab/billing/imaging use a shared FIFO pool claimed by each counter on Call next.
     *
     * @return array<string, array{name: string, prefix: string, routing_mode: string, type: string}>
     */
    public static function departments(): array
    {
        return [
            self::RECEPTION => [
                'name' => 'Reception',
                'prefix' => 'R',
                'routing_mode' => 'shared_pool',
                'type' => 'reception',
            ],
            self::TRIAGE => [
                'name' => 'Triage',
                'prefix' => 'T',
                'routing_mode' => 'assigned_only',
                'type' => 'consultation',
            ],
            self::CONSULTATION => [
                'name' => 'Consultation',
                'prefix' => 'C',
                'routing_mode' => 'assigned_only',
                'type' => 'consultation',
            ],
            self::PHARMACY => [
                'name' => 'Pharmacy',
                'prefix' => 'P',
                // Shared FIFO pool — any pharmacist counter claims the next waiting ticket.
                'routing_mode' => 'shared_pool',
                'type' => 'pharmacy',
            ],
            self::LABORATORY => [
                'name' => 'Laboratory',
                'prefix' => 'L',
                'routing_mode' => 'shared_pool',
                'type' => 'laboratory',
            ],
            self::BILLING => [
                'name' => 'Billing',
                'prefix' => 'B',
                'routing_mode' => 'shared_pool',
                'type' => 'cashier',
            ],
            self::IMAGING => [
                'name' => 'Imaging',
                'prefix' => 'I',
                'routing_mode' => 'shared_pool',
                'type' => 'laboratory',
            ],
        ];
    }

    public static function isDepartment(string $context): bool
    {
        return array_key_exists($context, self::departments());
    }

    public static function isSpecialty(string $context): bool
    {
        return array_key_exists($context, config('care.specialty_modules', []));
    }

    public static function usesAssignedRouting(string $context): bool
    {
        if (self::isSpecialty($context)) {
            return true;
        }

        return (self::departments()[$context]['routing_mode'] ?? 'shared_pool') === 'assigned_only';
    }

    public static function queueExternalKey(string $context, int|string $careBranchId): string
    {
        if (self::isSpecialty($context)) {
            return "care:specialty:{$context}:queue:{$careBranchId}";
        }

        return "care:dept:{$context}:queue:{$careBranchId}";
    }

    public static function departmentExternalKey(string $context, int|string $careBranchId): string
    {
        return "care:dept:{$context}:branch:{$careBranchId}";
    }

    /** @deprecated Prefer pointExternalKey — kept for legacy single-counter stubs. */
    public static function counterExternalKey(string $context, int|string $careBranchId): string
    {
        if (self::isSpecialty($context)) {
            return "care:specialty:{$context}:counter:{$careBranchId}";
        }

        return "care:dept:{$context}:counter:{$careBranchId}";
    }

    public static function pointExternalKey(
        string $context,
        int|string $careBranchId,
        string $pointKind,
        int|string $pointId,
    ): string {
        return "care:point:{$context}:{$pointKind}:{$careBranchId}:{$pointId}";
    }
}
