<?php

namespace App\Services;

use App\Events\OrdenLavanderiaCreada;
use App\Events\OrdenLavanderiaTerminada;
use App\Models\OrdenLavanderia;
use App\Repositories\Contracts\OrdenLavanderiaRepositoryInterface;
use App\Services\ImpresionInstruccionesLavanderiaService;
use Illuminate\Support\Str;

class OrdenLavanderiaService
{
    public function __construct(
        private readonly OrdenLavanderiaRepositoryInterface $ordenes,
        private readonly ImpresionInstruccionesLavanderiaService $impresionInstrucciones
    ) {
    }

    public function crearOrden(array $data): OrdenLavanderia
    {
        $folioUnico = $this->generarFolioUnico();

        $payload = array_merge($data, [
            'folio_unico' => $folioUnico,
            'codigo_qr' => $this->generarCodigoQR($folioUnico),
            'current_step' => OrdenLavanderia::STEP_RECEPCION,
            'current_step_started_at' => now(),
            'estatus' => OrdenLavanderia::ESTATUS_PENDIENTE,
        ]);

        $orden = $this->ordenes->create($payload);

        // Hook: detección de instrucciones especiales por área (para impresión automática)
        // Puedes conectar aquí la lógica concreta de impresión según $alertas.
        $alertas = $this->impresionInstrucciones->obtenerAlertasPorArea($orden);
        // Ejemplo:
        // if ($alertas['secado']) { $this->impresoraSecado->imprimirTicket($orden); }

        event(new OrdenLavanderiaCreada($orden));

        return $orden;
    }

    public function avanzarStep(OrdenLavanderia $orden): OrdenLavanderia
    {
        $nextStep = match ($orden->current_step) {
            OrdenLavanderia::STEP_RECEPCION => OrdenLavanderia::STEP_LAVADO,
            OrdenLavanderia::STEP_LAVADO => OrdenLavanderia::STEP_SECADO,
            OrdenLavanderia::STEP_SECADO => OrdenLavanderia::STEP_PLANCHADO,
            OrdenLavanderia::STEP_PLANCHADO => OrdenLavanderia::STEP_TERMINADO,
            default => $orden->current_step,
        };

        $updates = [
            'current_step' => $nextStep,
            'current_step_started_at' => now(),
        ];

        if ($nextStep === OrdenLavanderia::STEP_LAVADO && $orden->lavado_started_at === null) {
            $updates['lavado_started_at'] = now();
            $updates['estatus'] = OrdenLavanderia::ESTATUS_EN_PROCESO;
        } elseif ($nextStep === OrdenLavanderia::STEP_SECADO && $orden->secado_started_at === null) {
            $updates['secado_started_at'] = now();
        } elseif ($nextStep === OrdenLavanderia::STEP_PLANCHADO && $orden->planchado_started_at === null) {
            $updates['planchado_started_at'] = now();
        } elseif ($nextStep === OrdenLavanderia::STEP_TERMINADO && $orden->terminado_at === null) {
            $updates['terminado_at'] = now();
            $updates['estatus'] = OrdenLavanderia::ESTATUS_TERMINADO;
            event(new OrdenLavanderiaTerminada($orden));
        }

        return $this->ordenes->update($orden, $updates);
    }

    public function marcarEntregada(OrdenLavanderia $orden): OrdenLavanderia
    {
        return $this->ordenes->update($orden, [
            'current_step' => OrdenLavanderia::STEP_ENTREGADO,
            'current_step_started_at' => now(),
            'entregado_at' => now(),
            'estatus' => OrdenLavanderia::ESTATUS_ENTREGADO,
        ]);
    }

    private function generarFolioUnico(): string
    {
        do {
            $folio = 'LMS-'.date('Ymd').'-'.strtoupper(Str::random(6));
        } while ($this->ordenes->findByFolio($folio) !== null);

        return $folio;
    }

    private function generarCodigoQR(string $folioUnico): string
    {
        $qrData = [
            'folio' => $folioUnico,
            'timestamp' => now()->toIso8601String(),
        ];

        return base64_encode(json_encode($qrData));
    }
}

