<?php

namespace App\Services\Care;

use App\Models\Appointment;
use App\Models\CareQueueTicket;
use App\Models\Organization;
use App\Models\Visit;
use App\Services\Care\AuditLogger;
use App\Services\Care\Emergency\EmergencyWorkflowService;

/**
 * Persist specialty visit stages (dentistry chair → recovery) and re-route queue tickets.
 */
class SpecialtyVisitStageService
{
    public function __construct(
        protected SpecialtyShellService $shell,
        protected CareQueueBridge $queueBridge,
    ) {}

    /**
     * @return list<string>
     */
    public function allowedStages(string $moduleKey): array
    {
        return collect($this->shell->stages($moduleKey))
            ->pluck('code')
            ->filter()
            ->values()
            ->all();
    }

    public function setStage(
        Organization $organization,
        Visit $visit,
        string $moduleKey,
        string $stage,
        string $ownerRef,
        ?string $actorRef = null,
    ): Visit {
        $allowed = $this->allowedStages($moduleKey);
        if (! in_array($stage, $allowed, true)) {
            throw new \InvalidArgumentException("Invalid specialty stage [{$stage}] for {$moduleKey}.");
        }

        $previous = $visit->specialty_stage;
        $visit->update(['specialty_stage' => $stage]);

        if ($stage === 'completed' && $visit->status !== Visit::STATUS_COMPLETED) {
            $visit->update([
                'status' => Visit::STATUS_COMPLETED,
                'completed_at' => $visit->completed_at ?? now(),
            ]);
        } elseif ($stage !== 'completed' && $visit->status === Visit::STATUS_OPEN) {
            $visit->update(['status' => Visit::STATUS_IN_PROGRESS]);
        }

        $this->rerouteTicket($organization, $visit, $moduleKey, $stage);

        AuditLogger::record(
            $ownerRef,
            'specialty.visit.stage',
            $organization->id,
            $actorRef,
            Visit::class,
            $visit->id,
            ['module' => $moduleKey, 'from' => $previous, 'to' => $stage],
        );

        return $visit->fresh();
    }

    public function defaultOnCheckIn(string $moduleKey): ?string
    {
        $stages = $this->allowedStages($moduleKey);

        return $stages[0] ?? null;
    }

    public function stageOnConsultationStart(string $moduleKey): ?string
    {
        if ($moduleKey === 'emergency') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(EmergencyWorkflowService::STAGE_TREATMENT, $stages, true)
                ? EmergencyWorkflowService::STAGE_TREATMENT
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'blood_bank') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\BloodBank\BloodBankWorkflowService::STAGE_CROSSMATCH, $stages, true)
                ? \App\Services\Care\BloodBank\BloodBankWorkflowService::STAGE_CROSSMATCH
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'ophthalmology') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Ophthalmology\OphthalmologyWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Ophthalmology\OphthalmologyWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'physiotherapy') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Physiotherapy\PhysiotherapyWorkflowService::STAGE_ASSESSMENT, $stages, true)
                ? \App\Services\Care\Physiotherapy\PhysiotherapyWorkflowService::STAGE_ASSESSMENT
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'womens_health') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\WomensHealth\WomensHealthWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\WomensHealth\WomensHealthWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'radiology') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Radiology\RadiologyWorkflowService::STAGE_PROTOCOL, $stages, true)
                ? \App\Services\Care\Radiology\RadiologyWorkflowService::STAGE_PROTOCOL
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'cardiology') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Cardiology\CardiologyWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Cardiology\CardiologyWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'psychiatry') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Psychiatry\PsychiatryWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Psychiatry\PsychiatryWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'pediatrics') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Pediatrics\PediatricsWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Pediatrics\PediatricsWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'orthopedics') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Orthopedics\OrthopedicsWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Orthopedics\OrthopedicsWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'ent') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Ent\EntWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Ent\EntWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'dermatology') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Dermatology\DermatologyWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Dermatology\DermatologyWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'podiatry') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Podiatry\PodiatryWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Podiatry\PodiatryWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'fertility') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Fertility\FertilityWorkflowService::STAGE_HISTORY, $stages, true)
                ? \App\Services\Care\Fertility\FertilityWorkflowService::STAGE_HISTORY
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'child_welfare') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\ChildWelfare\ChildWelfareWorkflowService::STAGE_INTAKE, $stages, true)
                ? \App\Services\Care\ChildWelfare\ChildWelfareWorkflowService::STAGE_INTAKE
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        if ($moduleKey === 'ambulance') {
            $stages = $this->allowedStages($moduleKey);

            return in_array(\App\Services\Care\Ambulance\AmbulanceWorkflowService::STAGE_DISPATCH, $stages, true)
                ? \App\Services\Care\Ambulance\AmbulanceWorkflowService::STAGE_DISPATCH
                : ($stages[1] ?? ($stages[0] ?? null));
        }

        $stages = $this->allowedStages($moduleKey);
        foreach (['chair', 'in_care', 'exam', 'assessment', 'treatment'] as $preferred) {
            if (in_array($preferred, $stages, true)) {
                return $preferred;
            }
        }

        return $stages[1] ?? ($stages[0] ?? null);
    }

    protected function rerouteTicket(
        Organization $organization,
        Visit $visit,
        string $moduleKey,
        string $stage,
    ): void {
        if (! $this->queueBridge->isEnabled($organization)) {
            return;
        }

        $stageMeta = collect($this->shell->stages($moduleKey))
            ->first(fn ($s) => ($s['code'] ?? '') === $stage);
        $queuePoint = $stageMeta['queue_point'] ?? null;
        if (! $queuePoint) {
            return;
        }

        $appointment = $visit->appointment;
        if (! $appointment instanceof Appointment) {
            $appointment = Appointment::query()->where('visit_id', $visit->id)->first();
        }
        if (! $appointment?->queue_ticket_uuid) {
            return;
        }

        $ticket = CareQueueTicket::query()
            ->where('uuid', $appointment->queue_ticket_uuid)
            ->first();
        if (! $ticket) {
            return;
        }

        $stub = app(CareQueueProvisioner::class)->resourcesFor($organization, $moduleKey, (int) $visit->branch_id);
        $point = collect($stub['points'] ?? [])
            ->first(fn ($p) => ($p['kind'] ?? '') === 'stage' && ($p['stage'] ?? '') === $queuePoint);

        $ticket->update([
            'metadata' => array_merge($ticket->metadata ?? [], [
                'specialty_stage' => $stage,
                'queue_point' => $queuePoint,
                'point_external_key' => is_array($point) ? ($point['external_key'] ?? null) : null,
                'point_name' => is_array($point) ? ($point['name'] ?? null) : null,
            ]),
        ]);
    }
}
