<?php

namespace App\Services\Care\BloodBank;

/**
 * Map blood request / issue payloads onto Blood Bank visit stages.
 */
class BloodBankWorkflowService
{
    public const STAGE_REQUEST = 'request';

    public const STAGE_CROSSMATCH = 'crossmatch';

    public const STAGE_ISSUE = 'issue';

    public const STAGE_TRANSFUSION = 'transfusion';

    public const STAGE_COMPLETED = 'completed';

    /**
     * Suggested next visit stage after a blood request payload is saved.
     *
     * @param  array<string, mixed>  $payload
     */
    public function stageFromRequest(array $payload): string
    {
        $crossmatch = strtolower((string) ($payload['crossmatch_status'] ?? ''));
        $issued = (int) ($payload['issued_units'] ?? 0);
        $urgency = strtolower((string) ($payload['urgency'] ?? ''));

        if ($issued > 0 || $crossmatch === 'issued') {
            return self::STAGE_ISSUE;
        }

        if (in_array($crossmatch, ['compatible', 'incompatible', 'in progress'], true)) {
            return self::STAGE_CROSSMATCH;
        }

        if (str_contains($urgency, 'emergency') || str_contains($urgency, 'massive')) {
            return self::STAGE_CROSSMATCH;
        }

        return self::STAGE_REQUEST;
    }

    /**
     * Whether a transfusion payload should close the visit episode.
     *
     * @param  array<string, mixed>  $payload
     */
    public function shouldCompleteVisit(array $payload): bool
    {
        $outcome = strtolower((string) ($payload['outcome'] ?? ''));

        return $outcome !== '' && (
            str_contains($outcome, 'completed')
            || str_contains($outcome, 'stopped')
            || str_contains($outcome, 'complete')
        );
    }

    /**
     * Map product label to catalog service code for billing.
     */
    public function serviceCodeForProduct(?string $product): ?string
    {
        $normalized = strtolower(trim((string) $product));

        return match (true) {
            str_contains($normalized, 'whole') => 'bb.whole_blood',
            str_contains($normalized, 'packed') || str_contains($normalized, 'rbc') => 'bb.packed_rbc',
            str_contains($normalized, 'platelet') => 'bb.platelets',
            str_contains($normalized, 'ffp') || str_contains($normalized, 'plasma') => 'bb.ffp',
            str_contains($normalized, 'cryo') => 'bb.cryo',
            default => null,
        };
    }

    /**
     * Default stage progression for action buttons.
     *
     * @return array<string, array{next: string, label: string}>
     */
    public function stageFlow(): array
    {
        return [
            self::STAGE_REQUEST => ['next' => self::STAGE_CROSSMATCH, 'label' => 'Start cross-match'],
            self::STAGE_CROSSMATCH => ['next' => self::STAGE_ISSUE, 'label' => 'Ready to issue'],
            self::STAGE_ISSUE => ['next' => self::STAGE_TRANSFUSION, 'label' => 'Start transfusion'],
            self::STAGE_TRANSFUSION => ['next' => self::STAGE_COMPLETED, 'label' => 'Complete visit'],
            self::STAGE_COMPLETED => ['next' => self::STAGE_COMPLETED, 'label' => 'Completed'],
        ];
    }
}
