<?php

namespace App\Http\Controllers;

use App\Models\OrdenLavanderia;
use App\Repositories\Contracts\OrdenLavanderiaRepositoryInterface;
use App\Services\OrdenLavanderiaService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class OrdenLavanderiaController extends Controller
{
    public function __construct(
        private readonly OrdenLavanderiaService $service,
        private readonly OrdenLavanderiaRepositoryInterface $ordenes
    ) {
    }

    public function index(Request $request): JsonResponse
    {
        $perPage = (int) $request->get('per_page', 20);
        $filters = $request->only([
            'estatus',
            'current_step',
            'cliente_nombre',
            'folio_unico',
            'is_priority',
        ]);

        $result = $this->ordenes->paginate($filters, $perPage);

        return response()->json([
            'data' => $result,
        ], JsonResponse::HTTP_OK);
    }

    public function store(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'cliente_nombre' => ['required', 'string', 'max:255'],
            'cliente_email' => ['nullable', 'email', 'max:255'],
            'tipo_servicio' => ['required', 'string', 'max:150'],
            'detalles_ropa' => ['required', 'string'],
            'instrucciones' => ['nullable', 'string'],
            'total' => ['required', 'numeric', 'min:0'],
            'is_priority' => ['sometimes', 'boolean'],
        ]);

        if ($validator->fails()) {
            return response()->json([
                'errors' => $validator->errors(),
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        $orden = $this->service->crearOrden($validator->validated());

        // Aquí podrías disparar la impresión física de tickets (cliente e interno)
        // a través de un servicio de impresión especializado.

        return response()->json([
            'data' => $orden,
        ], JsonResponse::HTTP_CREATED);
    }

    public function show(OrdenLavanderia $orden): JsonResponse
    {
        return response()->json([
            'data' => $orden,
        ], JsonResponse::HTTP_OK);
    }

    public function avanzar(OrdenLavanderia $orden): JsonResponse
    {
        $ordenActualizada = $this->service->avanzarStep($orden);

        return response()->json([
            'data' => $ordenActualizada,
        ], JsonResponse::HTTP_OK);
    }

    public function marcarEntregada(OrdenLavanderia $orden): JsonResponse
    {
        $ordenActualizada = $this->service->marcarEntregada($orden);

        return response()->json([
            'data' => $ordenActualizada,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Endpoint para dashboard tipo semáforo.
     */
    public function dashboard(): JsonResponse
    {
        $ordenes = $this->ordenes->getPendientesEnProceso();

        $now = now();

        $data = $ordenes->map(function (OrdenLavanderia $orden) use ($now) {
            $startedAt = $orden->current_step_started_at ?? $orden->created_at;
            $diffMinutes = $startedAt ? $startedAt->diffInMinutes($now) : 0;

            $color = match (true) {
                $orden->estatus === OrdenLavanderia::ESTATUS_TERMINADO
                    || $orden->estatus === OrdenLavanderia::ESTATUS_ENTREGADO => 'verde',
                $diffMinutes > 30 => 'rojo',
                default => 'amarillo',
            };

            return [
                'id' => $orden->id,
                'folio_unico' => $orden->folio_unico,
                'cliente_nombre' => $orden->cliente_nombre,
                'tipo_servicio' => $orden->tipo_servicio,
                'detalles_ropa' => $orden->detalles_ropa,
                'instrucciones' => $orden->instrucciones,
                'is_priority' => $orden->is_priority,
                'current_step' => $orden->current_step,
                'estatus' => $orden->estatus,
                'current_step_started_at' => $orden->current_step_started_at,
                'minutos_en_etapa' => $diffMinutes,
                'color' => $color,
            ];
        });

        return response()->json([
            'data' => $data,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Escanear QR o folio para obtener orden (para operadores).
     */
    public function escanearQR(Request $request): JsonResponse
    {
        $validator = Validator::make($request->all(), [
            'codigo_qr' => ['required_without:folio_unico', 'string'],
            'folio_unico' => ['required_without:codigo_qr', 'string'],
        ], [
            'codigo_qr.required_without' => 'Debe proporcionar el código QR o folio.',
            'folio_unico.required_without' => 'Debe proporcionar el código QR o folio.',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'errors' => $validator->errors(),
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        $query = OrdenLavanderia::query();

        if ($request->has('codigo_qr')) {
            $query->where('codigo_qr', $request->codigo_qr);
        } elseif ($request->has('folio_unico')) {
            $query->where('folio_unico', $request->folio_unico);
        }

        $orden = $query->first();

        if (!$orden) {
            return response()->json([
                'errors' => ['orden' => ['Orden no encontrada.']],
                'encontrada' => false,
            ], JsonResponse::HTTP_NOT_FOUND);
        }

        if (in_array($orden->estatus, [
            OrdenLavanderia::ESTATUS_TERMINADO,
            OrdenLavanderia::ESTATUS_ENTREGADO,
            OrdenLavanderia::ESTATUS_CANCELADO,
        ])) {
            return response()->json([
                'errors' => ['orden' => ['La orden ya está terminada, entregada o cancelada.']],
                'encontrada' => false,
                'estatus' => $orden->estatus,
            ], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
        }

        return response()->json([
            'data' => $orden,
            'encontrada' => true,
        ], JsonResponse::HTTP_OK);
    }
}

