<?php

namespace App\Support;

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

/**
 * Bloque de observaciones del ticket térmico (C4), alineado a base.md / C0:
 * agrupa por tipo de prenda; instrucciones y detalle de ropa van aparte.
 *
 * Paridad obligatoria con resources/js/src/utils/ticketPosPdf.js
 * (constante TICKET_TITLE_OBSERVACIONES_POR_PRENDA + buildGarmentObservationSections + buildGeneralObservationLines).
 */
class TicketObservationLines
{
    /** Título del bloque dedicado en ticket (PDF cliente y servidor). */
    public const TITLE_OBSERVACIONES_POR_PRENDA = 'Observaciones por tipo de prenda';

    /**
     * @param  Collection<int, \App\Models\OrdenLavanderiaDetalle>|iterable  $detalles
     * @return array{
     *     garment_sections: list<array{title: string, lines: list<string>}>,
     *     general_lines: list<array{label: string, text: string}>
     * }
     */
    public static function forOrder(OrdenLavanderia $orden, iterable $detalles): array
    {
        $sections = [];
        $titleToIndex = [];

        foreach ($detalles as $d) {
            if ((bool) ($d->is_informational ?? false)) {
                continue;
            }

            $obs = $d->observations ?? null;
            if ($obs === null || trim((string) $obs) === '') {
                continue;
            }

            // Solo leer relaciones ya cargadas: en tests unitarios (sin app) el lazy-load
            // de laundrySaleProduct dispararía el contenedor (p. ej. DB/config).
            $laundrySaleName = $d->relationLoaded('laundrySaleProduct')
                ? $d->getRelation('laundrySaleProduct')?->name
                : null;

            $title = $d->garmentType?->name
                ?? $laundrySaleName
                ?? $d->producto?->nombre
                ?? $d->etapa?->name
                ?? 'Ítem';

            if (! array_key_exists($title, $titleToIndex)) {
                $titleToIndex[$title] = count($sections);
                $sections[] = ['title' => $title, 'lines' => []];
            }

            $sections[$titleToIndex[$title]]['lines'][] = trim((string) $obs);
        }

        $generalLines = [];
        if (! empty($orden->instrucciones) && trim((string) $orden->instrucciones) !== '') {
            $generalLines[] = [
                'label' => 'Instrucciones',
                'text' => trim((string) $orden->instrucciones),
            ];
        }
        $detallesRopa = trim((string) ($orden->detalles_ropa ?? ''));
        if ($detallesRopa !== '' && ! self::isPlaceholderDetallesRopa($detallesRopa)) {
            $generalLines[] = [
                'label' => 'Ropa / detalle',
                'text' => $detallesRopa,
            ];
        }

        return [
            'garment_sections' => $sections,
            'general_lines' => $generalLines,
        ];
    }

    public static function hasAny(array $payload): bool
    {
        return $payload['garment_sections'] !== [] || $payload['general_lines'] !== [];
    }

    public static function isPlaceholderDetallesRopa(string $text): bool
    {
        return (bool) preg_match('/^ver detalle en ítems$/iu', trim($text));
    }
}
