<?php

namespace App\Enums;

enum OrderStatus: string
{
    case Ingresado = 'Ingresado';
    case Preparando = 'Preparando';
    case Empacado = 'Empacado';
    case ListoParaEnviar = 'Listo para enviar';
    case ListoParaUber = 'Listo para el Uber';
    case ListoParaRetirar = 'Listo para retirar';
    case EntregadoAlTransporte ='Entregado al transporte';
    case EntregadoAlCliente = 'Entregado al cliente';
    case Cancelado = 'Cancelado';
    case OnHold = 'on_hold';
    case Redespacho = 'redespacho';
    case EntregadoParcial = 'Entregado Parcial';
    case DespachoMulticanal = 'Despacho Multicanal';

    public function label(): string
    {
        return match ($this) {
            self::Ingresado => 'Ingresado',
            self::Preparando => 'Preparando',
            self::Empacado => 'Empacado',
            self::ListoParaEnviar => 'Listo para enviar',
            self::ListoParaUber => 'Listo para el Uber',
            self::ListoParaRetirar => 'Listo para retirar',
            self::EntregadoAlTransporte => 'Entregado al transporte',
            self::EntregadoAlCliente => 'Entregado al cliente',
            self::EntregadoParcial => 'Entregado Parcial',
            self::DespachoMulticanal => 'Despacho Multicanal',
            self::Cancelado => 'Cancelado',
            self::OnHold => 'On Hold',
            self::Redespacho => 'Redespacho',
        };
    }

    public function filamentColor(): string
    {
        return match ($this) {
            self::Ingresado => 'gray',
            self::Preparando => 'warning',
            self::Empacado => 'info',
            self::ListoParaEnviar => 'primary',
            self::ListoParaUber => 'primary',
            self::EntregadoAlTransporte => 'primary',
            self::ListoParaRetirar => 'warning',
            self::EntregadoAlCliente => 'success',
            self::EntregadoParcial => 'success',
            self::DespachoMulticanal => 'info',
            self::Cancelado => 'danger',
            self::OnHold => 'danger',
            self::Redespacho => 'info',
        };
    }

    public function definition(): string
    {
        return match ($this) {
            self::Ingresado => 'Orden recibida/creada y lista para iniciar el alistamiento.',
            self::Preparando => 'En alistamiento: picking en proceso.',
            self::Empacado => 'Empacado: productos listos; pendiente envío o retiro.',
            self::ListoParaEnviar => 'Picking completado: listo para despacho.',
            self::ListoParaUber => 'Picking completado: listo para coordinar envío por Uber.',
            self::EntregadoAlTransporte => 'Entregado al transporte/carrier para distribución.',
            self::ListoParaRetirar => 'Listo para retirar en tienda: cliente notificado.',
            self::EntregadoAlCliente => 'Entregado al cliente (cierre del flujo).',
            self::EntregadoParcial => 'Entregado parcial: la orden fue entregada parcialmente y requiere seguimiento.',
            self::DespachoMulticanal => 'Despacho multicanal: la orden se distribuye o gestiona en más de un canal logístico.',
            self::Cancelado => 'Cancelado: no debe continuar el flujo.',
            self::OnHold => 'On Hold: pendiente de validación/acción antes de procesar.',
            self::Redespacho => 'Redespacho: orden derivada de una orden original.',
        };
    }

    public function isHiddenInStatusSelectors(): bool
    {
        return match ($this) {
            self::EntregadoParcial, self::DespachoMulticanal, self::ListoParaUber => true,
            default => false,
        };
    }

    /** @return array<int, string> */
    public static function hiddenSelectorValues(): array
    {
        return array_values(array_map(
            fn (self $case): string => $case->value,
            array_filter(self::cases(), fn (self $case): bool => $case->isHiddenInStatusSelectors())
        ));
    }

    /** @return array<string, string> */
    public static function options(): array
    {
        $options = [];
        foreach (self::cases() as $case) {
            $options[$case->value] = $case->label();
        }

        return $options;
    }

    /** @return array<string, string> */
    public static function visibleOptions(): array
    {
        $options = [];

        foreach (self::cases() as $case) {
            if ($case->isHiddenInStatusSelectors()) {
                continue;
            }

            $options[$case->value] = $case->label();
        }

        return $options;
    }
}
