<?php

use App\Http\Controllers\AreaAdminController;
use App\Http\Controllers\CajaController;
use App\Http\Controllers\CatalogosModuleController;
use App\Http\Controllers\ClienteCategoriaAdminController;
use App\Http\Controllers\ClienteController;
use App\Http\Controllers\ConfiguracionEmpresaController;
use App\Http\Controllers\EtapaAdminController;
use App\Http\Controllers\GarmentTypeAdminController;
use App\Http\Controllers\LaundrySaleCategoryAdminController;
use App\Http\Controllers\LaundrySaleProductAdminController;
use App\Http\Controllers\ImpresoraAdminController;
use App\Http\Controllers\InventoryCatalogController;
use App\Http\Controllers\InventoryMovementController;
use App\Http\Controllers\InventoryProductController;
use App\Http\Controllers\InventoryTransferDocumentController;
use App\Http\Controllers\LaundryApiController;
use App\Http\Controllers\LaundryWorkflowController;
use App\Http\Controllers\LavanderiaPosCatalogController;
use App\Http\Controllers\OrdenEstatusPublicController;
use App\Http\Controllers\OrdenLavanderiaController;
use App\Http\Controllers\ProductoController;
use App\Http\Controllers\PublicTrackingController;
use App\Http\Controllers\RoleController;
use App\Http\Controllers\TokenController;
use App\Http\Controllers\TipoServicioAdminController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\VentasController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Autenticación: la mayoría de endpoints bajo `auth:sanctum` (grupo más abajo).
| Rutas públicas (sin Sanctum): registro, config pública, tracking /orden-estatus (throttle),
| tokens create/pw/savepw, GET configuración-empresa, dev.setup. Resto: Bearer Sanctum. Detalle en comentarios del archivo.
|
*/

Route::post('/registro', [UserController::class, 'registro']);

Route::get('/configuracion-empresa/public', [ConfiguracionEmpresaController::class, 'publicConfig']);

Route::middleware('throttle:public-tracking')->group(function (): void {
    Route::get('/public/tracking/{folio}', [PublicTrackingController::class, 'show']);
    Route::get('/public/orden-estatus/{folio}', [OrdenEstatusPublicController::class, 'show']);
});

Route::middleware('dev.setup')->group(function (): void {
    Route::get('/storage-link', function () {
        try {
            Artisan::call('storage:link');
            $output = Artisan::output();

            return response()->json([
                'success' => true,
                'message' => 'Enlace simbólico de storage creado correctamente',
                'output' => $output,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error ejecutando storage:link: '.$e->getMessage(),
            ], 500);
        }
    });

    Route::get('/generate-key', function () {
        try {
            Artisan::call('key:generate');
            $output = Artisan::output();

            return response()->json([
                'success' => true,
                'message' => 'Clave de aplicación generada correctamente',
                'output' => $output,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error generando clave de aplicación: '.$e->getMessage(),
            ], 500);
        }
    });
});

Route::prefix('/tokens')->group(function (): void {
    Route::post('/create', [TokenController::class, 'createToken'])->middleware('throttle:login');
    Route::post('/pw', [TokenController::class, 'createResetPW'])->middleware('throttle:login');
    Route::post('/savepw', [TokenController::class, 'saveResetPW']);
    Route::post('/getpwuuid', [TokenController::class, 'getUserUuid']);
});

Route::middleware('auth:sanctum')->group(function () {

    Route::prefix('/tokens')->group(function (): void {
        Route::post('/logout', [TokenController::class, 'logout']);
        Route::delete('/{token}', [TokenController::class, 'expire']);
        Route::get('/permissions', function () {
            if (! auth()->check()) {
                return response()->json(['all' => false, 'permissions' => []], 401);
            }

            $user = auth()->user();
            $permissions = $user->getAllPermissions()->pluck('name')->toArray();
            $roles = $user->getRoleNames()->toArray();

            $isAdmin = in_array('Administrador', $roles);

            return response()->json([
                'all' => $isAdmin,
                'permissions' => $permissions,
                'roles' => $roles,
            ]);
        });
    });

    Route::prefix('/users')->group(function (): void {
        // Incluye `area` para que la vista de escaneo pueda derivar `areaCode` desde la asignación del operador.
        Route::get('/', fn (Request $request) => $request->user()->load(['roles', 'area']));
        Route::get('/all', [UserController::class, 'getUsers']);
        Route::get('/{user}', [UserController::class, 'getUser']);
        Route::post('/create', [UserController::class, 'store']);
        Route::put('/{user}/edit', [UserController::class, 'update']);
        Route::put('/{user}/password', [UserController::class, 'updatePassword']);
        Route::get('/{user}/mediciones', [UserController::class, 'getMediciones']);
        Route::get('/{user}/sucursales', [UserController::class, 'getSucursales']);
        Route::put('/perfil', [UserController::class, 'updatePerfil']);
        Route::get('/config/setconfig', [UserController::class, 'setConfigSucursal']);
        Route::get('/config/sucursal', [UserController::class, 'getConfigSucursal']);
        Route::get('/get/terapista', [UserController::class, 'getTerapistas']);
        Route::get('/get/revision', [UserController::class, 'getRevision']);
        Route::delete('/{user}', [UserController::class, 'destroy']);
    });

    Route::prefix('/roles')->group(function (): void {
        Route::get('/all', [RoleController::class, 'getRoles']);
        Route::get('/permissions', [RoleController::class, 'getPermissions']);
        Route::put('/{role}/permissions', [RoleController::class, 'updateRolePermissions']);
    });

    /** §23 — Administración de áreas TIBU (solo permiso administracion.areas). */
    Route::prefix('/admin/areas')->middleware('permission:administracion.areas')->group(function (): void {
        Route::get('/', [AreaAdminController::class, 'index']);
        Route::post('/', [AreaAdminController::class, 'store']);
        Route::put('/{area}', [AreaAdminController::class, 'update']);
        Route::patch('/{area}/disable', [AreaAdminController::class, 'disable']);
        Route::delete('/{area}', [AreaAdminController::class, 'destroy']);
    });

    // D5 — Administración de tipos de prenda (mapeado a administracion.areas en esta iteración).
    Route::prefix('/admin/garment-types')->middleware('permission:administracion.areas')->group(function (): void {
        Route::get('/', [GarmentTypeAdminController::class, 'index']);
        Route::post('/', [GarmentTypeAdminController::class, 'store']);
        Route::put('/{garmentType}', [GarmentTypeAdminController::class, 'update']);
        Route::patch('/{garmentType}/disable', [GarmentTypeAdminController::class, 'disable']);
        Route::delete('/{garmentType}', [GarmentTypeAdminController::class, 'destroy']);
    });

    Route::prefix('/admin/impresoras')->middleware('permission:administracion.areas')->group(function (): void {
        Route::get('/', [ImpresoraAdminController::class, 'index']);
        Route::post('/', [ImpresoraAdminController::class, 'store']);
        Route::post('/{impresora}/test-print', [ImpresoraAdminController::class, 'testPrint']);
        Route::put('/{impresora}', [ImpresoraAdminController::class, 'update']);
        Route::delete('/{impresora}', [ImpresoraAdminController::class, 'destroy']);
    });

    Route::prefix('/admin/laundry-sale-categories')->middleware('permission:administracion.areas')->group(function (): void {
        Route::get('/', [LaundrySaleCategoryAdminController::class, 'index']);
        Route::post('/', [LaundrySaleCategoryAdminController::class, 'store']);
        Route::put('/{laundrySaleCategory}', [LaundrySaleCategoryAdminController::class, 'update']);
        Route::patch('/{laundrySaleCategory}/disable', [LaundrySaleCategoryAdminController::class, 'disable']);
        Route::delete('/{laundrySaleCategory}', [LaundrySaleCategoryAdminController::class, 'destroy']);
    });

    Route::prefix('/admin/laundry-sale-products')->middleware('permission:administracion.areas')->group(function (): void {
        Route::get('/', [LaundrySaleProductAdminController::class, 'index']);
        Route::post('/', [LaundrySaleProductAdminController::class, 'store']);
        Route::put('/{laundrySaleProduct}', [LaundrySaleProductAdminController::class, 'update']);
        Route::patch('/{laundrySaleProduct}/disable', [LaundrySaleProductAdminController::class, 'disable']);
        Route::delete('/{laundrySaleProduct}', [LaundrySaleProductAdminController::class, 'destroy']);
    });

    Route::prefix('/admin/etapas')->middleware('permission:administracion.areas')->group(function (): void {
        Route::delete('/{etapa}', [EtapaAdminController::class, 'destroy']);
    });

    Route::prefix('/admin/tipos-servicio')->middleware('permission:administracion.areas')->group(function (): void {
        Route::delete('/{tipoServicio}', [TipoServicioAdminController::class, 'destroy']);
    });

    Route::prefix('/configuracion-empresa')->middleware(
        'permission:administracion.configuracion_empresa|administracion.areas|administracion.usuarios|caja.administrar'
    )->group(function (): void {
        Route::get('/', [ConfiguracionEmpresaController::class, 'index']);
        Route::put('/update', [ConfiguracionEmpresaController::class, 'update']);
        Route::post('/upload-logo', [ConfiguracionEmpresaController::class, 'uploadLogo']);
        Route::post('/upload-favicon', [ConfiguracionEmpresaController::class, 'uploadFavicon']);
        Route::post('/upload-icono-mensaje', [ConfiguracionEmpresaController::class, 'uploadIconoMensaje']);
        Route::delete('/delete-logo', [ConfiguracionEmpresaController::class, 'deleteLogo']);
        Route::delete('/delete-favicon', [ConfiguracionEmpresaController::class, 'deleteFavicon']);
        Route::delete('/delete-icono-mensaje', [ConfiguracionEmpresaController::class, 'deleteIconoMensaje']);
    });

    // Catálogo productos/servicios (CRUD unificado: producto con stock, servicio con tipo_cobro kg/pieza)
    Route::get('/productos', [ProductoController::class, 'index'])->middleware('permission:pos.vender|caja.administrar');
    Route::get('/productos/{producto}', [ProductoController::class, 'show'])->middleware('permission:pos.vender|caja.administrar');
    Route::post('/productos', [ProductoController::class, 'store'])->middleware('permission:pos.vender');
    Route::put('/productos/{producto}', [ProductoController::class, 'update'])->middleware('permission:pos.vender');
    Route::delete('/productos/{producto}', [ProductoController::class, 'destroy'])->middleware('permission:pos.vender');

    // D4: etapas TIBU, servicios SLA y productos legacy.
    Route::prefix('/catalogos')->group(function (): void {
        Route::get('/etapas', [CatalogosModuleController::class, 'etapas'])
            ->middleware('permission:pos.vender|caja.administrar|administracion.areas');
        Route::get('/tipos-servicio', [CatalogosModuleController::class, 'tiposServicio'])
            ->middleware('permission:pos.vender|caja.administrar|administracion.areas');
        Route::get('/productos-legacy', [CatalogosModuleController::class, 'productosLegacy'])
            ->middleware('permission:pos.vender|caja.administrar|administracion.areas');
    });

    // Clientes: lectura POS/caja (mismo criterio que productos); mutaciones solo venta
    Route::get('/clientes', [ClienteController::class, 'index'])->middleware('permission:pos.vender|caja.administrar');
    Route::get('/clientes/mostrador', [ClienteController::class, 'mostrador'])->middleware('permission:pos.vender|caja.administrar');
    Route::get('/clientes/{cliente}', [ClienteController::class, 'show'])->middleware('permission:pos.vender|caja.administrar');
    Route::post('/clientes', [ClienteController::class, 'store'])->middleware('permission:pos.vender');
    Route::put('/clientes/{cliente}', [ClienteController::class, 'update'])->middleware('permission:pos.vender');
    Route::delete('/clientes/{cliente}', [ClienteController::class, 'destroy'])->middleware('permission:pos.vender');

    Route::prefix('/catalogos/cliente-categorias')->group(function (): void {
        Route::get('/', [ClienteCategoriaAdminController::class, 'index'])->middleware('permission:pos.vender|caja.administrar');
        Route::post('/', [ClienteCategoriaAdminController::class, 'store'])->middleware('permission:pos.vender');
        Route::put('/{clienteCategoria}', [ClienteCategoriaAdminController::class, 'update'])->middleware('permission:pos.vender');
        Route::patch('/{clienteCategoria}/disable', [ClienteCategoriaAdminController::class, 'disable'])->middleware('permission:pos.vender');
        Route::delete('/{clienteCategoria}', [ClienteCategoriaAdminController::class, 'destroy'])->middleware('permission:pos.vender');
    });

    // Catálogos POS (prioridad, prendas, carga TIBU). Alias histórico; canónico C6: /laundry/pos-catalog.
    Route::get('/lavanderia/pos/catalog', [LavanderiaPosCatalogController::class, 'index'])
        ->middleware('permission:pos.vender');

    // Módulo de Lavandería - Órdenes (POST crear requiere caja abierta y permiso pos.vender)
    Route::prefix('/lavanderia/ordenes')->group(function (): void {
        Route::get('/export-csv', [OrdenLavanderiaController::class, 'exportCsv'])
            ->middleware('permission:reportes.ver');
        Route::get('/', [OrdenLavanderiaController::class, 'index'])->middleware('permission:pos.vender|lavanderia.consultar');
        Route::get('/abiertas', [OrdenLavanderiaController::class, 'openOrders'])->middleware('permission:pos.vender|lavanderia.recepcion');
        Route::post('/', [OrdenLavanderiaController::class, 'store'])
            ->middleware('permission:pos.vender', 'caja.abierta');
        Route::put('/{orden}', [OrdenLavanderiaController::class, 'update'])
            ->middleware('permission:pos.vender|lavanderia.recepcion');

        // Escaneo QR para operadores
        Route::post('/escanear-qr', [OrdenLavanderiaController::class, 'escanearQR'])->middleware('permission:lavanderia.operador');

        // Flujo operativo legacy: avance manual retirado; operación vía escaneo por área.
        Route::post('/{orden}/entregar', [OrdenLavanderiaController::class, 'marcarEntregada'])->middleware('permission:lavanderia.recepcion');
        Route::post('/{orden}/cancelar', [OrdenLavanderiaController::class, 'cancelar'])->middleware('permission:lavanderia.recepcion');

        // Dashboard tipo semáforo
        Route::get('/dashboard/resumen', [OrdenLavanderiaController::class, 'dashboard'])
            ->middleware('permission:lavanderia.dashboard');

        Route::get('/{orden}/ticket-pdf', [OrdenLavanderiaController::class, 'ticketPdf'])
            ->middleware('permission:lavanderia.consultar|lavanderia.operador|lavanderia.recepcion');
        Route::post('/{orden}/reimprimir-ticket', [OrdenLavanderiaController::class, 'reimprimirTicket'])
            ->middleware('permission:pos.vender|lavanderia.recepcion|lavanderia.consultar');
        Route::post('/{orden}/imprimir-etiqueta-bolsa', [OrdenLavanderiaController::class, 'imprimirEtiquetaBolsa'])
            ->middleware('permission:pos.vender|lavanderia.recepcion|lavanderia.consultar');
        Route::put('/{orden}/bolsas', [OrdenLavanderiaController::class, 'putBolsas'])
            ->middleware('permission:pos.vender|lavanderia.recepcion');
        Route::get('/{orden}/bolsas-pdf', [OrdenLavanderiaController::class, 'bolsasPdf'])
            ->middleware('permission:lavanderia.consultar|lavanderia.operador|lavanderia.recepcion');
        Route::get('/{orden}', [OrdenLavanderiaController::class, 'show'])
            ->middleware('permission:lavanderia.consultar|lavanderia.operador|lavanderia.recepcion');
    });

    // Flujo TIBU: escaneo por área (permiso area.{code}.operate vía middleware ensure.area.operate)
    Route::post('/lavanderia/workflow/register-scan', [LaundryWorkflowController::class, 'registerScan'])
        ->middleware(['ensure.area.operate', 'throttle:laundry-scans']);

    // API lavandería (prefijo /laundry). Catálogo POS y preview de totales (C6). /api/inventory/* es almacén (inventory_*), no usar para armar órdenes POS.
    Route::prefix('/laundry')->group(function (): void {
        Route::get('/pos-catalog', [LavanderiaPosCatalogController::class, 'index'])
            ->middleware('permission:pos.vender');
        Route::post('/pos/preview-totals', [LavanderiaPosCatalogController::class, 'previewTotals'])
            ->middleware('permission:pos.vender');

        Route::get('/areas', [LaundryApiController::class, 'areas'])
            ->middleware('permission:lavanderia.consultar|lavanderia.operador|lavanderia.recepcion');
        Route::get('/scan-operators', [LaundryWorkflowController::class, 'scanOperators'])
            ->middleware('permission:lavanderia.operador|lavanderia.recepcion');
        Route::post('/scans', [LaundryWorkflowController::class, 'storeScan'])
            ->middleware(['ensure.area.operate', 'throttle:laundry-scans']);
        Route::get('/orders/{orden}/presence', [LaundryApiController::class, 'orderPresence'])
            ->middleware('permission:pos.vender|lavanderia.consultar|lavanderia.operador');
        /** @see prompt §20 — mismo contrato que presence (estado operativo TIBU por orden). */
        Route::get('/orders/{orden}/laundry-state', [LaundryApiController::class, 'laundryState'])
            ->middleware('permission:pos.vender|lavanderia.consultar|lavanderia.operador');
    });

    // Caja: apertura, estado y corte (resumen + PDF)
    Route::prefix('/caja')->group(function (): void {
        Route::get('/estado', [CajaController::class, 'estado'])->middleware('permission:caja.administrar');
        Route::post('/abrir', [CajaController::class, 'abrir'])->middleware('permission:caja.administrar');
        Route::get('/movimientos', [CajaController::class, 'movimientos'])->middleware('permission:caja.administrar');
        Route::post('/movimientos', [CajaController::class, 'storeMovimiento'])->middleware('permission:caja.administrar');
        Route::post('/cortar', [CajaController::class, 'cortar'])->middleware('permission:caja.administrar');
    });

    // Reportes - Ventas al mes (órdenes entregadas)
    Route::prefix('/ventas')->group(function (): void {
        Route::get('/mensual', [VentasController::class, 'mensual'])->middleware('permission:reportes.ver');
    });

    // Inventario (tablas inventory_*; almacén/insumos). No sustituye el catálogo POS ni líneas de orden (/laundry/pos-catalog, lavanderia/ordenes).
    Route::prefix('/inventory')->group(function (): void {
        Route::get('/catalog', [InventoryCatalogController::class, 'index'])
            ->middleware('permission:inventory.view|inventory.manage');

        Route::post('/products/bulk-adjust-csv', [InventoryBulkAdjustCsvController::class, 'store'])
            ->middleware('permission:inventory.manage');

        Route::get('/products', [InventoryProductController::class, 'index'])
            ->middleware('permission:inventory.view|inventory.manage');
        Route::post('/products', [InventoryProductController::class, 'store'])
            ->middleware('permission:inventory.manage');
        Route::get('/products/{inventory_product}', [InventoryProductController::class, 'show'])
            ->middleware('permission:inventory.view|inventory.manage');
        Route::put('/products/{inventory_product}', [InventoryProductController::class, 'update'])
            ->middleware('permission:inventory.manage');
        Route::patch('/products/{inventory_product}/disable', [InventoryProductController::class, 'disable'])
            ->middleware('permission:inventory.manage');
        Route::patch('/products/{inventory_product}/activate', [InventoryProductController::class, 'activate'])
            ->middleware('permission:inventory.manage');
        Route::delete('/products/{inventory_product}', [InventoryProductController::class, 'destroy'])
            ->middleware('permission:inventory.manage');

        Route::get('/products/{inventory_product}/movements', [InventoryMovementController::class, 'index'])
            ->middleware('permission:inventory.view|inventory.manage');
        Route::post('/products/{inventory_product}/movements', [InventoryMovementController::class, 'store'])
            ->middleware('permission:inventory.manage');

        // Documentos de inventario (ADR-002): recepción IN, entrega interna y salida OUT. Lectura inventory.view|manage; mutación inventory.manage.
        Route::get('/transfer-documents', [InventoryTransferDocumentController::class, 'index'])
            ->middleware('permission:inventory.view|inventory.manage');
        Route::get('/transfer-documents/{inventory_transfer_document}', [InventoryTransferDocumentController::class, 'show'])
            ->middleware('permission:inventory.view|inventory.manage');
        Route::post('/quick-transfer', [InventoryTransferDocumentController::class, 'quickStore'])
            ->middleware('permission:inventory.manage');
        Route::post('/transfer-documents', [InventoryTransferDocumentController::class, 'store'])
            ->middleware('permission:inventory.manage');
        Route::put('/transfer-documents/{inventory_transfer_document}', [InventoryTransferDocumentController::class, 'update'])
            ->middleware('permission:inventory.manage');
        Route::post('/transfer-documents/{inventory_transfer_document}/confirm', [InventoryTransferDocumentController::class, 'confirm'])
            ->middleware('permission:inventory.manage');
        Route::post('/transfer-documents/{inventory_transfer_document}/cancel-draft', [InventoryTransferDocumentController::class, 'cancelDraft'])
            ->middleware('permission:inventory.manage');
    });
});
