<?php

namespace App\Support;

use App\Models\OrdenLavanderiaDetalle;
use Illuminate\Support\Collection;

/**
 * Partición de líneas de orden para el ticket térmico estilo Tibu (cargas mínimas vs servicios generales).
 */
final class TicketThermalSections
{
    /**
     * @param  iterable<int, OrdenLavanderiaDetalle>  $detalles
     * @return array{cargas: Collection<int, OrdenLavanderiaDetalle>, servicios: Collection<int, OrdenLavanderiaDetalle>}
     */
    public static function partition(iterable $detalles): array
    {
        $chargeable = collect($detalles)->reject(fn (OrdenLavanderiaDetalle $d): bool => (bool) $d->is_informational);

        $c = $chargeable->filter(function (OrdenLavanderiaDetalle $d): bool {
            return ($d->billing_mode ?? '') === OrdenLavanderiaDetalle::BILLING_BY_WEIGHT;
        })->values();

        $s = $chargeable->filter(function (OrdenLavanderiaDetalle $d): bool {
            return ($d->billing_mode ?? '') !== OrdenLavanderiaDetalle::BILLING_BY_WEIGHT;
        })->values();

        $contenido = collect($detalles)->filter(fn (OrdenLavanderiaDetalle $d): bool => (bool) $d->is_informational)->values();

        return ['cargas' => $c, 'tipos_servicio' => $s, 'contenido' => $contenido];
    }

    public static function lineConcepto(OrdenLavanderiaDetalle $d): string
    {
        if ($d->is_informational) {
            $product = $d->laundrySaleProduct?->name ?? '';
            $garment = $d->garmentType?->name ?? '';
            $qty = number_format((float) $d->cantidad, 0);
            $base = trim($product.' → '.$garment);
            if ($base === '→' || $base === '') {
                return 'Contenido';
            }

            return $base.' x'.$qty;
        }

        if ($d->producto !== null && $d->producto->nombre !== '') {
            return (string) $d->producto->nombre;
        }
        if ($d->laundrySaleProduct !== null && $d->laundrySaleProduct->name !== '') {
            $name = (string) $d->laundrySaleProduct->name;
            $extra = (float) ($d->extra_cost ?? 0);
            if ($extra > 0) {
                return $name.' (+ $'.number_format($extra, 2).' extra)';
            }

            return $name;
        }
        $parts = array_filter([
            $d->garmentType?->name,
            $d->etapa?->name,
            $d->loadType?->name,
        ]);

        return $parts !== [] ? implode(' · ', $parts) : 'Ítem';
    }

    /**
     * Líneas secundarias bajo la primera fila de cargas (texto libre de la orden).
     *
     * @return list<string>
     */
    public static function detalleRopaSublines(?string $detallesRopa): array
    {
        $raw = trim((string) ($detallesRopa ?? ''));
        if ($raw === '') {
            return [];
        }

        return collect(preg_split("/\r\n|\n|\r/", $raw))
            ->map(fn (string $l) => trim($l))
            ->filter(fn (string $l) => $l !== '')
            ->values()
            ->all();
    }

    public static function sectionSubtotal(Collection $rows): float
    {
        return round((float) $rows->sum(fn (OrdenLavanderiaDetalle $d) => (float) $d->subtotal), 2);
    }
}
