<?php

declare(strict_types=1);

namespace App\Enums;

use Filament\Support\Contracts\HasColor;
use Filament\Support\Contracts\HasLabel;

enum BookingStatus: string implements HasColor, HasLabel
{
    case PendingPayment = 'pending_payment';
    case PaymentSubmitted = 'payment_submitted';
    case Confirmed = 'confirmed';
    case Completed = 'completed';
    case Cancelled = 'cancelled';
    case Expired = 'expired';

    /**
     * Statuses that occupy a slot outright, with no further conditions.
     *
     * Pending payment is deliberately absent: it only holds a slot while its
     * hold_expires_at is still in the future, which is a per-row check rather
     * than a property of the status. See Booking::scopeLive().
     *
     * @return array<int, string>
     */
    public static function unconditionallyHolding(): array
    {
        return [
            self::PaymentSubmitted->value,
            self::Confirmed->value,
            self::Completed->value,
        ];
    }

    /** Nothing further can happen to a booking in one of these states. */
    public function isTerminal(): bool
    {
        return in_array($this, [self::Cancelled, self::Expired, self::Completed], true);
    }

    /** Statuses an admin needs to do something about. */
    public static function needingAttention(): array
    {
        return [
            self::PaymentSubmitted->value,
            self::PendingPayment->value,
        ];
    }

    public function getLabel(): string
    {
        return match ($this) {
            self::PendingPayment => 'Pending payment',
            self::PaymentSubmitted => 'Payment submitted',
            self::Confirmed => 'Confirmed',
            self::Completed => 'Completed',
            self::Cancelled => 'Cancelled',
            self::Expired => 'Expired',
        };
    }

    /**
     * Colour carries meaning here, so it is defined once rather than at each
     * call site: warning means the studio owes someone an action, success
     * means settled, danger means it fell through.
     */
    public function getColor(): string
    {
        return match ($this) {
            self::PendingPayment => 'warning',
            self::PaymentSubmitted => 'info',
            self::Confirmed => 'success',
            self::Completed => 'gray',
            self::Cancelled => 'danger',
            self::Expired => 'danger',
        };
    }
}
