<?php

namespace App\Support;

use App\Models\OrdenLavanderia;
use Carbon\CarbonInterface;

final class LaundrySemaphoreColorResolver
{
    /**
     * @return array{red: int, yellow: int}
     */
    public static function configDefaults(): array
    {
        return [
            'red' => max(0, (int) config('lavanderia.semaphore_hours_red', 2)),
            'yellow' => max(0, (int) config('lavanderia.semaphore_hours_yellow', 3)),
        ];
    }

    /**
     * Umbrales guardados en la orden (snapshot desde POS).
     *
     * @return array{red: int, yellow: int}
     */
    public static function thresholdsForOrder(OrdenLavanderia $orden): array
    {
        if ($orden->semaphore_hours_red !== null && $orden->semaphore_hours_yellow !== null) {
            return [
                'red' => (int) $orden->semaphore_hours_red,
                'yellow' => (int) $orden->semaphore_hours_yellow,
            ];
        }

        return self::configDefaults();
    }

    /**
     * Umbrales enviados desde POS al crear/actualizar orden.
     *
     * @param  array{semaphore_hours_red?: int|null, semaphore_hours_yellow?: int|null}  $data
     * @return array{red: int, yellow: int}
     */
    public static function resolveThresholdsForOrderPayload(array $data): array
    {
        $hasRed = array_key_exists('semaphore_hours_red', $data) && $data['semaphore_hours_red'] !== null && $data['semaphore_hours_red'] !== '';
        $hasYellow = array_key_exists('semaphore_hours_yellow', $data) && $data['semaphore_hours_yellow'] !== null && $data['semaphore_hours_yellow'] !== '';

        if ($hasRed && $hasYellow) {
            return [
                'red' => max(0, (int) $data['semaphore_hours_red']),
                'yellow' => max(0, (int) $data['semaphore_hours_yellow']),
            ];
        }

        return self::configDefaults();
    }

    public static function defaultFechaEntrega(?CarbonInterface $from = null): CarbonInterface
    {
        $base = $from ? $from->copy() : now();

        return $base->copy()->addDays((int) config('lavanderia.default_delivery_days', 3))->setTime(
            (int) config('lavanderia.default_delivery_hour', 20),
            0,
            0
        );
    }

    public static function promisedAt(OrdenLavanderia $orden): CarbonInterface
    {
        if ($orden->fecha_entrega !== null) {
            return $orden->fecha_entrega->copy()->timezone(config('app.timezone'));
        }

        return self::defaultFechaEntrega($orden->created_at);
    }

    /**
     * Texto de entrega para ticket/PDF: "SAB. 01/06/2026 18:30 Hrs"
     */
    public static function formatEntregaTicket(CarbonInterface $entrega): string
    {
        $e = $entrega->copy()->timezone(config('app.timezone'))->locale('es');

        return strtoupper($e->isoFormat('ddd')).' '.$e->format('d/m/Y H:i').' Hrs';
    }

    public static function resolveColor(OrdenLavanderia $orden, ?CarbonInterface $now = null): string
    {
        if ($orden->estatus === OrdenLavanderia::ESTATUS_TERMINADO
            || $orden->estatus === OrdenLavanderia::ESTATUS_ENTREGADO) {
            return 'verde';
        }

        $now = $now ?? now();
        $promised = self::promisedAt($orden);
        $hoursRemaining = $now->floatDiffInHours($promised, false);

        if ($hoursRemaining <= 0) {
            return 'rojo';
        }

        $thresholds = self::thresholdsForOrder($orden);
        $redHours = $thresholds['red'];
        $yellowHours = $thresholds['yellow'];

        if ($yellowHours < $redHours) {
            [$redHours, $yellowHours] = [$yellowHours, $redHours];
        }

        if ($hoursRemaining <= $redHours) {
            return 'rojo';
        }

        if ($hoursRemaining <= $yellowHours) {
            return 'amarillo';
        }

        return 'verde';
    }
}
