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

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

class FailureController extends Controller
{
    private $responseController;
    private $encController;

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

    public function getFault($line) {

        try {
            $getFault = DB::table('S002V01TFALL')
                ->join('S002V01TLIFA', 'FALL_IDFA', '=', 'LIFA_IDFA')
                ->join('S002V01TLIME', 'FALL_IDME', '=', 'LIME_IDME')
                ->orderBy('FALL_NUFA', 'ASC')
                ->where('FALL_NULI', '=', $line)
                ->get([
                    'FALL_NUFA',
                    'FALL_COEQ',
                    'FALL_IDFA',
                    'LIFA_NOFA',
                    'LIME_MEDI',
                    'LIME_ACRO',
                    'FALL_CAUS',
                    'FALL_FEFA',
                    'FALL_CLAS',
                    'FALL_REPA',
                    'FALL_DESO',
                    'FALL_COME',
                    'FALL_LIVA',
                    'FALL_VAOB',
                    'FALL_IDME',
                    'FALL_NUSI',
                    'FALL_ESTA',
                    'FALL_USRE',
                    'FALL_FERE',
                    'FALL_USMO',
                    'FALL_FEMO',
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_FAULT_GET000: No se pudo realizar la consulta a la base.", [], 500);
        }
        return $this->responseController->makeResponse(false, "ÉXITO", $getFault);

    }

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

        try {
            $getListFault = DB::table('S002V01TLIFA')
                ->where('FALL_COEQ', '=', $request['CODIGO_EQUIPAMIENTO'])
                ->where('FALL_NULI', '=', $request['NUMERO_LINEA'])
                ->join('S002V01TFALL', 'FALL_IDFA', '=', 'LIFA_IDFA')
                ->distinct()
                ->get('FALL_IDFA AS ID_FALLA');
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_FAULT_GET001: No se pudo realizar la consulta a la base.", [], 500);
        }

        $request = $request->all();
        foreach ($getListFault as $key => $fault) {
            try {
                $getFault = DB::table('S002V01TFALL')
                    ->where('FALL_COEQ', '=', $request['CODIGO_EQUIPAMIENTO'])
                    ->where('FALL_NULI', '=', $request['NUMERO_LINEA'])
                    ->where('FALL_IDFA', '=', $fault->ID_FALLA)
                    ->join('S002V01TLIFA', 'FALL_IDFA', '=', 'LIFA_IDFA')
                    ->join('S002V01TLIME', 'FALL_IDME', '=', 'LIME_IDME')
                    ->get([
                        'FALL_NUFA AS NUMERO DE FALLA',
                        'FALL_COEQ AS CODIGO_EQUIPAMIENTO',
                        'FALL_IDFA AS ID_FALLA',
                        'LIFA_NOFA AS FALLA',
                        'FALL_CAUS AS CAUSA',
                        'FALL_FEFA AS FECHA_FALLA',
                        'FALL_CLAS AS CLASIFICACION',
                        'FALL_REPA AS REPARABLE',
                        'FALL_DESO AS DESCRIPCION DE SOLUCION',
                        'FALL_COME AS COMENARIOS',
                        'FALL_LIVA AS VALOR_LIMITE',
                        'FALL_VAOB AS VALOR_OBTENIDO',
                        'FALL_IDME AS ID_MEDIDA',
                        'LIME_MEDI AS MEDIDA',
                        'LIME_ACRO AS ACRONIMO',
                        'FALL_NUSI AS NUMERO_SINTOMA',
                        'FALL_ESTA AS ESTADO',
                        'FALL_USRE AS USUARIO_REGISTRA',
                        'FALL_FERE AS FECHA_REGISTRA',
                        'FALL_USMO AS USUARIO_MOFIFICA',
                        'FALL_FEMO AS FECHA_MOFIFICA',
                    ]);
            } catch (\Throwable $th) {
                return $this->responseController->makeResponse(true, "ERR_FAULT_GET002: No se pudo realizar la consulta a la base.", [], 500);
            }
            $fault->FALLA = $getFault[0]->FALLA;
            $fault->LISTA = $getFault;
        }

        return $this->responseController->makeResponse(false, "ÉXITO", $getListFault);
    }

    public function registerFault(Request $request) {
        $validator = Validator::make($request->all(), [
            'CODIGO_EQUIPAMIENTO' => 'required|string',
            'ID_FALLA' => 'required|string',
            'CAUSA' => 'required|string',
            'FECHA' => 'required|string',
            'CLASIFICACION' => 'required|string',
            'REPARABLE' => 'required|boolean',
            'COMENTARIOS' => 'required|string',
            'LIMITE_VALOR' => 'required|string',
            'VALOR_OBTENIDO' => 'required|string',
            'ID_MEDIDA' => 'required|string',
            'NUMERO_SINTOMA' => 'string',
            'NUMERO_LINEA' => 'required|string',
            'USUARIO' => 'required|string',
        ]);
        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_FAULT_REG000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($validator->errors()->messages()),
                401
            );
        }

        DB::beginTransaction();
        $request = $request->all();
        $line = $request['NUMERO_LINEA'];
        $currentDate = Carbon::now()->timezone('America/Mazatlan')->toDateTimeString();
        try {
            $user = $this->encController->decrypt($request['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_REG001: No se pudo obtener el usuario.", [], 500);
        }


        // Se valida que exista el ID del síntoma
        if ( $request['NUMERO_SINTOMA'] != null ) {
            try {
                $exist = DB::table('S002V01TSINT')
                    ->where('SINT_NUSI', '=', $request['NUMERO_SINTOMA'])
                    ->where('SINT_NULI', '=', $line)
                    ->where('SINT_ESTA', '=', 'Activo')
                    ->exists();
            } catch (\Throwable $th) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_FAULT_REG001: Ocurrió al consultar la lista de síntomas.", $th, 500);
            }
            if (!$exist) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_FAULT_REG002: No existe el síntoma seleccionado.", [], 500);
            }
        }


        // Se valida que exista el ID de la lista de medidas
        try {
            $existMeasure = DB::table('S002V01TLIME')
                ->where('LIME_IDME', '=', $request['ID_MEDIDA'])
                ->where('LIME_NULI', '=', $line)
                ->where('LIME_ESTA', '=', 'Activo')
                ->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_REG003: Ocurrió al consultar la lista de medidas.", $th, 500);
        }
        if ( !$existMeasure ) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_REG004: No existe la medida seleccionada.", [], 500);
        }


        // Se valida que exista el ID de la lista de fallas
        try {
            $existFailure = DB::table('S002V01TLIFA')
                ->where('LIFA_IDFA', '=', $request['ID_FALLA'])
                ->where('LIFA_NULI', '=', $line)
                ->where('LIFA_ESTA', '=', 'Activo')
                ->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_REG005: Ocurrió un error al consultar la lista de fallas.", $th, 500);
        }
        if (!$existFailure) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_REG006: No existe la falla seleccionada.", [], 500);
        }

        $arrInsert = [
            'FALL_COEQ' => trim($request['CODIGO_EQUIPAMIENTO']),
            'FALL_IDFA' => trim($request['ID_FALLA']),
            'FALL_CAUS' => trim($request['CAUSA']),
            'FALL_FEFA' => trim($request['FECHA']),
            'FALL_CLAS' => trim($request['CLASIFICACION']),
            'FALL_REPA' => trim($request['REPARABLE']),
            'FALL_DESO' => $request['DESCRIPCION'] === null ? $request['DESCRIPCION'] : trim($request['DESCRIPCION']),
            'FALL_COME' => trim($request['COMENTARIOS']),
            'FALL_LIVA' => trim($request['LIMITE_VALOR']),
            'FALL_VAOB' => trim($request['VALOR_OBTENIDO']),
            'FALL_IDME' => trim($request['ID_MEDIDA']),
            'FALL_NUSI' => $request['NUMERO_SINTOMA'] === null ? $request['NUMERO_SINTOMA'] : trim($request['NUMERO_SINTOMA']),
            'FALL_NULI' => $line,
            'FALL_USRE' => $user,
            'FALL_FERE' => $currentDate,
            'FALL_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
        ];
        try {
            $response = DB::table('S002V01TFALL')->insert($arrInsert);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_REG007: Ocurrió un error al insertar el formulario en la base de datos.", $th, 500);
        }

        if (!$response) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_REG008: No se pudo insertar el formulario en la base de datos.", [], 500);
        }

        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Registro Exitoso");
    }


    public function updateFault(Request $request) {
        $validator = Validator::make($request->all(), [
            'NUMERO_FALLA' => 'required|string',
            'CODIGO_EQUIPAMIENTO' => 'required|string',
            'ID_FALLA' => 'required|string',
            'CAUSA' => 'required|string',
            'FECHA' => 'required|string',
            'CLASIFICACION' => 'required|string',
            'REPARABLE' => 'required|boolean',
            'COMENTARIOS' => 'required|string',
            'LIMITE_VALOR' => 'required|string',
            'VALOR_OBTENIDO' => 'required|string',
            'ID_MEDIDA' => 'required|string',
            'NUMERO_SINTOMA' => 'string',
            'NUMERO_LINEA' => 'required|string',
            'USUARIO' => 'required|string',
        ]);
        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_FAULT_UPD000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($validator->errors()->messages()),
                401
            );
        }

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

        $idFault = trim($request['NUMERO_FALLA']);
        $line = $request['NUMERO_LINEA'];
        $currentDate = Carbon::now()->timezone('America/Mazatlan')->toDateTimeString();
        try {
            $user = $this->encController->decrypt($request['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_REG001: No se pudo obtener el usuario.", [], 500);
        }

        try {
            $exist = DB::table('S002V01TFALL')->where('FALL_NUFA', '=', $idFault)->where('FALL_NULI', '=', $line)->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_UPD001: Ocurrió un error al consultar en la base de datos.", $th, 500);
        }

        if (!$exist) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_UPD002: No se pudo encontrar el registro dentro de la base de datos.", [], 500);
        }

        // Se valida que exista el ID del síntoma
        if ( $request['NUMERO_SINTOMA'] != null ) {
            try {
                $exist = DB::table('S002V01TSINT')
                    ->where('SINT_NUSI', '=', $request['NUMERO_SINTOMA'])
                    ->where('SINT_NULI', '=', $line)
                    ->where('SINT_ESTA', '=', 'Activo')
                    ->exists();
            } catch (\Throwable $th) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_FAULT_UPD003: Ocurrió al consultar la lista de síntomas.", $th, 500);
            }
            if (!$exist) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_FAULT_UPD004: No existe el síntoma seleccionado.", [], 500);
            }
        }


        // Se valida que exista el ID de la lista de medidas
        try {
            $existMeasure = DB::table('S002V01TLIME')
                ->where('LIME_IDME', '=', $request['ID_MEDIDA'])
                ->where('LIME_NULI', '=', $line)
                ->where('LIME_ESTA', '=', 'Activo')
                ->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_UPD005: Ocurrió al consultar la lista de medidas.", $th, 500);
        }
        if ( !$existMeasure ) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_UPD006: No existe la medida seleccionada.", [], 500);
        }


        // Se valida que exista el ID de la lista de fallas
        try {
            $existFailure = DB::table('S002V01TLIFA')
                ->where('LIFA_IDFA', '=', $request['ID_FALLA'])
                ->where('LIFA_NULI', '=', $line)
                ->where('LIFA_ESTA', '=', 'Activo')
                ->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_UPD007: Ocurrió un error al consultar la lista de fallas.", $th, 500);
        }
        if (!$existFailure) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_UPD008: No existe la falla seleccionada.", [], 500);
        }

        $arrUpdate = [
            'FALL_COEQ' => trim($request['CODIGO_EQUIPAMIENTO']),
            'FALL_IDFA' => trim($request['ID_FALLA']),
            'FALL_CAUS' => trim($request['CAUSA']),
            'FALL_FEFA' => trim($request['FECHA']),
            'FALL_CLAS' => trim($request['CLASIFICACION']),
            'FALL_REPA' => trim($request['REPARABLE']),
            'FALL_DESO' => $request['DESCRIPCION'] === null ? $request['DESCRIPCION'] : trim($request['DESCRIPCION']),
            'FALL_COME' => trim($request['COMENTARIOS']),
            'FALL_LIVA' => trim($request['LIMITE_VALOR']),
            'FALL_VAOB' => trim($request['VALOR_OBTENIDO']),
            'FALL_IDME' => trim($request['ID_MEDIDA']),
            'FALL_NUSI' => $request['NUMERO_SINTOMA'] === null ? $request['NUMERO_SINTOMA'] : trim($request['NUMERO_SINTOMA']),
            'FALL_USMO' => $user,
            'FALL_FEMO' => $currentDate,
            'FALL_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
        ];
        try {
            $response = DB::table('S002V01TFALL')->where('FALL_NUFA', '=', $idFault)->where('FALL_NULI', '=', $line)->update($arrUpdate);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_UPD009: Ocurrió un error al modificar el formulario en la base de datos.", $th, 500);
        }

        if (!$response) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_UPD010: No se pudo modificar el formulario en la base de datos.", [], 500);
        }
        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Modificación Exitosa");

    }

    public function deleteFault(Request $request) {
        $validator = Validator::make($request->all(), [
            'NUMERO_FALLA' => 'required|string',
            'NUMERO_LINEA' => 'required|string',
            'USUARIO' => 'required|string',
        ]);
        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_FAULT_DEL000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($validator->errors()->messages()),
                401
            );
        }

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

        $idFault = trim($request['NUMERO_FALLA']);
        $line = $request['NUMERO_LINEA'];
        $currentDate = Carbon::now()->timezone('America/Mazatlan')->toDateTimeString();
        try {
            $user = $this->encController->decrypt($request['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAILURES_REG001: No se pudo obtener el usuario.", $th, 500);
        }

        try {
            $exist = DB::table('S002V01TFALL')->where('FALL_NUFA', '=', $idFault)->where('FALL_NULI', '=', $line)->exists();
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_DEL001: Ocurrió un error al consultar en la base de datos.", $th, 500);
        }

        if (!$exist) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_DEL002: No se pudo encontrar el registro dentro de la base de datos.", [], 500);
        }

        $arrUpdate = [
            'FALL_ESTA' => 'Eliminado',
            'FALL_USMO' => $user,
            'FALL_FEMO' => $currentDate,
            'FALL_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
        ];
        try {
            $response = DB::table('S002V01TFALL')->where('FALL_NUFA', '=', $idFault)->where('FALL_NULI', '=', $line)->update($arrUpdate);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_FAULT_DEL003: Ocurrió un error al modificar el formulario en la base de datos.", $th, 500);
        }

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

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