<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Carbon;
use Carbon\Exceptions\InvalidFormatException;
use ElephantIO\Client;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\File;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\IOFactory;

class CorrectiveMaintenanceController extends Controller{
    private $responseController;
    private $encryptionController;
    private $functionsController;
    private $documentManagementController;
    private $notificationsController;
    private $socketClient;

    public function __construct(){
        $this->responseController = new ResponseController();
        $this->encryptionController = new EncryptionController();
        $this->functionsController = new FunctionsController();
        $this->documentManagementController = new DocumentManagementController();
        $this->notificationsController = new NotificationsController();

        $url = 'http://localhost:3200';
        $this->socketClient = new Client(Client::engine(Client::CLIENT_4X, $url));
        $this->socketClient->initialize();
        $this->socketClient->of('/');
    }

    public function registerWorkOrder(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_responsible' => 'required|string',
            'type_responsible' => 'required|string|in:U,S',
            'description' => 'required|string|min:15',
            'equipment' => 'required|string',
            'start_date_time' => 'required|date',
            'solution_time' => 'required|numeric',
            'priority' => 'required|string',
            'id_counter' => 'required|string',
            'id_last_measure' => 'required|string',
            'clasification' => 'required|string|max:50',
            'staff' => 'required|json',
            'security_management' => 'required|string',
            'activation_type' => 'required|string|in:Manual,Automática',
            'resources' => 'required|json',
            'attached' => 'json',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }
        
        $idUserResponsible = $this->encryptionController->decrypt($form['id_responsible']);
        if(!$idUserResponsible){
            return $this->responseController->makeResponse(true, 'El ID del usuario responsable no fue encriptado correctamente.', [], 400);
        }

        $usrResponsible = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUserResponsible]
        ])->first();
        
        if(is_null($usrResponsible)){
            return $this->responseController->makeResponse(true, 'El usuario responsable de atender la solicitud no existe.', [], 404);
        }

        $equipmentCode = $this->encryptionController->decrypt($form['equipment']);
        if(!$equipmentCode){
            return $this->responseController->makeResponse(true, 'El código del equipamiento relacionado no fue encriptado correctamente.', [], 400);
        }

        $equipment = DB::table('S002V01TEQUI')->where([
            ['EQUI_NULI', '=', $form['linea']],
            ['EQUI_COEQ', '=', $equipmentCode],
        ])->first();
        
        if(is_null($equipment)){
            return $this->responseController->makeResponse(true, 'El equipamiento relacionado no existe.', [], 404);
        }

        if(floatval($form['solution_time']) <= 0){
            return $this->responseController->makeResponse(true, 'El tiempo de solución estimado debe ser mayor a cero.', [], 400);
        }

        $priority = $this->encryptionController->decrypt($form['priority']);
        if(!$priority){
            return $this->responseController->makeResponse(true, 'La prioridad relacionada no fue encriptada correctamente.', [], 400);
        }

        $validPriorities = ['1', '2', '3', '4'];
        if(!in_array($priority, $validPriorities)){
            return $this->responseController->makeResponse(true, 'La prioridad relacionada es inválida.', [], 400);
        }

        $idCounter = $this->encryptionController->decrypt($form['id_counter']);
        if(!$idCounter){
            return $this->responseController->makeResponse(true, 'El ID del contador relacionado no fue encriptado correctamente.', [], 400);
        }

        $counter = DB::table('S002V01TCONA')->where([
            ['CONA_IDCO', '=', $idCounter],
            ['CONA_NULI', '=', $form['linea']]
        ])->first();
        
        if(is_null($counter)){
            return $this->responseController->makeResponse(true, 'El contador relacionado no existe.', [], 404);
        }

        $idLastMeasure = $this->encryptionController->decrypt($form['id_last_measure']);
        if(!$idLastMeasure){
            return $this->responseController->makeResponse(true, 'El ID de la última medida del contador relacionado no fue encriptado correctamente.', [], 400);
        }

        $lastMeasure = DB::table('S002V01TMEDI')->select([
            'MEDI_IDME AS ID_MEDIDA',
            'MEDI_CORE AS CONTADOR',
            'MEDI_VALO AS VALOR',
            'MEDI_WSRE AS ID_SERVICIO_WEB',
            'LSWE_URLX AS URL_SERVICIO_WEB',
            'MEDI_HORE AS HORA_REGISTRO',
        ])->join('S002V01TLSWE', 'LSWE_IDSW', '=', 'MEDI_WSRE')->where([
            ['MEDI_IDME', '=', $idLastMeasure],
            ['MEDI_NULI', '=', $form['linea']],
            ['MEDI_CORE', '=', $idCounter]
        ])->orderBy('MEDI_HORE', 'desc')->first();
        
        if(is_null($lastMeasure)){
            return $this->responseController->makeResponse(true, 'La última medida del contador relacionado no existe.', [], 404);
        }

        $staffArr = json_decode($form['staff'], true);
        if(count($staffArr) == 0){
            return $this->responseController->makeResponse(true, 'El arreglo del personal está vacío.', [], 400);
        }

        $staffArrFn = [];
        foreach($staffArr as $key=>$item){
            $itemArr = explode('-', $item);
            $idDec = $this->encryptionController->decrypt($itemArr[0]);
            if(!$idDec){
                return $this->responseController->makeResponse(true, "El ID en la posición $key del arreglo del personal no fue encriptado correctamente.", [], 400);
            }

            if($itemArr[1] == 'EQ'){
                $workTeam = DB::table('S002V01TEQMA')->where([
                    ['EQMA_IDEQ', '=', $idDec],
                    ['EQMA_NULI', '=', $form['linea']]
                ])->first();

                if(is_null($workTeam)){
                    return $this->responseController->makeResponse(true, "El equipo de trabajo en la posición $key del arreglo del personal no existe.", [], 404);
                }else if($workTeam->EQMA_ESTA == 'Eliminado'){
                    return $this->responseController->makeResponse(true, "El equipo de trabajo en la posición $key del arreglo del personal está eliminado.", [], 404);
                }

                $staffArrFn[] = [
                    'ID' => $idDec,
                    'TYPE' => $itemArr[1]
                ];
            }else if($itemArr[1] == 'SU'){
                $subcontratist = DB::table('S002V01TPESU')->where([
                    ['PESU_IDPS', '=', $idDec],
                    ['PESU_NULI', '=', $form['linea']]
                ])->first();

                if(is_null($subcontratist)){
                    return $this->responseController->makeResponse(true, "El subcontratista en la posición $key del arreglo del personal no existe.", [], 404);
                }else if($subcontratist->PESU_ESTA == 'Eliminado'){
                    return $this->responseController->makeResponse(true, "El subcontratista en la posición $key del arreglo del personal está eliminado.", [], 404);
                }

                $staffArrFn[] = [
                    'ID' => $idDec,
                    'TYPE' => $itemArr[1]
                ];
            }else if($itemArr[1] == 'EM'){
                $employee = DB::table('S002V01TPERS')->where([
                    ['PERS_IDPE', '=', $idDec],
                    ['PERS_NULI', '=', $form['linea']]
                ])->first();

                if(is_null($employee)){
                    return $this->responseController->makeResponse(true, "El empleado en la posición $key del arreglo del personal no existe.", [], 404);
                }else if($employee->PERS_ESTA == 'Eliminado'){
                    return $this->responseController->makeResponse(true, "El empleado en la posición $key del arreglo del personal está eliminado.", [], 404);
                }

                $staffArrFn[] = [
                    'ID' => $idDec,
                    'TYPE' => $itemArr[1]
                ];
            }
        }

        $staffStrFn = json_encode($staffArrFn);
        $idManagement = $this->encryptionController->decrypt($form['security_management']);
        if(!$idManagement){
            return $this->responseController->makeResponse(true, 'El ID de la gerencia de seguridad no está encriptado correctamente', [], 400);
        }

        $management = DB::table('S002V01TGESE')->where([
            ['GESE_NULI', '=', $form['linea']],
            ['GESE_IDGS', '=', $idManagement]
        ])->first();

        if(is_null($management)){
            return $this->responseController->makeResponse(true, 'La gerencia de seguridad seleccionada no está registrada.', [], 404);
        }
        //PENDIENTE REVISAR LOS RECURSOS

        $attachedArrFn = [];
        if(isset($form['attached'])){
            $attachedArr = json_decode($form['attached'], true);
            foreach($attachedArr as $key=>$attached){
                $idDec = $this->encryptionController->decrypt($attached['id']);
                if(!$idDec){
                    return $this->responseController->makeResponse(true, "El ID del documento en la posición $key no fue encriptado correctamente.", [], 400);
                }

                if($attached['type'] == 'Existente'){
                    $codeArr = explode('=', $idDec);
                    $codeArr0 = explode('-', $codeArr[0]);

                    $file = DB::table('S002V01TAFAL')->where([
                        ['AFAL_NULI', '=', $form['linea']],
                        ['AFAL_COMO', '=', $codeArr0[1]],
                        ['AFAL_CLDO', '=', $codeArr0[2]],
                        ['AFAL_FECR', '=', $codeArr0[3]],
                        ['AFAL_NUSE', '=', $codeArr0[4]],
                        ['AFAL_NUVE', '=', $codeArr[1]],
                    ])->first();

                    if(is_null($file)){
                        return $this->responseController->makeResponse(true, "El documento en la posición $key no existe.", [], 404);
                    }else if($file->AFAL_ESTA == 'Eliminado'){
                        return $this->responseController->makeResponse(true, "El documento en la posición $key está eliminado.", [], 404);
                    }

                    $attachedArrFn[] = $idDec;
                }else if($attached['type'] == 'Nuevo'){
                    $tempFile = DB::table('S002V01TARTE')->where([
                        ['ARTE_IDAR', '=', $idDec],
                        ['ARTE_NULI', '=', $form['linea']]
                    ])->first();

                    if(is_null($tempFile)){
                        return $this->responseController->makeResponse(true, "El documento en la posición $key no existe.", [], 404);
                    }else if($tempFile->ARTE_ESTA == 'Eliminado'){
                        return $this->responseController->makeResponse(true, "El documento en la posición $key está eliminado.", [], 404);
                    }

                    $finalFile = $this->documentManagementController->moveFinalFile($form['linea'], 'GMCO', 'OR', $tempFile, $idUser);
                    if(!$finalFile){
                        return $this->responseController->makeResponse(true, $finalFile[1], [], 400);
                    }else{
                        $attachedArrFn[] = $finalFile[1];
                    }
                }
            }
        }

        $activationType = $form['activation_type'][0];
        $attachedStrFn = json_encode($attachedArrFn);
        $lastMeasureStr = json_encode($lastMeasure);

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        $statusHistoryStr = json_encode([
            ['USUARIO' => $idUser, 'ESTADO' => 'PE', 'FECHA' => $nowStr]
        ]);

        $orderID = DB::table('S002V01TOTCO')->insertGetId([
            'OTCO_NULI' => $form['linea'],
            'OTCO_IDUR' => $idUserResponsible,
            'OTCO_TURE' => $form['type_responsible'],
            'OTCO_DEIN' => $form['description'],
            'OTCO_EQIN' => $equipmentCode,
            'OTCO_FIFA' => $form['start_date_time'],
            'OTCO_TESO' => $form['solution_time'],
            'OTCO_CORE' => $idCounter,
            'OTCO_DRCO' => $lastMeasureStr,
            'OTCO_PRIO' => $priority,
            'OTCO_RHUT' => $form['resources'],
            'OTCO_PEIN' => $staffStrFn,
            'OTCO_TIAC' => $activationType,
            'OTCO_DORE' => $attachedStrFn,
            'OTCO_CLAS' => $form['clasification'],
            'OTCO_GESE' => $idManagement,
            'OTCO_HIES' => $statusHistoryStr,
            'OTCO_ESOR' => 'PE',
            'OTCO_USRE' => $idUser,
            'OTCO_FERE' => $nowStr
        ]);

        $this->notificationsController->emitNotification(
            'S002V01M09GMCO',
            "Orden de mantenimiento correctivo #$orderID",
            "Su usuario ha sido asignado como responsable de atender la orden de mantenimiento #$orderID.",
            [[
                'BOTON' => 'Ver detalles',
                'FUNCION' => 'openCorrectiveWorkOrderDetails',
                'PARAMETROS' => json_encode([$this->encryptionController->encrypt($orderID)])
            ], [
                'BOTON' => 'Validar orden',
                'FUNCION' => 'validateCorrectiveWorkOrder',
                'PARAMETROS' => json_encode([$this->encryptionController->encrypt($orderID)])
            ], [
                'BOTON' => 'Ir al módulo',
                'FUNCION' => 'openModule',
                'PARAMETROS' => json_encode([$this->encryptionController->encrypt('GMCO/ORTR/GEOP')])
            ]],
            [$idUserResponsible],
            $idUser, 
            $form['linea'],
            $this->socketClient,
            $orderID,
            'Correctivo'
        );

        $idOrderEnc = $this->encryptionController->encrypt($orderID);
        $socketData = ['idOrder' => $idOrderEnc];
        $this->socketClient->emit('new_corrective_work_order', $socketData);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F04GEOT',
            'S002V01P01GEOT',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró la orden de trabajo correctivo #$orderID.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function getWorkOrders($idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $orders = DB::table('S002V01TOTCO')->select([
            'OTCO_IDOT AS ID_ORDEN',
            'OTCO_EQIN AS CODIGO_EQUIPAMIENTO',
            'EQUI_TIPO AS TIPO_EQUIPAMIENTO',
            'EQUI_MODE AS MODELO_EQUIPAMIENTO',
            'EQUI_IDEQ AS ID_EQUIPAMIENTO',
            'OTCO_FIFA AS FECHA_INICIO',
            'OTCO_CORE AS CONTADOR',
            'OTCO_FTIN AS FECHA_FIN',
            'OTCO_TIAC AS TIPO_ACTIVACION',
            'OTCO_IDUR AS ID_RESPONSABLE',
            'OTCO_TURE AS TIPO_RESPONSABLE',
            'OTCO_PRIO AS PRIORIDAD',
            'OTCO_ESOR AS ESTADO'
        ])->join('S002V01TEQUI', 'EQUI_COEQ', '=', 'OTCO_EQIN')
        ->where('OTCO_NULI', '=', $line)
        ->orderBy('OTCO_IDOT', 'desc')->get()->all();

        $subcontratistTypes = ['S' => 'Subcontratista', 'U' => 'Usuario'];
        $activationTypes = ['M' => 'Manual', 'A' => 'Automática'];
        $orderStates = [
            'PE' => 'Pendiente',   'VA' => 'Validado', 'RE' => 'Rechazado', 
            'EP' => 'En progreso', 'CE' => 'Cerrado',  'CP' => 'Cerrado pendiente',
            'CA' => 'Cancelado',   'EL' => 'Eliminado'
        ];

        foreach($orders as $key=>$order){
            if($order->TIPO_RESPONSABLE == 'U'){
                $userResponsible = DB::table('S002V01TUSUA')->where([
                    ['USUA_IDUS', '=', $order->ID_RESPONSABLE],
                    ['USUA_NULI', '=', $line]
                ])->first();

                $userResponsibleName = $this->functionsController->joinName($userResponsible->USUA_NOMB, $userResponsible->USUA_APPA, $userResponsible->USUA_APMA);
                $order->ID_RESPONSABLE = $userResponsibleName . " (" . $order->ID_RESPONSABLE . ")";
            }else{
                $subcontratistResponsible = DB::table('S002V01TPESU')->where([
                    ['PESU_NULI', '=', $line],
                    ['PESU_IDPS', '=', $order->ID_RESPONSABLE]
                ])->first();

                $order->ID_RESPONSABLE = $subcontratistResponsible->PESU_RASO . " (" . $subcontratistResponsible->PESU_REFI . ") (" . $order->ID_RESPONSABLE . ")";
            }

            $order->TIPO_RESPONSABLE = $subcontratistTypes[$order->TIPO_RESPONSABLE];
            $order->ID_ORDEN = $this->encryptionController->encrypt($order->ID_ORDEN);
            $order->CODIGO_EQUIPAMIENTO = $this->encryptionController->encrypt($order->CODIGO_EQUIPAMIENTO);
            $order->ID_EQUIPAMIENTO = $this->encryptionController->encrypt($order->ID_EQUIPAMIENTO);
            $order->CONTADOR = $this->encryptionController->encrypt($order->CONTADOR);
            $order->TIPO_ACTIVACION = $activationTypes[$order->TIPO_ACTIVACION];
            $order->PRIORIDAD = $this->encryptionController->encrypt($order->PRIORIDAD);
            $order->ESTADO = $orderStates[$order->ESTADO];

            $orders[$key] = $order;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F01GEOP',
            'S002V01P01COOP',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las órdenes de mantenimiento correctivo registradas.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $orders);
    }

    public function getWorkOrder($idOrder, $idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($idOrder);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente', [], 400);
        }

        $order = DB::table('S002V01TOTCO')->select([
            'OTCO_IDOT AS ID_ORDEN',
            'OTCO_DEIN AS DESCRIPCION',
            'OTCO_EQIN AS CODIGO_EQUIPAMIENTO',
            'EQUI_TIPO AS TIPO_EQUIPAMIENTO',
            'EQUI_MODE AS MODELO_EQUIPAMIENTO',
            'EQUI_IDEQ AS ID_EQUIPAMIENTO',
            'OTCO_FIFA AS FECHA_INICIO',
            'OTCO_TESO AS TIEMPO_ESTIMADO',
            'OTCO_CORE AS CONTADOR',
            'OTCO_DRCO AS MEDIDAS',
            'OTCO_PRIO AS PRIORIDAD',
            'OTCO_FTIN AS FECHA_FINAL',
            'OTCO_DTIN AS DURACION_TOTAL',
            'OTCO_RHUT AS RECURSOS',
            'OTCO_PEIN AS PERSONAL',
            'OTCO_TIAC AS TIPO_ACTIVACION',
            'OTCO_IDUR AS ID_RESPONSABLE',
            'OTCO_TURE AS TIPO_RESPONSABLE',
            'OTCO_ANCO AS ANALISIS_COSTOS',
            'OTCO_DORE AS DOCUMENTOS_RELACIONADOS',
            'OTCO_CLAS AS CLASIFICACION',
            'OTCO_COME AS COMENTARIOS',
            'OTCO_GESE AS GERENCIA_SEGURIDAD',
            'OTCO_CAEX AS CAMPOS_EXTRA',
            'OTCO_ESOR AS ESTADO',
            'OTCO_USRE AS USUREG',
            'OTCO_FERE AS FECREG',
            'OTCO_USMO AS USUMOD',
            'OTCO_FEMO AS FECMOD'
        ])->join('S002V01TEQUI', 'EQUI_COEQ', '=', 'OTCO_EQIN')
        ->where([
            ['OTCO_IDOT', '=', $idOrder],
            ['OTCO_NULI', '=', $line]
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no está registrada.', [], 404);
        }
        
        $subcontratistTypes = ['S' => 'Subcontratista', 'U' => 'Usuario'];
        if($order->TIPO_RESPONSABLE == 'U'){
            $userResponsible = DB::table('S002V01TUSUA')->where([
                ['USUA_IDUS', '=', $order->ID_RESPONSABLE],
                ['USUA_NULI', '=', $line]
            ])->first();

            $userResponsibleName = $this->functionsController->joinName($userResponsible->USUA_NOMB, $userResponsible->USUA_APPA, $userResponsible->USUA_APMA);
            $order->ID_RESPONSABLE = $userResponsibleName . " (" . $order->ID_RESPONSABLE . ")";
        }else{
            $subcontratistResponsible = DB::table('S002V01TPESU')->where([
                ['PESU_NULI', '=', $line],
                ['PESU_IDPS', '=', $order->ID_RESPONSABLE]
            ])->first();

            $order->ID_RESPONSABLE = $subcontratistResponsible->PESU_RASO . " (" . $subcontratistResponsible->PESU_REFI . ") (" . $order->ID_RESPONSABLE . ")";
        }

        $order->TIPO_RESPONSABLE = $subcontratistTypes[$order->TIPO_RESPONSABLE];
        $order->ID_ORDEN = $this->encryptionController->encrypt($order->ID_ORDEN);
        $order->CODIGO_EQUIPAMIENTO = $this->encryptionController->encrypt($order->CODIGO_EQUIPAMIENTO);
        $order->ID_EQUIPAMIENTO = $this->encryptionController->encrypt($order->ID_EQUIPAMIENTO);
        $order->CONTADOR = $this->encryptionController->encrypt($order->CONTADOR);

        $measureArr = json_decode($order->MEDIDAS, true);
        $measureArr['CONTADOR'] = $this->encryptionController->encrypt($measureArr['CONTADOR']);
        $measureArr['ID_MEDIDA'] = $this->encryptionController->encrypt($measureArr['ID_MEDIDA']);
        $measureArr['ID_SERVICIO_WEB'] = $this->encryptionController->encrypt($measureArr['ID_SERVICIO_WEB']);

        $order->MEDIDAS = json_encode($measureArr);
        $order->PRIORIDAD = $this->encryptionController->encrypt($order->PRIORIDAD);
        $order->GERENCIA_SEGURIDAD = $this->encryptionController->encrypt($order->GERENCIA_SEGURIDAD);
        
        $staffArr = json_decode($order->PERSONAL, true);
        foreach($staffArr as $key=>$val){
            if($val['TYPE'] == 'EQ'){
                $workTeam = DB::table('S002V01TEQMA')->where([
                    ['EQMA_NULI', '=', $line],
                    ['EQMA_IDEQ', '=', $val['ID']]
                ])->first();

                $val['NAME'] = $workTeam->EQMA_NOMB . " (" . $val['ID'] . ")";
            }else if($val['TYPE'] == 'SU'){
                $subcontratist = DB::table('S002V01TPESU')->where([
                    ['PESU_NULI', '=', $line],
                    ['PESU_IDPS', '=', $val['ID']]
                ])->first();

                $val['NAME'] = $subcontratist->PESU_RASO . " (" . $subcontratist->PESU_REFI . ") (" . $val['ID'] . ")";
            }else if($val['TYPE'] == 'EM'){
                $employee = DB::table('S002V01TPERS')
                ->join('S002V01TUSUA', 'USUA_IDUS', '=', 'PERS_IDUS')
                ->where([
                    ['PERS_NULI', '=', $line],
                    ['PERS_IDPE', '=', $val['ID']]
                ])->first();

                $employeeName = $this->functionsController->joinName($employee->USUA_NOMB, $employee->USUA_APPA, $employee->USUA_APMA);
                $val['NAME'] = $employeeName . " (" . $employee->PERS_IDUS . ") (" . $val['ID'] . ")";;
            }
            $val['ID'] = $this->encryptionController->encrypt($val['ID']);
            $staffArr[$key] = $val;
        }
        
        $activationTypes = ['M' => 'Manual', 'A' => 'Automática'];
        $order->PERSONAL = json_encode($staffArr);
        $order->TIPO_ACTIVACION = $activationTypes[$order->TIPO_ACTIVACION];
        
        $orderStates = [
            'PE' => 'Pendiente',   'VA' => 'Validado', 'RE' => 'Rechazado', 
            'EP' => 'En progreso', 'CE' => 'Cerrado',  'CP' => 'Cerrado pendiente',
            'CA' => 'Cancelado',   'EL' => 'Eliminado'
        ];
        $order->ESTADO = $orderStates[$order->ESTADO];

        $documentsArr = json_decode($order->DOCUMENTOS_RELACIONADOS, true);
        $documentsFn = [];
        foreach($documentsArr as $document){
            $documentArr = explode('=', $document);
            $codeArr = explode('-', $documentArr[0]);
            $file = DB::table('S002V01TAFAL')->where([
                ['AFAL_NULI', '=', $line],
                ['AFAL_COMO', '=', $codeArr[1]],
                ['AFAL_CLDO', '=', $codeArr[2]],
                ['AFAL_FECR', '=', $codeArr[3]],
                ['AFAL_NUSE', '=', $codeArr[4]],
                ['AFAL_NUVE', '=', $documentArr[1]]
            ])->first();

            $documentsFn[] = [
                'id' => $this->encryptionController->encrypt($document),
                'name' => $file->AFAL_NOAR . '.' . $file->AFAL_EXTE,
                'size' => $file->AFAL_TAMA,
                'type' => 'Existente'
            ];
        }

        $order->DOCUMENTOS_RELACIONADOS = json_encode($documentsFn);
        $usrReg = DB::table('S002V01TUSUA')->where([
            ['USUA_IDUS', '=', $order->USUREG],
            ['USUA_NULI', '=', $line]
        ])->first();

        $nameReg = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
        $order->USUREG = $nameReg . " (" . $order->USUREG . ")";

        if(!is_null($order->USUMOD)){
            $usrMod = DB::table('S002V01TUSUA')->where([
                ['USUA_IDUS', '=', $order->USUMOD],
                ['USUA_NULI', '=', $line]
            ])->first();
    
            $nameMod = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA);
            $order->USUMOD = $nameMod . " (" . $order->USUMOD . ")";
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F01GEOP',
            'S002V01P01COOP',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los detalles de la orden #$idOrder de mantenimiento correctivo registradas.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $order);
    }

    public function updateWorkOrder(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'description' => 'required|string|min:15',
            'equipment' => 'required|string',
            'start_date_time' => 'required|date',
            'solution_time' => 'required|numeric',
            'priority' => 'required|string',
            'id_counter' => 'required|string',
            'id_last_measure' => 'required|string',
            'clasification' => 'required|string|max:50',
            'staff' => 'required|json',
            'security_management' => 'required|string',
            'activation_type' => 'required|string|in:Manual,Automática',
            'resources' => 'required|json',
            'attached' => 'json',
            'id_order' => 'required|string'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden no fue encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTCO')->where([
            ['OTCO_NULI', '=', $form['linea']],
            ['OTCO_IDOT', '=', $idOrder]
        ])->first();
        
        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }

        $equipmentCode = $this->encryptionController->decrypt($form['equipment']);
        if(!$equipmentCode){
            return $this->responseController->makeResponse(true, 'El código del equipamiento relacionado no fue encriptado correctamente.', [], 400);
        }

        $equipment = DB::table('S002V01TEQUI')->where([
            ['EQUI_NULI', '=', $form['linea']],
            ['EQUI_COEQ', '=', $equipmentCode],
        ])->first();
        
        if(is_null($equipment)){
            return $this->responseController->makeResponse(true, 'El equipamiento relacionado no existe.', [], 404);
        }

        if(floatval($form['solution_time']) <= 0){
            return $this->responseController->makeResponse(true, 'El tiempo de solución estimado debe ser mayor a cero.', [], 400);
        }

        $priority = $this->encryptionController->decrypt($form['priority']);
        if(!$priority){
            return $this->responseController->makeResponse(true, 'La prioridad relacionada no fue encriptada correctamente.', [], 400);
        }

        $validPriorities = ['1', '2', '3', '4'];
        if(!in_array($priority, $validPriorities)){
            return $this->responseController->makeResponse(true, 'La prioridad relacionada es inválida.', [], 400);
        }

        $idCounter = $this->encryptionController->decrypt($form['id_counter']);
        if(!$idCounter){
            return $this->responseController->makeResponse(true, 'El ID del contador relacionado no fue encriptado correctamente.', [], 400);
        }

        $counter = DB::table('S002V01TCONA')->where([
            ['CONA_IDCO', '=', $idCounter],
            ['CONA_NULI', '=', $form['linea']]
        ])->first();
        
        if(is_null($counter)){
            return $this->responseController->makeResponse(true, 'El contador relacionado no existe.', [], 404);
        }

        $idLastMeasure = $this->encryptionController->decrypt($form['id_last_measure']);
        if(!$idLastMeasure){
            return $this->responseController->makeResponse(true, 'El ID de la última medida del contador relacionado no fue encriptado correctamente.', [], 400);
        }

        $lastMeasure = DB::table('S002V01TMEDI')->select([
            'MEDI_IDME AS ID_MEDIDA',
            'MEDI_CORE AS CONTADOR',
            'MEDI_VALO AS VALOR',
            'MEDI_WSRE AS ID_SERVICIO_WEB',
            'LSWE_URLX AS URL_SERVICIO_WEB',
            'MEDI_HORE AS HORA_REGISTRO',
        ])->join('S002V01TLSWE', 'LSWE_IDSW', '=', 'MEDI_WSRE')->where([
            ['MEDI_IDME', '=', $idLastMeasure],
            ['MEDI_NULI', '=', $form['linea']],
            ['MEDI_CORE', '=', $idCounter]
        ])->orderBy('MEDI_HORE', 'desc')->first();
        
        if(is_null($lastMeasure)){
            return $this->responseController->makeResponse(true, 'La última medida del contador relacionado no existe.', [], 404);
        }

        $staffArr = json_decode($form['staff'], true);
        if(count($staffArr) == 0){
            return $this->responseController->makeResponse(true, 'El arreglo del personal está vacío.', [], 400);
        }

        $staffArrFn = [];
        foreach($staffArr as $key=>$item){
            $itemArr = explode('-', $item);
            $idDec = $this->encryptionController->decrypt($itemArr[0]);
            if(!$idDec){
                return $this->responseController->makeResponse(true, "El ID en la posición $key del arreglo del personal no fue encriptado correctamente.", [], 400);
            }

            if($itemArr[1] == 'EQ'){
                $workTeam = DB::table('S002V01TEQMA')->where([
                    ['EQMA_IDEQ', '=', $idDec],
                    ['EQMA_NULI', '=', $form['linea']]
                ])->first();

                if(is_null($workTeam)){
                    return $this->responseController->makeResponse(true, "El equipo de trabajo en la posición $key del arreglo del personal no existe.", [], 404);
                }else if($workTeam->EQMA_ESTA == 'Eliminado'){
                    return $this->responseController->makeResponse(true, "El equipo de trabajo en la posición $key del arreglo del personal está eliminado.", [], 404);
                }

                $staffArrFn[] = [
                    'ID' => $idDec,
                    'TYPE' => $itemArr[1]
                ];
            }else if($itemArr[1] == 'SU'){
                $subcontratist = DB::table('S002V01TPESU')->where([
                    ['PESU_IDPS', '=', $idDec],
                    ['PESU_NULI', '=', $form['linea']]
                ])->first();

                if(is_null($subcontratist)){
                    return $this->responseController->makeResponse(true, "El subcontratista en la posición $key del arreglo del personal no existe.", [], 404);
                }else if($subcontratist->PESU_ESTA == 'Eliminado'){
                    return $this->responseController->makeResponse(true, "El subcontratista en la posición $key del arreglo del personal está eliminado.", [], 404);
                }

                $staffArrFn[] = [
                    'ID' => $idDec,
                    'TYPE' => $itemArr[1]
                ];
            }else if($itemArr[1] == 'EM'){
                $employee = DB::table('S002V01TPERS')->where([
                    ['PERS_IDPE', '=', $idDec],
                    ['PERS_NULI', '=', $form['linea']]
                ])->first();

                if(is_null($employee)){
                    return $this->responseController->makeResponse(true, "El empleado en la posición $key del arreglo del personal no existe.", [], 404);
                }else if($employee->PERS_ESTA == 'Eliminado'){
                    return $this->responseController->makeResponse(true, "El empleado en la posición $key del arreglo del personal está eliminado.", [], 404);
                }

                $staffArrFn[] = [
                    'ID' => $idDec,
                    'TYPE' => $itemArr[1]
                ];
            }
        }

        $staffStrFn = json_encode($staffArrFn);
        $idManagement = $this->encryptionController->decrypt($form['security_management']);
        if(!$idManagement){
            return $this->responseController->makeResponse(true, 'El ID de la gerencia de seguridad no está encriptado correctamente', [], 400);
        }

        $management = DB::table('S002V01TGESE')->where([
            ['GESE_NULI', '=', $form['linea']],
            ['GESE_IDGS', '=', $idManagement]
        ])->first();

        if(is_null($management)){
            return $this->responseController->makeResponse(true, 'La gerencia de seguridad seleccionada no está registrada.', [], 404);
        }
        //PENDIENTE REVISAR LOS RECURSOS

        $attachedArrFn = [];
        if(isset($form['attached'])){
            $attachedArr = json_decode($form['attached'], true);
            foreach($attachedArr as $key=>$attached){
                $idDec = $this->encryptionController->decrypt($attached['id']);
                if(!$idDec){
                    return $this->responseController->makeResponse(true, "El ID del documento en la posición $key no fue encriptado correctamente.", [], 400);
                }

                if($attached['type'] == 'Existente'){
                    $codeArr = explode('=', $idDec);
                    $codeArr0 = explode('-', $codeArr[0]);

                    $file = DB::table('S002V01TAFAL')->where([
                        ['AFAL_NULI', '=', $form['linea']],
                        ['AFAL_COMO', '=', $codeArr0[1]],
                        ['AFAL_CLDO', '=', $codeArr0[2]],
                        ['AFAL_FECR', '=', $codeArr0[3]],
                        ['AFAL_NUSE', '=', $codeArr0[4]],
                        ['AFAL_NUVE', '=', $codeArr[1]],
                    ])->first();

                    if(is_null($file)){
                        return $this->responseController->makeResponse(true, "El documento en la posición $key no existe.", [], 404);
                    }else if($file->AFAL_ESTA == 'Eliminado'){
                        return $this->responseController->makeResponse(true, "El documento en la posición $key está eliminado.", [], 404);
                    }

                    $attachedArrFn[] = $idDec;
                }else if($attached['type'] == 'Nuevo'){
                    $tempFile = DB::table('S002V01TARTE')->where([
                        ['ARTE_IDAR', '=', $idDec],
                        ['ARTE_NULI', '=', $form['linea']]
                    ])->first();

                    if(is_null($tempFile)){
                        return $this->responseController->makeResponse(true, "El documento en la posición $key no existe.", [], 404);
                    }else if($tempFile->ARTE_ESTA == 'Eliminado'){
                        return $this->responseController->makeResponse(true, "El documento en la posición $key está eliminado.", [], 404);
                    }

                    $finalFile = $this->documentManagementController->moveFinalFile($form['linea'], 'GMCO', 'OR', $tempFile, $idUser);
                    if(!$finalFile){
                        return $this->responseController->makeResponse(true, $finalFile[1], [], 400);
                    }else{
                        $attachedArrFn[] = $finalFile[1];
                    }
                }
            }
        }

        $activationType = $form['activation_type'][0];
        $attachedStrFn = json_encode($attachedArrFn);
        $lastMeasureStr = json_encode($lastMeasure);

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        DB::table('S002V01TOTCO')->where([
            ['OTCO_IDOT', '=', $idOrder],
            ['OTCO_NULI', '=', $form['linea']]
        ])->update([
            'OTCO_DEIN' => $form['description'],
            'OTCO_EQIN' => $equipmentCode,
            'OTCO_FIFA' => $form['start_date_time'],
            'OTCO_TESO' => $form['solution_time'],
            'OTCO_CORE' => $idCounter,
            'OTCO_DRCO' => $lastMeasureStr ,
            'OTCO_PRIO' => $priority,
            'OTCO_FTIN' => $order->OTCO_FTIN,
            'OTCO_DTIN' => $order->OTCO_DTIN,
            'OTCO_RHUT' => $form['resources'],
            'OTCO_PEIN' => $staffStrFn,
            'OTCO_TIAC' => $activationType,
            'OTCO_ANCO' => $order->OTCO_ANCO,
            'OTCO_DORE' => $attachedStrFn,
            'OTCO_CLAS' => $form['clasification'],
            'OTCO_COME' => $order->OTCO_COME,
            'OTCO_GESE' => $idManagement,
            'OTCO_CAEX' => $order->OTCO_CAEX,
            'OTCO_ESOR' => $order->OTCO_ESOR,
            'OTCO_USMO' => $idUser,
            'OTCO_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F04GEOT',
            'S002V01P01GEOT',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó la orden de trabajo correctivo #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function deleteWorkOrder(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden no fue encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTCO')->where([
            ['OTCO_NULI', '=', $form['linea']],
            ['OTCO_IDOT', '=', $idOrder]
        ])->first();
        
        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        $statusHistoryArr = json_decode($order->OTCO_HIES, true);
        $statusHistoryArr[] = ['USUARIO' => $idUser, 'ESTADO' => 'EL', 'FECHA' => $nowStr];
        $statusHistoryStr = json_encode($statusHistoryArr);

        DB::table('S002V01TOTCO')->where([
            ['OTCO_IDOT', '=', $idOrder],
            ['OTCO_NULI', '=', $form['linea']]
        ])->update([
            'OTCO_ESOR' => 'EL',
            'OTCO_HIES' => $statusHistoryStr,
            'OTCO_USMO' => $idUser,
            'OTCO_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F04GEOT',
            'S002V01P01GEOT',
            'Eliminación',
            "El usuario $name (" . $usr->USUA_IDUS . ") eliminó la orden de trabajo correctivo #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function approveWorkOrder(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden no fue encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTCO')->where([
            ['OTCO_NULI', '=', $form['linea']],
            ['OTCO_IDOT', '=', $idOrder]
        ])->first();
        
        $orderStates = [
            'PE' => 'Pendiente',   'VA' => 'Validado', 'RE' => 'Rechazado', 
            'EP' => 'En progreso', 'CE' => 'Cerrado',  'CP' => 'Cerrado pendiente',
            'CA' => 'Cancelado',   'EL' => 'Eliminado'
        ];
        
        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }else if($order->OTCO_ESOR == 'EL'){
            return $this->responseController->makeResponse(true, 'La orden solicitada está eliminada.', [], 404);
        }else if($order->OTCO_ESOR != 'PE'){
            $status = $orderStates[$order->OTCO_ESOR];
            return $this->responseController->makeResponse(true, "La orden está $status.", [], 401);
        }

        $staffArr = json_decode($order->OTCO_PEIN, true);
        $audience = [];

        foreach($staffArr as $item){
            if($item['TYPE'] == 'EQ'){
                $employees = DB::table('S002V01TPERS')->where([
                    ['PERS_NULI', '=', $form['linea']],
                    ['PERS_EQTR', '=', $item['ID']]
                ])->get()->all();

                foreach($employees as $employee){
                    if(!in_array($employee->PERS_IDUS, $audience)){
                        $audience[] = $employee->PERS_IDUS;
                    }
                }
            }else if($item['TYPE'] == 'SU'){
                $employees = DB::table('S002V01TPERS')->where([
                    ['PERS_NULI', '=', $form['linea']],
                    ['PERS_IDPS', '=', $item['ID']]
                ])->get()->all();

                foreach($employees as $employee){
                    if(!in_array($employee->PERS_IDUS, $audience)){
                        $audience[] = $employee->PERS_IDUS;
                    }
                }
            }else if($item['TYPE'] == 'EM'){
                $employee = DB::table('S002V01TPERS')->where([
                    ['PERS_NULI', '=', $form['linea']],
                    ['PERS_IDPE', '=', $item['ID']]
                ])->first();

                if(!in_array($employee->PERS_IDUS, $audience)){
                    $audience[] = $employee->PERS_IDUS;
                }
            }
        }

        $this->notificationsController->emitNotification(
            'S002V01M09GMCO',
            "Orden de mantenimiento correctivo #$idOrder",
            "Se ha generado la orden de mantenimiento correctivo #$idOrder y requiere su atención.",
            [],
            $audience,
            $idUser, 
            $form['linea'],
            $this->socketClient,
            $idOrder,
            'Correctivo'
        );

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        $statusHistoryArr = json_decode($order->OTCO_HIES, true);
        $statusHistoryArr[] = ['USUARIO' => $idUser, 'ESTADO' => 'VA', 'FECHA' => $nowStr];
        $statusHistoryStr = json_encode($statusHistoryArr);

        DB::table('S002V01TOTCO')->where([
            ['OTCO_IDOT', '=', $idOrder],
            ['OTCO_NULI', '=', $form['linea']]
        ])->update([
            'OTCO_ESOR' => 'VA',
            'OTCO_HIES' => $statusHistoryStr,
            'OTCO_USMO' => $idUser,
            'OTCO_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F04GEOT',
            'S002V01P01GEOT',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") validó la orden de trabajo correctivo #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function startWorkOrder(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden no fue encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTCO')->where([
            ['OTCO_NULI', '=', $form['linea']],
            ['OTCO_IDOT', '=', $idOrder]
        ])->first();
        
        $orderStates = [
            'PE' => 'Pendiente',   'VA' => 'Validado', 'RE' => 'Rechazado', 
            'EP' => 'En progreso', 'CE' => 'Cerrado',  'CP' => 'Cerrado pendiente',
            'CA' => 'Cancelado',   'EL' => 'Eliminado'
        ];
        
        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }else if($order->OTCO_ESOR == 'EL'){
            return $this->responseController->makeResponse(true, 'La orden solicitada está eliminada.', [], 404);
        }else if($order->OTCO_ESOR != 'VA'){
            $status = $orderStates[$order->OTCO_ESOR];
            return $this->responseController->makeResponse(true, "La orden está $status.", [], 401);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        $statusHistoryArr = json_decode($order->OTCO_HIES, true);
        $statusHistoryArr[] = ['USUARIO' => $idUser, 'ESTADO' => 'EP', 'FECHA' => $nowStr];
        $statusHistoryStr = json_encode($statusHistoryArr);

        DB::table('S002V01TOTCO')->where([
            ['OTCO_IDOT', '=', $idOrder],
            ['OTCO_NULI', '=', $form['linea']]
        ])->update([
            'OTCO_ESOR' => 'EP',
            'OTCO_HIES' => $statusHistoryStr,
            'OTCO_USMO' => $idUser,
            'OTCO_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F04GEOT',
            'S002V01P01GEOT',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") inició la orden de trabajo correctivo #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function updateWorkOrderStatus(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string',
            'status' => 'required|string|in:RE,CE,CA',
            'comments' => 'required|string|min:15'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden no fue encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTCO')->where([
            ['OTCO_NULI', '=', $form['linea']],
            ['OTCO_IDOT', '=', $idOrder]
        ])->first();
        
        $orderStates = [
            'PE' => 'Pendiente',   'VA' => 'Validado', 'RE' => 'Rechazado', 
            'EP' => 'En progreso', 'CE' => 'Cerrado',  'CP' => 'Cerrado pendiente',
            'CA' => 'Cancelado',   'EL' => 'Eliminado'
        ];
        
        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }else if($order->OTCO_ESOR == 'EL'){
            return $this->responseController->makeResponse(true, 'La orden solicitada está eliminada.', [], 404);
        }
        
        $status = $form['status'];
        switch($status){
            case 'RE': 
                if($order->OTCO_ESOR != 'PE'){
                    $status = $orderStates[$order->OTCO_ESOR];
                    return $this->responseController->makeResponse(true, "La orden está $status.", [], 401);
                }
            break;
            case 'CE':
                if($order->OTCO_ESOR != 'EP' && $order->OTCO_ESOR != 'CP'){
                    $status = $orderStates[$order->OTCO_ESOR];
                    return $this->responseController->makeResponse(true, "La orden está $status.", [], 401);
                }
            break;
            case 'CA':
                if($order->OTCO_ESOR != 'VA'){
                    $status = $orderStates[$order->OTCO_ESOR];
                    return $this->responseController->makeResponse(true, "La orden está $status.", [], 401);
                }
            break;
        }

        $message = '';
        if($status == 'CE' && is_null($order->OTCO_ANCO)){
            $status = 'CP';
            $message = 'La orden no puede cerrarse complentamente hasta asignar el análisis de costos.';
        }else{
            $message = 'Actualización correcta.';
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();

        $ftin = null;
        $dtin = null;
        if(($status == 'CE' || $status == 'CP') && is_null($order->OTCO_FTIN)){
            $ftin = $nowStr;
            $startDate = new Carbon($order->OTCO_FIFA);

            $diffInSecs = $now->diffInSeconds($startDate);
            $diffInMins = $this->functionsController->floatDiv($diffInSecs, 60);
            $dtin = $this->functionsController->floatDiv($diffInMins, 60);
        }else{
            $ftin = $order->OTCO_FTIN;
            $dtin = $order->OTCO_DTIN;
        }

        $statusHistoryArr = json_decode($order->OTCO_HIES, true);
        $statusHistoryArr[] = ['USUARIO' => $idUser, 'ESTADO' => $status, 'FECHA' => $nowStr];
        $statusHistoryStr = json_encode($statusHistoryArr);

        DB::table('S002V01TOTCO')->where([
            ['OTCO_IDOT', '=', $idOrder],
            ['OTCO_NULI', '=', $form['linea']]
        ])->update([
            'OTCO_ESOR' => $status,
            'OTCO_COME' => $form['comments'],
            'OTCO_HIES' => $statusHistoryStr,
            'OTCO_FTIN' => $ftin,
            'OTCO_DTIN' => $dtin,
            'OTCO_USMO' => $idUser,
            'OTCO_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F04GEOT',
            'S002V01P01GEOT',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó el estado de la orden de trabajo correctivo #$idOrder.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, "EXITO: $message");
    }

    public function getWorkOrderClasifications($idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $clasifications = DB::table('S002V01TOTCO')->select([
            DB::raw('DISTINCT(OTCO_CLAS) AS CLASIFICACION')
        ])->get()->all();

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F01GEOP',
            'S002V01P01COOP',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las clasificaciones registradas.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $clasifications);
    }

    public function getResponsibleUsers($idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $profiles = DB::table('S002V01TPERF')->where('PERF_NULI', '=', $line)->get()->all();
        $profilesWithAccess = [];
        foreach($profiles as $profile){
            $permissions = json_decode($profile->PERF_PERM, true);
            $permissionsArr = $permissions['permissions'];
            $correctiveMaintenanceFilt = array_filter($permissionsArr, function($v, $k) {
                return $v['id'] == 'S002V01M09GMCO';
            }, ARRAY_FILTER_USE_BOTH);
            
            $correctiveMaintenance = end($correctiveMaintenanceFilt);
            if(intval($correctiveMaintenance['access']) > 0){
                $submodules = $correctiveMaintenance['children'];
                $workOrdersFilt = array_filter($submodules, function($v, $k) {
                    return $v['id'] == 'S002V01S01ORTR';
                }, ARRAY_FILTER_USE_BOTH);

                $workOrders = end($workOrdersFilt);
                if(intval($workOrders['access']) > 0){
                    $functions = $workOrders['children'];
                    $operationsManagementFilt = array_filter($functions, function($v, $k) {
                        return $v['id'] == 'S002V01F01GEOP';
                    }, ARRAY_FILTER_USE_BOTH);

                    $operationsManagement = end($operationsManagementFilt);
                    if(intval($operationsManagement['access']) > 0){
                        $profilesWithAccess[] = $profile->PERF_IDPE;
                    }
                }
            }
        }

        $usersWithAccess = [];
        foreach($profilesWithAccess as $idProfile){
            $users = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_PERF', '=', $idProfile],
                ['USUA_ESTA', '=', 'Activo']
            ])->get()->all();

            foreach($users as $user){
                $userName = $this->functionsController->joinName($user->USUA_NOMB, $user->USUA_APPA, $user->USUA_APMA);
                $usersWithAccess[] = [
                    'ID' => $this->encryptionController->encrypt($user->USUA_IDUS),
                    'NOMBRE' => $userName,
                ];
            }
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F01GEOP',
            'S002V01P01COOP',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los usuarios con acceso a la gestión de las operaciones.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $usersWithAccess);
    }

    public function transferWorkOrder(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_order' => 'required|string',
            'id_new_user' => 'required|string',
            'type' => 'required|string|in:U,S'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($form['id_order']);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden no fue encriptado correctamente.', [], 400);
        }

        $order = DB::table('S002V01TOTCO')->where([
            ['OTCO_NULI', '=', $form['linea']],
            ['OTCO_IDOT', '=', $idOrder]
        ])->first();
        
        $orderStates = [
            'PE' => 'Pendiente',   'VA' => 'Validado', 'RE' => 'Rechazado', 
            'EP' => 'En progreso', 'CE' => 'Cerrado',  'CP' => 'Cerrado pendiente',
            'CA' => 'Cancelado',   'EL' => 'Eliminado'
        ];
        
        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no existe.', [], 404);
        }else if($order->OTCO_ESOR == 'EL'){
            return $this->responseController->makeResponse(true, 'La orden solicitada está eliminada.', [], 404);
        }else if($order->OTCO_ESOR != 'PE'){
            $status = $orderStates[$order->OTCO_ESOR];
            return $this->responseController->makeResponse(true, "La orden está $status.", [], 401);
        }

        if($order->OTCO_TURE == 'U' && $order->OTCO_IDUR != $idUser){
            return $this->responseController->makeResponse(true, "El usuario que realizó la solicitud no es el responsable de atenderla.", [], 401);
        }else if($order->OTCO_TURE == 'S'){
            $users = DB::table('S002V01TPERS')->where([
                ['PERS_NULI', '=', $form['linea']],
                ['PERS_TICO', '=', 'Subcontratista'],
                ['PERS_IDPS', '=', $order->OTCO_IDUR],
            ])->get()->all();

            $enabledUsers = [];
            foreach($users as $user){
                $enabledUsers[] = $user->PERS_IDUS;
            }

            if(!in_array($idUser, $enabledUsers)){
                return $this->responseController->makeResponse(true, "El usuario que realizó la solicitud no es el responsable de atenderla.", [], 401);
            }
        }

        $audience = [];
        $idNewUser = $this->encryptionController->decrypt($form['id_new_user']);
        if(!$idNewUser){
            return $this->responseController->makeResponse(true, 'El ID del nuevo encargado no fue encriptado correctamente.', [], 400);
        }

        if($form['type'] == 'U'){
            $newUser = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $form['linea']],
                ['USUA_IDUS', '=', $idNewUser]
            ])->first();
        
            if(is_null($newUser)){
                return $this->responseController->makeResponse(true, 'El usuario seleccionado no existe.', [], 404);
            }
            
            $audience[] = $idNewUser;
        }else if($form['type'] == 'S'){
            $subcontratist = DB::table('S002V01TPESU')->where([
                ['PESU_IDPS', '=', $idNewUser],
                ['PESU_NULI', '=', $form['linea']]
            ])->first();
        
            if(is_null($subcontratist)){
                return $this->responseController->makeResponse(true, 'El subcontratista seleccionado no existe.', [], 404);
            }
            
            $users = DB::table('S002V01TPERS')->where([
                ['PERS_NULI', '=', $form['linea']],
                ['PERS_TICO', '=', 'Subcontratista'],
                ['PERS_IDPS', '=', $idNewUser],
            ])->get()->all();

            foreach($users as $user){
                $audience[] = $user->PERS_IDUS;
            }
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TOTCO')->where([
            ['OTCO_NULI', '=', $form['linea']],
            ['OTCO_IDOT', '=', $idOrder]
        ])->update([
            'OTCO_IDUR' => $idNewUser,
            'OTCO_TURE' => $form['type'],
            'OTCO_USMO' => $idUser,
            'OTCO_FEMO' => $nowStr
        ]);

        $this->notificationsController->emitNotification(
            'S002V01M09GMCO',
            "Orden de mantenimiento correctivo #$idOrder",
            "Su usuario ha sido asignado como responsable de atender la orden de mantenimiento #$idOrder.",
            [[
                'BOTON' => 'Ver detalles',
                'FUNCION' => 'openCorrectiveWorkOrderDetails',
                'PARAMETROS' => json_encode([$this->encryptionController->encrypt($idOrder)])
            ], [
                'BOTON' => 'Validar orden',
                'FUNCION' => 'validateCorrectiveWorkOrder',
                'PARAMETROS' => json_encode([$this->encryptionController->encrypt($idOrder)])
            ], [
                'BOTON' => 'Ir al módulo',
                'FUNCION' => 'openModule',
                'PARAMETROS' => json_encode([$this->encryptionController->encrypt('GMCO/ORTR/GEOP')])
            ]],
            $audience,
            $idUser, 
            $form['linea'],
            $this->socketClient,
            $idOrder,
            'Correctivo'
        );

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F06TROT',
            '-',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") traspasó la orden de trabajo correctivo al usuario o subcontratista #$idNewUser.",
            $idUser,
            $nowStr,
            'S002V01S01ORTR'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function registerSecurityManagement(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'lada1' => 'required|string|max:8',
            'phone1' => 'required|string|min:10|max:11',
            'ext1' => 'string|max:5',
            'lada2' =>'string|max:8',
            'phone2' => 'string|min:10|max:11',
            'ext2' => 'string|max:5',
            'email' => 'required|string|max:150',
            'id_manager' => 'required|string',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idManager = $this->encryptionController->decrypt($form['id_manager']);
        if(!$idManager){
            return $this->responseController->makeResponse(true, 'El ID del gerente no fue encriptado correctamente.', [], 400);
        }

        $manager = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idManager]
        ])->first();
        
        if(is_null($manager)){
            return $this->responseController->makeResponse(true, 'El usuario seleccionado como gerente no existe.', [], 404);
        }

        $email = $form['email'];
        if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
            return $this->responseController->makeResponse(true, 'El formato del correo electrónico enviado es inválido.', [], 400);
        }

        $emailVerified = DB::table('S002V01TGESE')->where([
            ['GESE_NULI', '=', $form['linea']],
            ['GESE_COEL', '=', $email]
        ])->get()->all();

        if(count($emailVerified) > 0){
            return $this->responseController->makeResponse(true, 'El correo electrónico enviado ya ha sido registrado.', [], 400);
        }

        $lada1 = DB::table('S002V01TPAIS')->where([
            ['PAIS_NULI', '=', $form['linea']],
            ['PAIS_LADA', '=', $form['lada1']]
        ])->first();
        
        if(is_null($lada1)){
            return $this->responseController->makeResponse(true, 'La lada seleccionada para el teléfono principal es inválida.', [], 400);
        }else if(!$this->functionsController->validPhoneNumber($form['phone1'])){
            return $this->responseController->makeResponse(true, 'El número de teléfono principal es inválido.', [], 400);
        }else if(isset($form['ext1']) && !is_numeric($form['ext1'])){
            return $this->responseController->makeResponse(true, 'La extensión de teléfono principal es inválida.', [], 400);
        }

        $ext1 = isset($form['ext1']) ? $form['ext1']: null;
        $lad2 = null;
        $tel2 = null;
        $ext2 = null;
        if(isset($form['lada2']) || isset($form['phone2'])){
            if(!isset($form['lada2']) || !isset($form['phone2'])){
                if(!isset($form['lada2'])){
                    return $this->responseController->makeResponse(true, 'La lada del teléfono secundario es obligatoria cuando se envía el teléfono o la extensión secundarios', [], 400);
                }

                if(!isset($form['phone2'])){
                    return $this->responseController->makeResponse(true, 'El teléfono secundario es obligatorio cuando se envía la lada o la extensión secundarias', [], 400);
                }
            }

            $lada2 = DB::table('S002V01TPAIS')->where([
                ['PAIS_NULI', '=', $form['linea']],
                ['PAIS_LADA', '=', $form['lada2']]
            ])->first();
        
            if(is_null($lada2)){
                return $this->responseController->makeResponse(true, 'La lada seleccionada para el teléfono secundario es inválida.', [], 400);
            }else if(!$this->functionsController->validPhoneNumber($form['phone2'])){
                return $this->responseController->makeResponse(true, 'El número de teléfono secundario es inválido.', [], 400);
            }else if(isset($form['ext2']) && !is_numeric($form['ext2'])){
                return $this->responseController->makeResponse(true, 'La extensión de teléfono secundario es inválida.', [], 400);
            }

            $lad2 = $form['lada2'];
            $tel2 = $form['phone2'];
            $ext2 = isset($form['ext2']) ? $form['ext2'] : null;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $idManagement = DB::table('S002V01TGESE')->insertGetId([
            'GESE_NULI' => $form['linea'],
            'GESE_LAD1' => $form['lada1'],
            'GESE_TEL1' => $form['phone1'],
            'GESE_EXT1' => $ext1,
            'GESE_LAD2' => $lad2,
            'GESE_TEL2' => $tel2,
            'GESE_EXT2' => $ext2,
            'GESE_COEL' => $email,
            'GESE_GERE' => $idManager,
            'GESE_USRE' => $idUser,
            'GESE_FERE' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F03GESE',
            'S002V01P02GSAU',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró la gerencia de seguridad #$idManagement.",
            $idUser,
            $nowStr,
            'S002V01S02GEME'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function getSegurityManagements($idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $securityManagements = DB::table('S002V01TGESE')->select([
            'GESE_IDGS AS ID_GERENCIA_SEGURIDAD',
            'GESE_LAD1 AS LADA_TELEFONO_PRINCIPAL',
            'GESE_TEL1 AS TELEFONO_PRINCIPAL',
            'GESE_EXT1 AS EXTENSION_TELEFONO_PRINCIPAL',
            'GESE_LAD2 AS LADA_TELEFONO_SECUNDARIO',
            'GESE_TEL2 AS TELEFONO_SECUNDARIO',
            'GESE_EXT2 AS EXTENSION_TELEFONO_SECUNDARIO',
            'GESE_COEL AS CORREO_GERENCIA',
            'GESE_GERE AS GERENTE',
            'GESE_ESTA AS ESTADO',
            'GESE_USRE AS USUREG',
            'GESE_FERE AS FECREG',
            'GESE_USMO AS USUMOD',
            'GESE_FEMO AS FECMOD'
        ])->where('GESE_NULI', '=', $line)->get()->all();

        foreach($securityManagements as $key=>$item){
            $workOrders = DB::table('S002V01TOTCO')->where([
                ['OTCO_NULI', '=', $line],
                ['OTCO_GESE', '=', $item->ID_GERENCIA_SEGURIDAD]
            ])->get()->all();
            
            $item->NUMERO_ORDENES = count($workOrders);
            $item->ID_GERENCIA_SEGURIDAD = $this->encryptionController->encrypt($item->ID_GERENCIA_SEGURIDAD);
            $manager = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $item->GERENTE]
            ])->first();

            $managerName = $this->functionsController->joinName($manager->USUA_NOMB, $manager->USUA_APPA, $manager->USUA_APMA);
            $item->GERENTE = $managerName . " (" . $item->GERENTE . ")";

            $usrReg = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $item->USUREG]
            ])->first();

            $usrRegName = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
            $item->USUREG = $usrRegName . " (" . $item->USUREG . ")";

            if(!is_null($item->USUMOD)){
                $usrMod = DB::table('S002V01TUSUA')->where([
                    ['USUA_NULI', '=', $line],
                    ['USUA_IDUS', '=', $item->USUMOD]
                ])->first();

                $usrModName = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA);
                $item->USUMOD = $usrModName . " (" . $item->USUMOD . ")";
            }

            $securityManagements[$key] = $item;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F03GESE',
            'S002V01P02GSAU',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó las gerencias de seguridad registradas.",
            $idUser,
            $nowStr,
            'S002V01S02GEME'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $securityManagements);
    }

    public function getSecurityManagement($idManagement, $idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $idManagement = $this->encryptionController->decrypt($idManagement);
        if(!$idManagement){
            return $this->responseController->makeResponse(true, 'El ID de la gerencia de seguridad no está encriptado correctamente', [], 400);
        }

        $management = DB::table('S002V01TGESE')->select([
            'GESE_IDGS AS ID_GERENCIA_SEGURIDAD',
            'GESE_LAD1 AS LADA_TELEFONO_PRINCIPAL',
            'GESE_TEL1 AS TELEFONO_PRINCIPAL',
            'GESE_EXT1 AS EXTENSION_TELEFONO_PRINCIPAL',
            'GESE_LAD2 AS LADA_TELEFONO_SECUNDARIO',
            'GESE_TEL2 AS TELEFONO_SECUNDARIO',
            'GESE_EXT2 AS EXTENSION_TELEFONO_SECUNDARIO',
            'GESE_COEL AS CORREO_GERENCIA',
            'GESE_GERE AS GERENTE',
            'GESE_ESTA AS ESTADO',
            'GESE_USRE AS USUREG',
            'GESE_FERE AS FECREG',
            'GESE_USMO AS USUMOD',
            'GESE_FEMO AS FECMOD'
        ])->where([
            ['GESE_NULI', '=', $line],
            ['GESE_IDGS', '=', $idManagement]
        ])->first();

        if(is_null($management)){
            return $this->responseController->makeResponse(true, 'La gerencia de seguridad consultada no está registrada.', [], 404);
        }

        $workOrders = DB::table('S002V01TOTCO')->select([
            'OTCO_IDOT AS ID_ORDEN'
        ])->where([
            ['OTCO_NULI', '=', $line],
            ['OTCO_GESE', '=', $idManagement]
        ])->get()->all();

        foreach($workOrders as $key=>$order){
            $order->ID_ORDEN = $this->encryptionController->encrypt($order->ID_ORDEN);
            $workOrders[$key] = $order;
        }

        $management->ORDENES_TRABAJO = $workOrders;
        $management->ID_GERENCIA_SEGURIDAD = $this->encryptionController->encrypt($management->ID_GERENCIA_SEGURIDAD);
        $manager = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $management->GERENTE]
        ])->first();

        $managerName = $this->functionsController->joinName($manager->USUA_NOMB, $manager->USUA_APPA, $manager->USUA_APMA);
        $management->GERENTE = $managerName . " (" . $management->GERENTE . ")";

        $usrReg = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $management->USUREG]
        ])->first();

        $usrRegName = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
        $management->USUREG = $usrRegName . " (" . $management->USUREG . ")";

        if(!is_null($management->USUMOD)){
            $usrMod = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $management->USUMOD]
            ])->first();

            $usrModName = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA);
            $management->USUMOD = $usrModName . " (" . $management->USUMOD . ")";
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F03GESE',
            'S002V01P02GSAU',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó la gerencias de seguridad #$idManagement.",
            $idUser,
            $nowStr,
            'S002V01S02GEME'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $management);
    }

    public function updateSecurityManagement(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'lada1' => 'required|string|max:8',
            'phone1' => 'required|string|min:10|max:11',
            'ext1' => 'string|max:5',
            'lada2' =>'string|max:8',
            'phone2' => 'string|min:10|max:11',
            'ext2' => 'string|max:5',
            'email' => 'required|string|max:150',
            'id_manager' => 'required|string',
            'id_management' => 'required|string',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idManagement = $this->encryptionController->decrypt($form['id_management']);
        if(!$idManagement){
            return $this->responseController->makeResponse(true, 'El ID de la gerencia de seguridad no está encriptado correctamente', [], 400);
        }

        $management = DB::table('S002V01TGESE')->where([
            ['GESE_NULI', '=', $form['linea']],
            ['GESE_IDGS', '=', $idManagement]
        ])->first();

        if(is_null($management)){
            return $this->responseController->makeResponse(true, 'La gerencia de seguridad consultada no está registrada.', [], 404);
        }

        $idManager = $this->encryptionController->decrypt($form['id_manager']);
        if(!$idManager){
            return $this->responseController->makeResponse(true, 'El ID del gerente no fue encriptado correctamente.', [], 400);
        }

        $manager = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idManager]
        ])->first();
        
        if(is_null($manager)){
            return $this->responseController->makeResponse(true, 'El usuario seleccionado como gerente no existe.', [], 404);
        }

        $email = $form['email'];
        if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
            return $this->responseController->makeResponse(true, 'El formato del correo electrónico enviado es inválido.', [], 400);
        }

        $emailVerified = DB::table('S002V01TGESE')->where([
            ['GESE_NULI', '=', $form['linea']],
            ['GESE_COEL', '=', $email],
            ['GESE_IDGS', '!=', $idManagement]
        ])->get()->all();

        if(count($emailVerified) > 0){
            return $this->responseController->makeResponse(true, 'El correo electrónico enviado ya ha sido registrado.', [], 400);
        }

        $lada1 = DB::table('S002V01TPAIS')->where([
            ['PAIS_NULI', '=', $form['linea']],
            ['PAIS_LADA', '=', $form['lada1']]
        ])->first();
        
        if(is_null($lada1)){
            return $this->responseController->makeResponse(true, 'La lada seleccionada para el teléfono principal es inválida.', [], 400);
        }else if(!$this->functionsController->validPhoneNumber($form['phone1'])){
            return $this->responseController->makeResponse(true, 'El número de teléfono principal es inválido.', [], 400);
        }else if(isset($form['ext1']) && !is_numeric($form['ext1'])){
            return $this->responseController->makeResponse(true, 'La extensión de teléfono principal es inválida.', [], 400);
        }

        $ext1 = isset($form['ext1']) ? $form['ext1']: null;
        $lad2 = null;
        $tel2 = null;
        $ext2 = null;
        if(isset($form['lada2']) || isset($form['phone2'])){
            if(!isset($form['lada2']) || !isset($form['phone2'])){
                if(!isset($form['lada2'])){
                    return $this->responseController->makeResponse(true, 'La lada del teléfono secundario es obligatoria cuando se envía el teléfono o la extensión secundarios', [], 400);
                }

                if(!isset($form['phone2'])){
                    return $this->responseController->makeResponse(true, 'El teléfono secundario es obligatorio cuando se envía la lada o la extensión secundarias', [], 400);
                }
            }

            $lada2 = DB::table('S002V01TPAIS')->where([
                ['PAIS_NULI', '=', $form['linea']],
                ['PAIS_LADA', '=', $form['lada2']]
            ])->first();
        
            if(is_null($lada2)){
                return $this->responseController->makeResponse(true, 'La lada seleccionada para el teléfono secundario es inválida.', [], 400);
            }else if(!$this->functionsController->validPhoneNumber($form['phone2'])){
                return $this->responseController->makeResponse(true, 'El número de teléfono secundario es inválido.', [], 400);
            }else if(isset($form['ext2']) && !is_numeric($form['ext2'])){
                return $this->responseController->makeResponse(true, 'La extensión de teléfono secundario es inválida.', [], 400);
            }

            $lad2 = $form['lada2'];
            $tel2 = $form['phone2'];
            $ext2 = isset($form['ext2']) ? $form['ext2'] : null;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TGESE')->where([
            ['GESE_NULI', '=', $form['linea']],
            ['GESE_IDGS', '=', $idManagement]
        ])->update([
            'GESE_LAD1' => $form['lada1'],
            'GESE_TEL1' => $form['phone1'],
            'GESE_EXT1' => $ext1,
            'GESE_LAD2' => $lad2,
            'GESE_TEL2' => $tel2,
            'GESE_EXT2' => $ext2,
            'GESE_COEL' => $email,
            'GESE_GERE' => $idManager,
            'GESE_USMO' => $idUser,
            'GESE_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F03GESE',
            'S002V01P02GSAU',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") actualizó la gerencia de seguridad #$idManagement.",
            $idUser,
            $nowStr,
            'S002V01S02GEME'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function deleteSecurityManagement(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_management' => 'required|string',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idManagement = $this->encryptionController->decrypt($form['id_management']);
        if(!$idManagement){
            return $this->responseController->makeResponse(true, 'El ID de la gerencia de seguridad no está encriptado correctamente', [], 400);
        }

        $management = DB::table('S002V01TGESE')->where([
            ['GESE_NULI', '=', $form['linea']],
            ['GESE_IDGS', '=', $idManagement]
        ])->first();

        if(is_null($management)){
            return $this->responseController->makeResponse(true, 'La gerencia de seguridad consultada no está registrada.', [], 404);
        }

        $workOrders = DB::table('S002V01TOTCO')->select([
            'OTCO_IDOT AS ID_ORDEN'
        ])->where([
            ['OTCO_NULI', '=', $form['linea']],
            ['OTCO_GESE', '=', $idManagement],
            ['OTCO_ESOR', '!=', 'EL'],
        ])->get()->all();

        if(count($workOrders) > 0){
            return $this->responseController->makeResponse(true, 'La gerencia no se puede eliminar porque tiene órdenes de trabajo relacionadas.', [], 401);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TGESE')->where([
            ['GESE_NULI', '=', $form['linea']],
            ['GESE_IDGS', '=', $idManagement]
        ])->update([
            'GESE_ESTA' => 'Eliminado',
            'GESE_USMO' => $idUser,
            'GESE_FEMO' => $nowStr,
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F03GESE',
            'S002V01P02GSAU',
            'Eliminación',
            "El usuario $name (" . $usr->USUA_IDUS . ") eliminó la gerencia de seguridad #$idManagement.",
            $idUser,
            $nowStr,
            'S002V01S02GEME'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function registerBlock(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'blocked' => 'required|string',
            'type' => 'required|string|in:USR,SUB'
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idBlocked = $this->encryptionController->decrypt($form['blocked']);
        if(!$idBlocked){
            return $this->responseController->makeResponse(true, 'El ID que desea bloquear no fue encriptado correctamente.', [], 400);
        }

        $blockedTypes = ['USR' => 'Empleado', 'SUB' => 'Subcontratista'];
        $blockedType = $blockedTypes[$form['type']];

        if($blockedType == 'Empleado'){
            $employee = DB::table('S002V01TPERS')->where([
                ['PERS_IDPE', '=', $idBlocked],
                ['PERS_NULI', '=', $form['linea']]
            ])->first();
        
            if(is_null($employee)){
                return $this->responseController->makeResponse(true, 'El empleado que desea bloquear no está registrado.', [], 404);
            }
        }else{
            $subcontratist = DB::table('S002V01TPESU')->where([
                ['PESU_NULI', '=', $form['linea']],
                ['PESU_IDPS', '=', $idBlocked]
            ])->first();
        
            if(is_null($subcontratist)){
                return $this->responseController->makeResponse(true, 'El subcontratista que desea bloquear no está registrado.', [], 404);
            }
        }

        $checkStatus = DB::table('S002V01TBIBL')->where([
            ['BIBL_NULI', '=', $form['linea']],
            ['BIBL_BLOQ', '=', $idBlocked],
            ['BIBL_TIBL', '=', $blockedType],
            ['BIBL_ESTA', '=', 'Activo']
        ])->get()->all();

        if(count($checkStatus)){
            return $this->responseController->makeResponse(true, "El $blockedType que desea bloquear ya se encuentra bloqueado.", [], 401);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TBIBL')->insert([
            'BIBL_NULI' => $form['linea'],
            'BIBL_BLOQ' => $idBlocked,
            'BIBL_TIBL' => $blockedType,
            'BIBL_USRE' => $idUser,
            'BIBL_FERE' => $nowStr
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F03GESE',
            'S002V01P04REBL',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") bloqueó al $blockedType #$idBlocked.",
            $idUser,
            $nowStr,
            'S002V01S02GEME'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function getBlockRegisters($idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado', [], 404);
        }

        $blockRegisters = DB::table('S002V01TBIBL')->select([
            'BIBL_IDBL AS ID_BLOQUEO',
            'BIBL_BLOQ AS BLOQUEADO',
            'BIBL_TIBL AS TIPO_BLOQUEADO',
            'BIBL_ESTA AS ESTADO',
            'BIBL_USRE AS USUREG',
            'BIBL_FERE AS FECREG',
            'BIBL_USMO AS USUMOD',
            'BIBL_FEMO AS FECMOD'
        ])->where('BIBL_NULI', '=', $line)->get()->all();

        foreach($blockRegisters as $key=>$register){
            $register->ID_BLOQUEO = $this->encryptionController->encrypt($register->ID_BLOQUEO);
            if($register->TIPO_BLOQUEADO == 'Subcontratista'){
                $subcontratist = DB::table('S002V01TPESU')->where([
                    ['PESU_NULI', '=', $line],
                    ['PESU_IDPS', '=', $register->BLOQUEADO]
                ])->first();

                $register->BLOQUEADO = $subcontratist->PESU_RASO . " (" . $subcontratist->PESU_REFI . ") (" . $register->BLOQUEADO . ")";
            }else{
                $employee = DB::table('S002V01TPERS')->where([
                    ['PERS_NULI', '=', $line],
                    ['PERS_IDPE', '=', $register->BLOQUEADO]
                ])->join('S002V01TUSUA', 'USUA_IDUS', '=', 'PERS_IDUS')->first();

                $employeeName = $this->functionsController->joinName($employee->USUA_NOMB, $employee->USUA_APPA, $employee->USUA_APMA);
                $register->BLOQUEADO = $employeeName . " (" . $register->BLOQUEADO . ")";
            }

            $usrReg = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $register->USUREG]
            ])->first();

            $usrRegName = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
            $register->USUREG = $usrRegName . " (" . $register->USUREG . ")";

            if(!is_null($register->USUMOD)){
                $usrMod = DB::table('S002V01TUSUA')->where([
                    ['USUA_NULI', '=', $line],
                    ['USUA_IDUS', '=', $register->USUMOD]
                ])->first();

                $usrModName = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA);
                $register->USUMOD = $usrModName . " (" . $register->USUMOD . ")";
            }

            $blockRegisters[$key] = $register;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F03GESE',
            'S002V01P03BLOQ',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los bloqueos registrados.",
            $idUser,
            $nowStr,
            'S002V01S02GEME'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $blockRegisters);
    }

    public function unblockRegister(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'id_register' => 'required|string',
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $idBlocked = $this->encryptionController->decrypt($form['id_register']);
        if(!$idBlocked){
            return $this->responseController->makeResponse(true, 'El ID del bloqueo no fue encriptado correctamente.', [], 400);
        }

        $register = DB::table('S002V01TBIBL')->where([
            ['BIBL_NULI', '=', $form['linea']],
            ['BIBL_IDBL', '=', $idBlocked]
        ])->first();
        
        if(is_null($register)){
            return $this->responseController->makeResponse(true, 'El bloqueo que desea revocar no está registrado.', [], 404);
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        DB::table('S002V01TBIBL')->where([
            ['BIBL_NULI', '=', $form['linea']],
            ['BIBL_IDBL', '=', $idBlocked]
        ])->update([
            'BIBL_ESTA' => 'Anulado',
            'BIBL_USMO' => $idUser,
            'BIBL_FEMO' => $nowStr
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F03GESE',
            'S002V01P04REBL',
            'Actualización',
            "El usuario $name (" . $usr->USUA_IDUS . ") anuló el bloqueo #$idBlocked.",
            $idUser,
            $nowStr,
            'S002V01S02GEME'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.');
    }

    public function getWorkOrderStatusHistory($idOrder, $idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $idOrder = $this->encryptionController->decrypt($idOrder);
        if(!$idOrder){
            return $this->responseController->makeResponse(true, 'El ID de la orden solicitada no está encriptado correctamente', [], 400);
        }

        $order = DB::table('S002V01TOTCO')->select([
            'OTCO_HIES AS HISTORIAL',
        ])->where([
            ['OTCO_IDOT', '=', $idOrder],
            ['OTCO_NULI', '=', $line]
        ])->first();

        if(is_null($order)){
            return $this->responseController->makeResponse(true, 'La orden solicitada no está registrada.', [], 404);
        }
        
        $orderStates = [
            'PE' => 'Pendiente',   'VA' => 'Validado', 'RE' => 'Rechazado', 
            'EP' => 'En progreso', 'CE' => 'Cerrado',  'CP' => 'Cerrado pendiente',
            'CA' => 'Cancelado',   'EL' => 'Eliminado'
        ];

        $statusHistoryArr = json_decode($order->HISTORIAL, true);
        foreach($statusHistoryArr as $key=>$item){
            $item['ESTADO'] = $orderStates[$item['ESTADO']];
            $usrSta = DB::table('S002V01TUSUA')->where([
                ['USUA_NULI', '=', $line],
                ['USUA_IDUS', '=', $item['USUARIO']]
            ])->first();

            $usrStaName = $this->functionsController->joinName($usrSta->USUA_NOMB, $usrSta->USUA_APPA, $usrSta->USUA_APMA);
            $item['USUARIO'] = $usrStaName . " (" . $item['USUARIO'] . ")";
            $statusHistoryArr[$key] = $item;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F01GEOT',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó el historial de estados de la orden #$idOrder de mantenimiento correctivo.",
            $idUser,
            $nowStr,
            'S002V01S03PRIN'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $statusHistoryArr);
    }

    public function generateReport(Request $request) {
        DB::enableQueryLog();
        $validator = Validator::make($request->all(), [
            'id_user' => 'required|string',
            'linea' => 'required|integer',
            'report_type' => 'required|string|in:TODAS,MANUA,AUTOM,ESTAD',
            'start_date' => 'date',
            'end_date' => 'date',
            'order_state' => 'required_if:report_type,=,ESTAD|string', 
        ]);
 
        if($validator->fails()){
            return $this->responseController->makeResponse(
                true,
                "Se encontraron uno o más errores.",
                $this->responseController->makeErrors(
                    $validator->errors()->messages()
                ),
                401
            );
        }

        $form = $request->all();
        $idUser = $this->encryptionController->decrypt($form['id_user']);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID de usuario no fue encriptado correctamente.', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $form['linea']],
            ['USUA_IDUS', '=', $idUser]
        ])->first();
        
        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la petición no existe.', [], 404);
        }

        $systemParamsExists = file_exists('C:\inetpub\wwwroot\sam\storage\app\files\system-params.json');
        if(!$systemParamsExists){
            return $this->responseController->makeResponse(true, 'El archivo de parámetros del sistema no fue encontrado.', [], 500);
        }

        $paramsStr = file_get_contents('C:\inetpub\wwwroot\sam\storage\app\files\system-params.json');
        $paramsArr = json_decode($paramsStr, true);

        $ordersBuilder = DB::table('S002V01TOTCO')->select([
            'OTCO_IDOT AS ID_ORDEN',
            'OTCO_IDUR AS USUARIO_RESPONSABLE',
            'OTCO_TURE AS TIPO_USUARIO_RESPONSABLE',
            'OTCO_DEIN AS DESCRIPCION',
            'OTCO_EQIN AS EQUIPAMIENTO',
            'OTCO_FIFA AS FECHA_REGISTRO_FALLA',
            'OTCO_TESO AS TIEMPO_ESTIMADO',
            'OTCO_CORE AS CONTADOR',
            'OTCO_DRCO AS MEDIDA_REGISTRADA',
            'OTCO_PRIO AS PRIORIDAD',
            'OTCO_FTIN AS FECHA_FINALIZACION',
            'OTCO_DTIN AS DURACION_TOTAL',
            'OTCO_RHUT AS RECURSOS',
            'OTCO_PEIN AS PERSONAL',
            'OTCO_TIAC AS TIPO_ACTIVACION',
            'OTCO_ANCO AS ANALISIS_COSTOS',
            'OTCO_DORE AS DOCUMENTOS',
            'OTCO_CLAS AS CLASIFICACION',
            'OTCO_COME AS COMENTARIOS',
            'OTCO_GESE AS GERENCIA_SGURIDAD',
            'OTCO_HIES AS HISTORIAL_ESTADOS',
            'OTCO_ESOR AS ESTADO',
            'OTCO_USRE AS USUREG',
            'OTCO_FERE AS FECREG',
            'OTCO_USMO AS USUMOD',
            'OTCO_FEMO AS FECMOD'
        ])->where('OTCO_NULI', '=', $form['linea']);
        if(isset($form['start_date'])){
            $ordersBuilder->where('OTCO_FERE', '>=', $form['start_date']);
        }

        if(isset($form['end_date'])){
            $ordersBuilder->where('OTCO_FERE', '<=', $form['end_date']);
        }
        
        $orderStates = [
            'PE' => 'Pendiente',   'VA' => 'Validado', 'RE' => 'Rechazado', 
            'EP' => 'En progreso', 'CE' => 'Cerrado',  'CP' => 'Cerrado pendiente',
            'CA' => 'Cancelado',   'EL' => 'Eliminado'
        ];

        if(isset($form['order_state']) && !array_key_exists($form['order_state'], $orderStates)){
            return $this->responseController->makeResponse(true, 'El estado solicitado para las órdenes de mantenimiento correctivo es inválido.', [], 400);
        }else if(isset($form['order_state']) && array_key_exists($form['order_state'], $orderStates)){
            $ordersBuilder->where('OTCO_ESOR', '=', $form['order_state']);
        }

        if($form['report_type'] == 'MANUA'){
            $ordersBuilder->where('OTCO_TIAC', '=', 'M');
        }

        if($form['report_type'] == 'AUTOM'){
            $ordersBuilder->where('OTCO_TIAC', '=', 'A');
        }

        $workOrders = $ordersBuilder->get()->all();
        foreach($workOrders as $order){
            $order->ID_ORDEN = "#" . $order->ID_ORDEN;

            if($order->TIPO_USUARIO_RESPONSABLE == 'S'){
                $subcontratist = DB::table('S002V01TPESU')->where([
                    ['PESU_NULI', '=', $form['linea']],
                    ['PESU_IDPS', '=', $order->USUARIO_RESPONSABLE]
                ])->first();

                $order->USUARIO_RESPONSABLE = $subcontratist->PESU_RASO . " (" . $subcontratist->PESU_REFI . ") (" . $subcontratist->PESU_IDPS . ")";
                $order->TIPO_USUARIO_RESPONSABLE = 'Subcontratista';
            }else if($order->TIPO_USUARIO_RESPONSABLE == 'U'){
                $usrResp = DB::table('S002V01TUSUA')->where([
                    ['USUA_NULI', '=', $form['linea']],
                    ['USUA_IDUS', '=', $order->USUARIO_RESPONSABLE]
                ])->first();
    
                $nameUsrResp = $this->functionsController->joinName($usrResp->USUA_NOMB, $usrResp->USUA_APPA, $usrResp->USUA_APMA);
                $order->USUARIO_RESPONSABLE = $nameUsrResp . " (" . $order->USUARIO_RESPONSABLE . ")";
                $order->TIPO_USUARIO_RESPONSABLE = 'Empleado';
            }

            $equipment = DB::table('S002V01TEQUI')->where([
                ['EQUI_NULI', '=', $form['linea']],
                ['EQUI_COEQ', '=', $order->EQUIPAMIENTO]
            ])->first();

            $order->EQUIPAMIENTO = $order->EQUIPAMIENTO . ' - ' . $equipment->EQUI_TIPO . ' - ' . $equipment->EQUI_MODE . ' (' . $equipment->EQUI_IDEQ . ')';
            $order->FECHA_REGISTRO_FALLA = $this->functionsController->formatDateTime($order->FECHA_REGISTRO_FALLA);
            $order->TIEMPO_ESTIMADO = $order->TIEMPO_ESTIMADO . "h";

            $counterActivator = DB::table('S002V01TACTI')->where([
                ['ACTI_NULI', '=', $form['linea']],
                ['ACTI_CORE', '=', $order->CONTADOR]
            ])->first();

            $measureArr = json_decode($order->MEDIDA_REGISTRADA, true);
            $activationConfig = json_decode($counterActivator->ACTI_COAC, true);
            if($counterActivator->ACTI_TIAC == 'Medida' || $counterActivator->ACTI_TIAC == 'Valor'){
                $unit = DB::table('S002V01TLIME')->where([
                    ['LIME_IDME', '=', $activationConfig['unit']],
                    ['LIME_MAGN', '=', $activationConfig['magnitude']],
                ])->first();

                $order->MEDIDA_REGISTRADA = "Medida #" . $measureArr['ID_MEDIDA'] . ". Valor registrado: " . $measureArr['VALOR'] . 
                ' ' . $unit->LIME_ACME . ". Fecha de registro: " . $this->functionsController->formatDateTime($measureArr['HORA_REGISTRO']) . 
                ". Servicio web de recepción: " . $measureArr['URL_SERVICIO_WEB'] . " (" . $measureArr['ID_SERVICIO_WEB'] . ")";
            }else if($counterActivator->ACTI_TIAC == 'Sintoma'){
                $symptom = DB::table('S002V01TLISI')->where([
                    ['LISI_IDSI', '=', $activationConfig['sign']],
                    ['LISI_NULI', '=', $form['linea']]
                ])->first();

                $unit = DB::table('S002V01TLIME')->where([
                    ['LIME_IDME', '=', $symptom->LISI_IDME],
                    ['LIME_MAGN', '=', $activationConfig['magnitude']],
                ])->first();

                $order->MEDIDA_REGISTRADA = "Medida #" . $measureArr['ID_MEDIDA'] . ". Valor registrado: " . $measureArr['VALOR'] . 
                ' ' . $unit->LIME_ACME . ". Fecha de registro: " . $this->functionsController->formatDateTime($measureArr['HORA_REGISTRO']) . 
                ". Servicio web de recepción: " . $measureArr['URL_SERVICIO_WEB'] . " (" . $measureArr['ID_SERVICIO_WEB'] . ")";
            }else{
                $order->MEDIDA_REGISTRADA = 'No aplica';
            }

            $order->CONTADOR = "#" . $order->CONTADOR;
            $orderPriorities = $paramsArr['order_priorities'];
            $priorityFilt = array_filter($orderPriorities, function($v, $k) use($order) {
                return $v['value'] == $order->PRIORIDAD;
            }, ARRAY_FILTER_USE_BOTH);

            if(count($priorityFilt) < 1){
                $order->PRIORIDAD = 'Desconocido';
            }else{
                $priority = end($priorityFilt);
                $order->PRIORIDAD = $priority['label'] . " (" . $order->PRIORIDAD . ")";
            }

            if(is_null($order->FECHA_FINALIZACION)) {
                $order->FECHA_FINALIZACION = '-';
            }else{
                $order->FECHA_FINALIZACION = $this->functionsController->formatDateTime($order->FECHA_FINALIZACION);
            }

            if(is_null($order->DURACION_TOTAL)) {
                $order->DURACION_TOTAL = '-';
            }else{
                $order->DURACION_TOTAL = $order->DURACION_TOTAL . "h";
            }

            $resourcesArr = json_decode($order->RECURSOS, true);
            if(count($resourcesArr) < 1){
                $order->RECURSOS = 'Ninguno';
            }else{
                //Pendiente procesar los recursos
            }

            $staffArr = json_decode($order->PERSONAL, true);
            $staffStr = "";
            foreach($staffArr as $item){
                if($item['TYPE'] == 'EQ'){
                    $workTeam = DB::table('S002V01TEQMA')->where([
                        ['EQMA_IDEQ', '=', $item['ID']],
                        ['EQMA_NULI', '=', $form['linea']]
                    ])->first();

                    $staffStr .= "equipo de trabajo " . $workTeam->EQMA_NOMB . " (" . $item['ID'] . "), ";
                }else if($item['TYPE'] == 'SU'){
                    $subcontratist = DB::table('S002V01TPESU')->where([
                        ['PESU_IDPS', '=', $item['ID']],
                        ['PESU_NULI', '=', $form['linea']]
                    ])->first();

                    $staffStr .= "subcontratista " . $subcontratist->PESU_RASO . " (" . $subcontratist->PESU_REFI . ") (" . $item['ID'] . "), ";
                }else if($item['TYPE'] == 'EM'){
                    $employee = DB::table('S002V01TPERS')->where([
                        ['PERS_IDPE', '=', $item['ID']],
                        ['PERS_NULI', '=', $form['linea']]
                    ])->join('S002V01TUSUA', 'USUA_IDUS', '=', 'PERS_IDUS')->first();

                    $employeeName = $this->functionsController->joinName($employee->USUA_NOMB, $employee->USUA_APPA, $employee->USUA_APMA);
                    $staffStr .= "empleado " . $employeeName . " (" . $item['ID'] . "), ";
                }
            }

            $staffStr = substr($staffStr, 0, -2);
            $staffStr = ucfirst($staffStr);
            
            $order->PERSONAL = $staffStr;
            $order->TIPO_ACTIVACION = $order->TIPO_ACTIVACION == 'M' ? 'Manual' : 'Automática';

            if(is_null($order->ANALISIS_COSTOS)){
                $order->ANALISIS_COSTOS = 'Sin asignar';
            }else{
                //Pendiente revisar el análisis de costos
            }

            $documentsArr = json_decode($order->DOCUMENTOS, true);
            $documentsStr = "";

            if(count($documentsArr) < 1){
                $documentsStr = 'Ninguno';
            }else{
                foreach($documentsArr as $document){
                    $documentsStr .= $document . ", ";
                }

                $documentsStr = substr($documentsStr, 0, -2);
            }

            $order->DOCUMENTOS = $documentsStr;
            if(is_null($order->COMENTARIOS)){
                $order->COMENTARIOS = 'Sin comentarios';
            }

            $order->GERENCIA_SGURIDAD = "Gerencia #" . $order->GERENCIA_SGURIDAD;
            $statusHistoryArr = json_decode($order->HISTORIAL_ESTADOS, true);
            $statusHistoryStr = "";
            foreach($statusHistoryArr as $item){
                $statusHistoryStr .= $orderStates[$item['ESTADO']] . ' - ' . $this->functionsController->formatDateTime($item['FECHA']);
                $usrState = DB::table('S002V01TUSUA')->where([
                    ['USUA_IDUS', '=', $item['USUARIO']],
                    ['USUA_NULI', '=', $form['linea']]
                ])->first();

                $usrStateName = $this->functionsController->joinName($usrState->USUA_NOMB, $usrState->USUA_APPA, $usrState->USUA_APMA);
                $statusHistoryStr .= ' - ' . $usrStateName . ' (' . $item['USUARIO'] . '), ';
            }

            $statusHistoryStr = substr($statusHistoryStr, 0, -2);
            $order->HISTORIAL_ESTADOS = $statusHistoryStr;
            $order->ESTADO = $orderStates[$order->ESTADO];

            $usrReg = DB::table('S002V01TUSUA')->where([
                ['USUA_IDUS', '=', $order->USUREG],
                ['USUA_NULI', '=', $form['linea']]
            ])->first();

            $usrRegName = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
            $order->USUREG = $usrRegName . " (" . $order->USUREG . ")";
            $order->FECREG = $this->functionsController->formatDateTime($order->FECREG);

            if(!is_null($order->USUMOD)){
                $usrMod = DB::table('S002V01TUSUA')->where([
                    ['USUA_IDUS', '=', $order->USUMOD],
                    ['USUA_NULI', '=', $form['linea']]
                ])->first();
    
                $usrModName = $this->functionsController->joinName($usrMod->USUA_NOMB, $usrMod->USUA_APPA, $usrMod->USUA_APMA);
                $order->USUMOD = $usrModName . " (" . $order->USUMOD . ")";
                $order->FECMOD = $this->functionsController->formatDateTime($order->FECMOD);
            }else{
                $order->USUMOD = "-";
                $order->FECMOD = "-";
            }
        }

        $document = $this->reportWorkOrders($workOrders);

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        
        $dateTimeArr = explode(" ", $nowStr);
        $dateArr = explode("-", $dateTimeArr[0]);
        $year = substr($dateArr[0], 2);
        $como = 'GMCO';
        $cldo = 'IN';
        $fecr = $year . $dateArr[1] . $dateArr[2];

        $sec = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $form['linea']],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
        ])->orderBy('AFAL_NUSE', 'desc')->first();

        $nuse = "";
        if(is_null($sec)){
            $nuse = '000001';
        }else{
            $secu = "" . intval($sec->AFAL_NUSE) + 1 . "";
            $nuse = "";

            for($i = strlen($secu); $i < 6; $i++){
                $nuse .= "0";
            }

            $nuse = $nuse . $secu;
        }

        $timestamp = $now->timestamp;
        $noar = "informe_ordenes_mantenimiento_correctivo_$timestamp";
        $exte = "xlsx";

        $ver = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $form['linea']],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
            ['AFAL_NOAR', '=', $noar],
            ['AFAL_EXTE', '=', $exte],
        ])->orderBy('AFAL_NUVE', 'desc')->first();

        $nuve = "";
        if(is_null($ver)){
            $nuve = "01";
        }else{
            $vers = intval($ver->AFAL_NUVE) + 1;
            $nuve = $vers < 10 ? "0$vers" : "$vers";
        }

        $line = $form['linea'] < 10 ? "0$form[linea]" : "$form[linea]";
        $filePath = 'C:\inetpub\wwwroot\sam\public_files\\';
        $fileName = "$line-$como-$cldo-$fecr-$nuse=$nuve=$noar.$exte";
        
        $tempFile = $filePath . $fileName;
        if(file_exists($tempFile)){
            unlink($tempFile);
        }

        $writer = IOFactory::createWriter($document, 'Xlsx');
        $writer->save($tempFile);
        $ubic = Storage::putFile('files', new File($tempFile));
        $ubic = str_replace("/", "\\", $ubic);
        $ubic = "C:\inetpub\wwwroot\sam\storage\app\\" . $ubic;
        $tama = filesize($ubic);
        $usac = json_encode([$idUser]);
        unlink($tempFile);

        DB::table('S002V01TAFAL')->insert([
            'AFAL_NULI' => $line,
            'AFAL_COMO' => $como,
            'AFAL_CLDO' => $cldo,
            'AFAL_FECR' => $fecr,
            'AFAL_NUSE' => $nuse,
            'AFAL_NUVE' => $nuve,
            'AFAL_NOAR' => $noar,
            'AFAL_EXTE' => $exte,
            'AFAL_TAMA' => $tama,
            'AFAL_UBIC' => $ubic,
            'AFAL_USAC' => $usac,
            'AFAL_USRE' => $idUser,
            'AFAL_FERE' => $nowStr,
        ]);

        $idReport = DB::table('S002V01TIMCO')->insertGetId([
            'IMCO_NULI' => $form['linea'],
            'IMCO_TIIN' => $form['report_type'],
            'IMCO_DORE' => $fileName,
            'IMCO_USRE' => $idUser,
            'IMCO_FERE' => $nowStr
        ]);

        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $form['linea'],
            'S002V01M09GMCO',
            'S002V01F02PRIN',
            'S002V01P01REIN',
            'Registro',
            "El usuario $name (" . $usr->USUA_IDUS . ") registró el informe #$idReport.",
            $idUser,
            $nowStr,
            'S002V01S03PRIN'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $form['linea']);
        return $this->responseController->makeResponse(false, 'EXITO.', ['report' => $this->encryptionController->encrypt($fileName)]);
    }

    private function reportWorkOrders($workOrders) : Spreadsheet {
        $spreadsheet = new Spreadsheet;
        $spreadsheet->getProperties()
            ->setCreator('STC')
            ->setTitle('Historial de órdenes de trabajo de mantenimiento correctivo.')
            ->setSubject('Historial documento')
            ->setKeywords('Historial Órdenes Mantenimiento Correctivo')
            ->setCategory('Historial archivo');

        $worksheet = $spreadsheet->getActiveSheet();
        $worksheet->setTitle('ÓRDENES DE MANT CORRECTIVO');

        $columns = ['# ORDEN', 'RESPONSABLE', 'TIPO DE USUARIO RESPONSABLE', 'DESCRIPCIÓN', 'EQUIPAMIENTO', 'FECHA Y HORA DE REGISTRO DE LA FALLA', 
        'TIEMPO ESTIMADO DE DURACIÓN DE LA INTERVENCIÓN', 'CONTADOR RELACIONADO', 'MEDIDA REGISTRADA AL MOMENTO DE LA FALLA', 'PRIORIDAD', 
        'FECHA DE FINALIZACIÓN DE LA INTERVENCIÓN', 'DURACIÓN TOTAL DE LA INTERVENCIÓN', 'CONSUMIBLES UTILIZADOS', 'PERSONAL INVOLUCRADO', 
        'TIPO DE ACTIVACIÓN', 'ANÁLISIS DE COSTOS', 'DOCUMENTOS REQUERIDOS', 'CLASIFICACIÓN', 'COMENTARIOS REALIZADOS DURANTE LA INTERVENCIÓN', 
        'GERENCIA DE SEGURIDAD RELACIONADA', 'HISTORIAL DE ESTADOS', 'ESTADO DE LA ORDEN', 'USUARIO DE REGISTRO', 'FECHA DE REGISTRO', 'USUARIO DE ACTIALIZACIÓN', 
        'FECHA DE ACTUALIZACIÓN'];
        
        $startRow = 2;
        $startCol = 2;
        $maxRow = $startRow + count($workOrders) + 1;
        $maxCol = $startCol + count($columns) - 1;

        for($row = $startRow; $row <= $maxRow; $row++){
            $startColStr = Coordinate::stringFromColumnIndex($startCol);
            $maxColStr = Coordinate::stringFromColumnIndex($maxCol);

            if($row == 2){
                $worksheet->mergeCells($startColStr . $row . ':' . $maxColStr . $row);
                $worksheet->setCellValue($startColStr . $row, 'INFORME DE ÓRDENES DE MANTENIMIENTO CORRECTIVO')->getStyle($startColStr . $row)->getFill()
                    ->setFillType(Fill::FILL_SOLID)
                    ->getStartColor()->setRGB('B7BCC4');
                $worksheet->getStyle($startColStr . $row)->getFont()->setBold(true);
                $worksheet->getStyle($startColStr . $row)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
            }else if($row == 3){
                for($col = $startCol; $col <= $maxCol; $col++){
                    $colStr = Coordinate::stringFromColumnIndex($col);
                    $colInd = $col - 2;

                    $column = $columns[$colInd]; 
                    $worksheet->setCellValue($colStr . $row, $column);
                    $worksheet->getStyle($colStr . $row)->getFont()->setBold(true);
                    $worksheet->getStyle($colStr . $row)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
                }
            }else if($row > 3){
                $rowInd = $row - 4;
                $order = (array) $workOrders[$rowInd];
                $keys = array_keys($order);

                for($col = $startCol; $col <= $maxCol; $col++){
                    $colInd = $col - 2;
                    $key = $keys[$colInd];
                    $value = $order[$key];
                    $colStr = Coordinate::stringFromColumnIndex($col);

                    if($key == 'ID_ORDEN' || $key == 'TIEMPO_ESTIMADO' || $key == 'CONTADOR' || 
                    $key == 'DURACION_TOTAL' || $key == 'GERENCIA_SGURIDAD'){
                        $worksheet->getStyle($colStr . $row)->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
                        $worksheet->getColumnDimension($colStr)->setAutoSize(true);
                    }else if($key == 'EQUIPAMIENTO' || $key == 'DESCRIPCION' || $key == 'MEDIDA_REGISTRADA' || 
                    $key == 'PERSONAL' || $key == 'DOCUMENTOS' || $key == 'COMENTARIOS' || $key == 'HISTORIAL_ESTADOS'){
                        $worksheet->getColumnDimension($colStr)->setWidth(48);
                        $worksheet->getStyle($colStr . $row)->getAlignment()->setWrapText(true);
                    }else{
                        $worksheet->getColumnDimension($colStr)->setAutoSize(true);
                    }

                    $worksheet->getStyle($colStr . $row)->getAlignment()->setVertical(Alignment::HORIZONTAL_CENTER);
                    $worksheet->setCellValue($colStr . $row, $value);
                }
            }
        }

        return $spreadsheet;
    }

    public function getReports($type, $startDate, $endDate, $idUser, $line) {
        DB::enableQueryLog();

        $idUser = $this->encryptionController->decrypt($idUser);
        if(!$idUser){
            return $this->responseController->makeResponse(true, 'El ID del usuario que realizó la solicitud no está encriptado correctamente', [], 400);
        }

        $usr = DB::table('S002V01TUSUA')->where([
            ['USUA_NULI', '=', $line],
            ['USUA_IDUS', '=', $idUser],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El usuario que realizó la consulta no está registrado.', [], 404);
        }

        $reportsBuilder = DB::table('S002V01TIMCO')->select([
            'IMCO_IDIN AS ID_INFORME',
            'IMCO_TIIN AS TIPO_INFORME',
            'IMCO_DORE AS DOCUMENTO',
            'IMCO_USRE AS USUREG',
            'IMCO_FERE AS FECREG'
        ])->where('IMCO_NULI', '=', $line);

        if($type != '-'){
            $validReports = ['TODAS','MANUA','AUTOM','ESTAD'];
            if(!in_array($type, $validReports)){
                return $this->responseController->makeResponse(true, "El tipo de reportes solicitado es inválido.", [], 400);
            }

            $reportsBuilder->where('IMCO_TIIN', '=', $type);
        }

        if($startDate != '-'){
            $startDateArr = explode('-', $startDate);
            if(count($startDateArr) != 3){
                return $this->responseController->makeResponse(true, 'La fecha de inicio tiene un formato inválido.', [], 400);
            }
    
            try{
                $startDateObj = new Carbon($startDate);
            }catch(InvalidFormatException $e){
                return $this->responseController->makeResponse(true, "La fecha de inicio tiene un formato inválido: " . $e->getMessage(), [], 400);
            }
    
            $startDate = $startDateObj->toDateTimeString();
            $reportsBuilder->where('IMCO_FERE', '>=', $startDate);
        }

        if($endDate != '-'){
            $endDateArr = explode('-', $endDate);
            if(count($endDateArr) != 3){
                return $this->responseController->makeResponse(true, 'La fecha final tiene un formato inválido.', [], 400);
            }
    
            try{
                $endDateObj = new Carbon($endDate);
                
                $endDateObj->addDay();
                $endDateObj->subSecond();
            }catch(InvalidFormatException $e){
                return $this->responseController->makeResponse(true, "La fecha final tiene un formato inválido: " . $e->getMessage(), [], 400);
            }
            
            $endDate = $endDateObj->toDateTimeString();
            $reportsBuilder->where('IMCO_FERE', '<=', $endDate);
        }

        $reports = $reportsBuilder->get()->all();
        foreach($reports as $key=>$report){
            $report->ID_INFORME = $this->encryptionController->encrypt($report->ID_INFORME);
            $report->DOCUMENTO = $this->encryptionController->encrypt($report->DOCUMENTO);

            $usrReg = DB::table('S002V01TUSUA')->where([
                ['USUA_IDUS', '=', $report->USUREG],
                ['USUA_NULI', '=', $line]
            ])->first();

            $usrRegName = $this->functionsController->joinName($usrReg->USUA_NOMB, $usrReg->USUA_APPA, $usrReg->USUA_APMA);
            $report->USUREG = $usrRegName . " (" . $report->USUREG . ")";

            $reports[$key] = $report;
        }

        $now = $this->functionsController->now();
        $nowStr = $now->toDateTimeString();
        $actions = DB::getQueryLog();
        $name = $this->functionsController->joinName($usr->USUA_NOMB, $usr->USUA_APPA, $usr->USUA_APMA);
        
        $idac = $this->functionsController->registerActivity(
            $line,
            'S002V01M09GMCO',
            'S002V01F02PRIN',
            '-',
            'Consulta',
            "El usuario $name (" . $usr->USUA_IDUS . ") consultó los informes de tipo $type.",
            $idUser,
            $nowStr,
            'S002V01S03PRIN'
        );

        $this->functionsController->registerLog($actions, $idUser, $nowStr, $idac, $line);
        return $this->responseController->makeResponse(false, 'EXITO.', $reports);
    }
}