<?php

namespace App\Http\Controllers;

use App\Http\Requests\LaundryPosPreviewTotalsRequest;
use App\Models\GarmentType;
use App\Models\LaundryPiecePrice;
use App\Models\LaundrySaleCategory;
use App\Models\LaundrySaleProduct;
use App\Models\LoadType;
use App\Models\TipoServicio;
use App\Models\Etapa;
use App\Services\LaundryPosPreviewTotalsService;
use App\Services\LaundryPricingService;
use App\Support\ImpresoraResolver;
use Illuminate\Http\JsonResponse;

/**
 * Catálogos para el POS (prioridad, tipo de prenda, tipo de carga, matriz C2, catálogo por producto ADR-001).
 *
 * Rutas (JSON `data`):
 * - `GET /api/laundry/pos-catalog` (canónico) y `GET /api/lavanderia/pos/catalog` (alias).
 * - `POST /api/laundry/pos/preview-totals` — cuerpo: `{ "items": [ ... ] }` (mismas reglas que `POST /api/lavanderia/ordenes` con `items`).
 *
 * Ejemplo de `items` mezclados (TIBU + catálogo POS):
 * ```json
 * {
 *   "items": [
 *     {
 *       "etapa_id": 1,
 *       "billing_mode": "by_garment_type",
 *       "garment_type_id": 2,
 *       "load_type_id": 1,
 *       "cantidad": 1
 *     },
 *     {
 *       "laundry_sale_product_id": 3,
 *       "cantidad": 2
 *     }
 *   ]
 * }
 * ```
 *
 * Respuesta `GET` (resumen): `data` incluye `servicios`, `etapas`, `garment_types`, `load_types`,
 * `laundry_piece_prices`, `price_per_kg`, `laundry_sale_categories`, `laundry_sale_products` (con `category`, defaults y `unit_price`).
 */
class LavanderiaPosCatalogController extends Controller
{
    public function __construct(
        private readonly LaundryPricingService $laundryPricing,
        private readonly LaundryPosPreviewTotalsService $posPreviewTotals
    ) {}

    public function index(): JsonResponse
    {
        $piecePrices = LaundryPiecePrice::query()
            ->where('is_active', true)
            ->with(['etapa:id,code,name', 'garmentType:id,code,name', 'loadType:id,code,name'])
            ->orderBy('etapa_id')
            ->orderBy('garment_type_id')
            ->orderBy('load_type_id')
            ->get();

        $pricePerKg = $this->laundryPricing->resolvePricePerKg();

        $saleCategories = LaundrySaleCategory::query()
            ->where('is_active', true)
            ->orderBy('sort_order')
            ->get(['id', 'code', 'name', 'sort_order', 'is_active']);

        $saleProducts = LaundrySaleProduct::query()
            ->where('is_active', true)
            ->with([
                'category:id,code,name,sort_order',
                'defaultEtapa:id,code,name',
                'defaultLoadType:id,code,name',
                'defaultTipoServicio:id,code,name,sort_order',
                'servicePrices:id,laundry_sale_product_id,etapa_id,amount',
            ])
            ->orderBy('laundry_sale_category_id')
            ->orderBy('sort_order')
            ->get([
                'id', 'laundry_sale_category_id', 'code', 'name', 'tipo', 'description',
                'default_etapa_id', 'default_load_type_id',
                'billing_unit', 'unit_price', 'extra_cost',
                'is_active', 'sort_order', 'inventory_product_id', 'tracks_stock', 'stock_quantity',
            ]);

        return response()->json([
            'data' => [
                'tipos_servicio' => TipoServicio::query()->orderBy('sort_order')->get([
                    'id', 'code', 'name', 'sort_order',
                ]),
                'etapas' => Etapa::query()->orderBy('sort_order')->get(['id', 'code', 'name', 'sort_order']),
                'garment_types' => GarmentType::query()->orderBy('sort_order')->get([
                    'id', 'code', 'name', 'sort_order', 'default_load_type_id', 'is_active',
                ]),
                'load_types' => LoadType::query()->orderBy('sort_order')->get(['id', 'code', 'name', 'sort_order']),
                'laundry_piece_prices' => $piecePrices,
                'price_per_kg' => $pricePerKg,
                'laundry_sale_categories' => $saleCategories,
                'laundry_sale_products' => $saleProducts,
                'reception_printer' => ImpresoraResolver::posReceptionPrinterStatus(),
                'default_delivery_days' => (int) config('lavanderia.default_delivery_days', 3),
                'default_delivery_hour' => (int) config('lavanderia.default_delivery_hour', 20),
                'semaphore_hours_red' => (int) config('lavanderia.semaphore_hours_red', 2),
                'semaphore_hours_yellow' => (int) config('lavanderia.semaphore_hours_yellow', 3),
                'weight_min_kg' => (float) config('lavanderia.weight_min_kg', 3),
                'piece_min_bill_qty' => (int) config('lavanderia.piece_min_bill_qty', 3),
            ],
            'meta' => null,
            'errors' => null,
        ], JsonResponse::HTTP_OK);
    }

    /**
     * Totales de líneas sin persistir (C6); mismas reglas que POST lavanderia/ordenes con items.
     */
    public function previewTotals(LaundryPosPreviewTotalsRequest $request): JsonResponse
    {
        $result = $this->posPreviewTotals->compute($request->validated()['items']);

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