<?php
/*
    Desarrollador: Ing. Jean Jairo Benitez Meza
    Ultima Modificación: 15/09/2023
    Módulo: Analisis de Fallas
*/
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Http\Controllers\ResponseController;
use App\Http\Controllers\FunctionsController;
use App\Http\Controllers\EncryptionController;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class FailureListController extends Controller
{

    private $responseController;
    private $encController;
    private $functionsController;

    public function __construct() {
        $this->responseController = new ResponseController();
        $this->encController = new EncryptionController();
        $this->functionsController = new FunctionsController();
    }

    public function getFailures($user, $line) {
        try {
            $getFailures = DB::table('S002V01TLIFA')
                ->where('LIFA_NULI', '=', $line)
                ->get([
                    'LIFA_IDFA AS ID_FALLA',
                    'LIFA_NOFA AS NOMBRE_FALLA',
                    'LIFA_NIVE AS NIVEL_CRITICIDAD',
                    'LIFA_CAUS AS CAUSA_FALLA',
                    'LIFA_SOLU AS SOLICION',
                    'LIFA_DESC AS DESCRIPCION',
                    'LIFA_ESTA AS ESTADO',
                    'LIFA_USRE AS USUARIO_REGISTRA',
                    'LIFA_FERE AS FECHA_REGISTRA',
                    'LIFA_USMO AS USUARIO_MODIFICA',
                    'LIFA_FEMO AS FECHA_MODIFICA',
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_FAILURES_GET000: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
        }
        return $this->responseController->makeResponse(false, "ÉXITO: Consulta Exitosa", $getFailures);
    }

    public function getFailuresActives($user, $line) {
        try {
            $getFailures = DB::table('S002V01TLIFA')
                ->where('LIFA_ESTA', '=', 'Activo')
                ->where('LIFA_NULI', '=', 1)
                ->get([
                    'LIFA_IDFA AS ID_FALLA',
                    'LIFA_NOFA AS NOMBRE_FALLA',
                    'LIFA_NIVE AS NIVEL_CRITICIDAD',
                    'LIFA_CAUS AS CAUSA_FALLA',
                    'LIFA_SOLU AS SOLICION',
                    'LIFA_DESC AS DESCRIPCION',
                    'LIFA_ESTA AS ESTADO',
                    'LIFA_USRE AS USUARIO_REGISTRA',
                    'LIFA_FERE AS FECHA_REGISTRA',
                    'LIFA_USMO AS USUARIO_MODIFICA',
                    'LIFA_FEMO AS FECHA_MODIFICA',
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_FAILURES_GET000: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
        }
        return $this->responseController->makeResponse(false, "ÉXITO: Consulta Exitosa", $getFailures);
    }

    public function getFailureById($idFailure, $user, $line) {
        $idFailure = $this->encController->decrypt($idFailure);
        try {
            $arrFailures = (array) DB::table('S002V01TLIFA')
                ->where('LIFA_IDFA', '=', $idFailure)
                ->where('LIFA_NULI', '=', $line)
                ->where('LIFA_ESTA', '=', 'Activo')
                ->first([
                    'LIFA_IDFA AS ID_FALLA',
                    'LIFA_NOFA AS NOMBRE_FALLA',
                    'LIFA_NIVE AS NIVEL_CRITICIDAD',
                    'LIFA_CAUS AS CAUSA_FALLA',
                    'LIFA_SOLU AS SOLICION',
                    'LIFA_DESC AS DESCRIPCION',
                    'LIFA_ESTA AS ESTADO',
                    'LIFA_USRE AS USUARIO_REGISTRA',
                    'LIFA_FERE AS FECHA_REGISTRA',
                    'LIFA_USMO AS USUARIO_MODIFICA',
                    'LIFA_FEMO AS FECHA_MODIFICA',
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(
                true, 
                "ERR_FAILURES_GETBYID000: No se pudo realizar la consulta a la base.", 
                $th->getMessage(), 
                500
            );
        }
        if ( !empty($arrFailures) ) {
            try {
                $arrEquipment = DB::table('S002V01TLFEQ')
                    ->where('LFEQ_IDFA', '=', $arrFailures['ID_FALLA'])
                    ->where('LFEQ_NULI', '=', $line)
                    ->where('LFEQ_ESTA', '=', 'Activo')
                    ->where('EQUI_NULI', '=', $line)
                    ->join('S002V01TEQUI', 'EQUI_COEQ', '=', 'LFEQ_COEQ')
                    ->get([
                        'EQUI_COEQ AS CODIGO',
                        'EQUI_TIPO AS TIPO',
                        'EQUI_MODE AS MODELO',
                        'EQUI_IDEQ AS ID_EQUIPO',
                        'EQUI_ESFU AS ESTADO_FUNCIONAMIENTO',
                        // 'EQUI_GAIM AS GALERIA_IMAGENES',
                        'EQUI_ELOR AS ELEMENTO_ORIGEN',
                        'EQUI_TICO AS TIPO_CODIGO'
                    ]);
            } catch (\Throwable $th) {
                return $this->responseController->makeResponse(
                    true, 
                    "ERR_FAILURES_GETBYID001: No se pudo realizar la consulta a la base.", 
                    $th->getMessage(), 
                    500
                );
            }
    
            $arrEquipment = json_decode( json_encode($arrEquipment), true );

            foreach ($arrEquipment as $keyEquipment => $equipment) {
                $equipment['ID_EQUIPO'] = strval($equipment['ID_EQUIPO']);
                $arrEquipment[$keyEquipment] = $equipment;
            }
            $arrFailures['EQUIPAMIENTOS'] = $arrEquipment;
        }

        return $this->responseController->makeResponse(false, "ÉXITO: Consulta Exitosa", $arrFailures);
    }

    public function getFailureListByClassification($clasificate, $user, $line) {
        try {
            $clasificate = $this->encController->decrypt($clasificate);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_FAILURES_GETCLASS000: No se pudo obtener las clasificación.", $th->getMessage(), 500);
        }
        try {
            $getFailures = DB::table('S002V01TLIFA')
                ->where('LIFA_NIVE', '=', $clasificate)
                ->where('LIFA_ESTA', '=', 'Activo')
                ->where('LIFA_NULI', '=', 1)
                ->get([
                    'LIFA_IDFA AS ID_FALLA',
                    'LIFA_NOFA AS NOMBRE_FALLA',
                    'LIFA_NIVE AS NIVEL_CRITICIDAD',
                    'LIFA_CAUS AS CAUSA_FALLA',
                    'LIFA_SOLU AS SOLICION',
                    'LIFA_DESC AS DESCRIPCION',
                    'LIFA_ESTA AS ESTADO',
                    'LIFA_USRE AS USUARIO_REGISTRA',
                    'LIFA_FERE AS FECHA_REGISTRA',
                    'LIFA_USMO AS USUARIO_MODIFICA',
                    'LIFA_FEMO AS FECHA_MODIFICA',
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_FAILURES_GETCLASS001: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
        }
        return $this->responseController->makeResponse(false, "ÉXITO: Consulta Exitosa", $getFailures);
    }
    
    public function registerFailures(Request $request) {
        $validator = Validator::make($request->all(), [
            'NOMBRE_FALLA' => 'required|string',
            'NIVEL' => 'required|string',
            'CAUSA' => 'required|string',
            'SOLUCION' => 'required|string',
            'DESCRIPCION' => 'required|string',
            'EQUIPAMIENTOS' => 'required',
            'NUMERO_LINEA' => 'required|string',
            'USUARIO' => 'required|string',
        ]);
        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_FAILURES_REG000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($validator->errors()->messages()),
                401
            );
        }

        DB::beginTransaction();
        $requestData = $request->all();

        try {
            $user = $this->encController->decrypt($requestData['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_REG001: No se pudo obtener el usuario.", $th->getMessage(), 500);
        }

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

        try {
            $idFailure = DB::table('S002V01TLIFA')->insertGetId([
                'LIFA_NULI' => $requestData['NUMERO_LINEA'],
                'LIFA_NOFA' => $requestData['NOMBRE_FALLA'],
                'LIFA_NIVE' => $requestData['NIVEL'],
                'LIFA_CAUS' => $requestData['CAUSA'],
                'LIFA_SOLU' => $requestData['SOLUCION'],
                'LIFA_DESC' => $requestData['DESCRIPCION'],
                'LIFA_USRE' => $user,
                'LIFA_FERE' => $currentDate,
                'LIFA_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
            ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse( 
                true, 
                "ERR_FAILURES_REG002: Ocurrió un error al registrar el formulario en la lista de falla.", 
                $th->getMessage(), 
                500
            );
        }
        if ( !$idFailure ) {
            DB::rollBack();
            return $this->responseController->makeResponse(
                true, 
                "ERR_FAILURES_REG003: No se pudo registrar el formulario en la lista de falla.", 
                [], 
                500
            );
        }

        foreach ($requestData['EQUIPAMIENTOS'] as $keyEquipment => $equipment) {
            try {
                $validateRegisterEquipment = DB::table('S002V01TLFEQ')->insert([
                    'LFEQ_NULI' => $requestData['NUMERO_LINEA'],
                    'LFEQ_IDFA' => $idFailure,
                    'LFEQ_COEQ' => $equipment,
                    'LFEQ_USRE' => $user,
                    'LFEQ_FERE' => $currentDate,
                    'LFEQ_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                ]);
            } catch (\Throwable $th) {
                DB::rollBack();
                return $this->responseController->makeResponse( 
                    true, 
                    "ERR_FAILURES_REG004: Ocurrió un error al registrar el formulario en la lista de falla.", 
                    $th->getMessage(), 
                    500
                );
            }

            if ( !$validateRegisterEquipment ) {
                DB::rollBack();
                return $this->responseController->makeResponse(
                    true, 
                    "ERR_FAILURES_REG005: No se pudo registrar el equipamiento $equipment en la lista de fallas.", 
                    [], 
                    500
                );
            }
        }
        
        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Registro Exitoso");
    }
    public function updateFailures(Request $request) {
        $validator = Validator::make($request->all(), [
            'ID_FALLA' => 'required|integer',
            'NOMBRE_FALLA' => 'required|string',
            'NIVEL' => 'required|string',
            'CAUSA' => 'required|string',
            'SOLUCION' => 'required|string',
            'DESCRIPCION' => 'required|string',
            'EQUIPAMIENTOS' => 'required',
            'NUMERO_LINEA' => 'required|string',
            'USUARIO' => 'required|string',
        ]);
        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_FAILURES_UPD000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($validator->errors()->messages()),
                401
            );
        }

        DB::beginTransaction();
        $requestData = $request->all();
        try {
            $user = $this->encController->decrypt($request['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_UPD001: No se pudo obtener el usuario.", $th->getMessage(), 500);
        }

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

        try {
            $idFailure = DB::table('S002V01TLIFA')
                ->where('LIFA_NULI', '=', $requestData['NUMERO_LINEA'])    
                ->where('LIFA_IDFA', '=', $requestData['ID_FALLA'])    
                ->update([
                    'LIFA_NOFA' => $requestData['NOMBRE_FALLA'],
                    'LIFA_NIVE' => $requestData['NIVEL'],
                    'LIFA_CAUS' => $requestData['CAUSA'],
                    'LIFA_SOLU' => $requestData['SOLUCION'],
                    'LIFA_DESC' => $requestData['DESCRIPCION'],
                    'LIFA_USMO' => $user,
                    'LIFA_FEMO' => $currentDate,
                    'LIFA_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse( 
                true, 
                "ERR_FAILURES_UPD002: Ocurrió un error al modificar el formulario en la lista de falla.", 
                $th->getMessage(), 
                500
            );
        }

        if ( !$idFailure ) {
            DB::rollBack();
            return $this->responseController->makeResponse(
                true, 
                "ERR_FAILURES_UPD003: No se pudo modificar el formulario en la lista de falla.", 
                [], 
                500
            );
        }

        foreach ($requestData['EQUIPAMIENTOS'] as $keyEquipment => $equipment) {
            try {
                $validateExists = DB::table('S002V01TLFEQ')
                    ->where('LFEQ_IDFA', '=', $requestData['ID_FALLA'])
                    ->where('LFEQ_NULI', '=', $requestData['NUMERO_LINEA'])
                    ->where('LFEQ_COEQ', '=', $equipment)
                    ->exists();
            } catch (\Throwable $th) {
                DB::rollBack();
                return $this->responseController->makeResponse(
                    true, 
                    "ERR_FAILURES_UPD004: Ocurrió un error al consultar el equipamiento.", 
                    $th->getMessage(), 
                    500
                );
            }
    
            if ( $validateExists ) {
                try {
                    $validate = DB::table('S002V01TLFEQ')
                        ->where('LFEQ_NULI', '=', $requestData['NUMERO_LINEA'])
                        ->where('LFEQ_IDFA', '=', $requestData['ID_FALLA'])
                        ->where('LFEQ_COEQ', '=', $equipment)
                        ->update([
                            'LFEQ_ESTA' => 'Activo',
                            'LFEQ_USMO' => $user,
                            'LFEQ_FEMO' => $currentDate,
                            'LFEQ_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                        ]);
                } catch (\Throwable $th) {
                    DB::rollBack();
                    return $this->responseController->makeResponse( 
                        true, 
                        "ERR_FAILURES_UPD005: Ocurrió un error al modificar el formulario en la lista de falla el equipamiento $equipment.", 
                        $th->getMessage(), 
                        500
                    );
                }
            } else {
                try {
                    $validate = DB::table('S002V01TLFEQ')->insert([
                        'LFEQ_NULI' => $requestData['NUMERO_LINEA'],
                        'LFEQ_IDFA' => $requestData['ID_FALLA'],
                        'LFEQ_COEQ' => $equipment,
                        'LFEQ_USRE' => $user,
                        'LFEQ_FERE' => $currentDate,
                        'LFEQ_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                    ]);
                } catch (\Throwable $th) {
                    DB::rollBack();
                    return $this->responseController->makeResponse( 
                        true, 
                        "ERR_FAILURES_UPD006: Ocurrió un error al registrar el formulario en la lista de falla el equipamiento $equipment.", 
                        $th->getMessage(), 
                        500
                    );
                }
            }
            if ( !$validate ) {
                DB::rollBack();
                return $this->responseController->makeResponse(
                    true, 
                    "ERR_FAILURES_UPD007: No se pudo modificar el equipamiento $equipment en la lista de fallas.", 
                    [], 
                    500
                );
            }
        }

        try {
            $getListEquipment = DB::table('S002V01TLFEQ')
                ->where('LFEQ_IDFA', '=', $requestData['ID_FALLA'])
                ->where('LFEQ_NULI', '=', $requestData['NUMERO_LINEA'])
                ->get([
                    'LFEQ_IDLF',
                    'LFEQ_IDFA',
                    'LFEQ_COEQ',
                    'LFEQ_ESTA',
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(
                true, 
                "ERR_FAILURES_UPD008: Ocurrió un error al consultar la lista de equipamientos.", 
                $th->getMessage(), 
                500
            );
        }

        $arrListEquipment = json_decode( json_encode($getListEquipment), true );
        
        foreach ($arrListEquipment as $keyListEquipment => $listEquipment) {
            if( !in_array($listEquipment['LFEQ_COEQ'], $requestData['EQUIPAMIENTOS']) ) {
                try {
                    $validateDelete = DB::table('S002V01TLFEQ')
                        ->where('LFEQ_NULI', '=', $requestData['NUMERO_LINEA'])
                        ->where('LFEQ_IDFA', '=', $requestData['ID_FALLA'])
                        ->where('LFEQ_COEQ', '=', $listEquipment['LFEQ_COEQ'])
                        ->update([
                            'LFEQ_ESTA' => 'Eliminado',
                            'LFEQ_USMO' => $user,
                            'LFEQ_FEMO' => $currentDate,
                            'LFEQ_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                        ]);
                } catch (\Throwable $th) {
                    DB::rollBack();
                    return $this->responseController->makeResponse( 
                        true, 
                        "ERR_FAILURES_UPD009: Ocurrió un error al eliminar de la lista de falla el equipamiento ". $listEquipment['LFEQ_COEQ'].".", 
                        $th->getMessage(), 
                        500
                    );
                }

                if ( !$validateDelete ) {
                    DB::rollBack();
                    return $this->responseController->makeResponse( 
                        true, 
                        "ERR_FAILURES_UPD010: No se pudo eliminar de la lista de falla el equipamiento ". $listEquipment['LFEQ_COEQ'].".", 
                        [], 
                        500
                    );
                }
            }
        }
        
        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Modificación Exitosa");
    }
    public function deleteFailures(Request $request) {
        $validator = Validator::make($request->all(), [
            'ID_FALLA' => 'required|integer',
            'NUMERO_LINEA' => 'required|integer',
            'USUARIO' => 'required|string',
        ]);
        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_FAILURES_DEL000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($validator->errors()->messages()),
                401
            );
        }

        DB::beginTransaction();
        $requestData = $request->all();
        
        try {
            $user = $this->encController->decrypt($request['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_DEL001: No se pudo obtener el usuario.", $th->getMessage(), 500);
        }
        
        $now = $this->functionsController->now();
        $currentDate = $now->toDateTimeString();

        try {
            $exist = DB::table('S002V01TLIFA')
                ->where('LIFA_IDFA', '=', $requestData['ID_FALLA'])
                ->where('LIFA_NULI', '=', $requestData['NUMERO_LINEA'])
                ->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_DEL002: Ocurrió un error al consultar en la base de datos.", $th->getMessage(), 500);
        }
        
        if (!$exist) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_DEL003: No se pudo encontrar el registro dentro de la base de datos.", [], 500);
        }

        try {
            $validateUpdate = DB::table('S002V01TLIFA')
                ->where('LIFA_IDFA', '=', $requestData['ID_FALLA'])
                ->where('LIFA_NULI', '=', $requestData['NUMERO_LINEA'])
                ->update([
                    'LIFA_ESTA' => 'Eliminado',
                    'LIFA_USMO' => $user,
                    'LIFA_FEMO' => $currentDate,
                    'LIFA_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_DEL004: Ocurrió un error al modificar el formulario en la base de datos.", $th->getMessage(), 500);
        }
        if (!$validateUpdate) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_DEL005: No se pudo modificar el formulario en la base de datos.", [], 500);
        }

        try {
            $validateDelete = DB::table('S002V01TLFEQ')
                ->where('LFEQ_IDFA', '=', $requestData['ID_FALLA'])
                ->where('LFEQ_NULI', '=', $requestData['NUMERO_LINEA'])
                ->update([
                    'LFEQ_ESTA' => 'Eliminado',
                    'LFEQ_USMO' => $user,
                    'LFEQ_FEMO' => $currentDate,
                    'LFEQ_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(
                true, 
                "ERR_FAILURES_DEL006: Ocurrió un error al eliminar la lista de equipamientos.", 
                $th->getMessage(), 
                500
            );
        }

        if ( !$validateDelete ) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_DEL007: No se pudo eliminar la lista de equipamientos.", [], 500);
        }

        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Eliminación Exitosa");
    }

}
