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

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 RequestLineController extends Controller
{
    private $responseController;
    private $encController;

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

    // Se registran las líneas de solicitud
    public function createRequestLine(Request $request){

        $validator = Validator::make($request->all(), [
            'line' => 'required|string',
            'user' => 'required|string',
            'description' => 'required|string',
            'products' => 'required|string'
        ]);

        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_ORDER_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['user']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_REG001: Ocurrió un error al obtener el usuario.", [], 500);
        }

        try {
            $line = $this->encController->decrypt($requestData['line']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_REG002: Ocurrió un error al obtener la línea.", [], 500);
        }

        try {
            $description = $this->encController->decrypt($requestData['description']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_REG003: Ocurrió un error al obtener el contenido de la descripción.", [], 500);
        }

        try {
            $strArtitles = $this->encController->decrypt($requestData['products']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_REG004: Ocurrió un error al obtener los productos del artículo.", [], 500);
        }

        if (empty($strArtitles)) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_REG005: No se encontró ningún registro de productos.", [], 500);
        }

        $arrResponseArti = [
            'LINE_DESC' => $description,
            'LINE_NULI' => $line,
            'LINE_USRE' => $user,
            'LINE_FERE' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
            'LINE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
        ];

        try {
            $idRegisterLine = DB::table('S002V01TLINE')->insertGetId($arrResponseArti);
            if ($idRegisterLine == null || $idRegisterLine <= 0) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_ORDER_REG006: Ocurrió un error al hacer la inserción en la base.", [], 500);
            }
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_REG007: Ocurrió un error al hacer la inserción en la base.", $th->getMessage(), 500);
        }

        $arrArtitles = json_decode($strArtitles);
        foreach ($arrArtitles as $keyArtitles => $artitles) {

            $idArtitle = $artitles->idArtitle;
            $arrProducts = $artitles->content;
            $idProvider = $artitles->idProvider;
            foreach ($arrProducts as $keyProducts => $products) {
                $arrResponseProd = [
                    'ARSE_IDLI' => $idRegisterLine,
                    'ARSE_IDAR' => $idArtitle,
                    'ARSE_NUPR' => $idProvider,
                    'ARSE_IDIN' => $products->NUMERO_INFORMACION,
                    'ARSE_CANT' => $products->CANTIDAD,
                    'ARSE_PRTO' => $products->CANTIDAD * $products->PRECIO,
                    'ARSE_NULI' => $line,
                    'ARSE_USRE' => $user,
                    'ARSE_FERE' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
                    'ARSE_FEAR' => DB::raw('CURRENT_TIMESTAMP')
                ];

                try {
                    $idRegisterArtitle = DB::table('S002V01TARSE')->insertGetId($arrResponseProd);
                    if ($idRegisterArtitle == null || $idRegisterArtitle <= 0) {
                        DB::rollBack();
                        return $this->responseController->makeResponse(true, "ERR_ORDER_REG008: Ocurrió un error al hacer la inserción en la base.", [], 500);
                    }
                } catch (\Throwable $th) {
                    DB::rollBack();
                    return $this->responseController->makeResponse(true, "ERR_ORDER_REG009: Ocurrió un error al hacer la inserción en la base.", $th->getMessage(), 500);
                }
            }
        }
        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Registro correcto");
    }

    // Se obtienen todas las líneas de solicitud
    public function getAllRequestLines($line){
        try {
            $arrRequestLines = DB::table('S002V01TLINE')
                ->where("LINE_NULI", "=", $line)
                ->get([
                    'LINE_IDLI AS ID_LINEA_SOLICITUD',
                    'LINE_DESC AS DESCRIPCION',
                    'LINE_ESTA AS ESTADO',
                    'LINE_FERE AS FECHA_REGISTRA',
                    'LINE_FEMO AS FECHA_MODIFICA',
                    'LINE_USRE AS USUARIO_MODIFICA',
                    'LINE_USRE AS USUARIO_MODIFICA'
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_ORDER_GET000: No se pudo realizar la consulta a la base.", [], 500);
        }

        foreach ($arrRequestLines as $keyRequest => $requestLines) {
            $idRequestLine = $requestLines->ID_LINEA_SOLICITUD;
            try {
                $countData = DB::table('S002V01TARSE')->where('ARSE_IDLI', '=', $idRequestLine)->count();
            } catch (\Throwable $th) {
                return $this->responseController->makeResponse(true, "ERR_ORDER_GET001: No se pudo realizar la consulta a la base", [], 500);
            }
            $requestLines->CANTIDAD = $countData;
        }

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

    // Se obtiene una línea de solicitud en específico
    public function getRequestLine($encIdRequestLine, $line){

        try {
            $idRequestLine = $this->encController->decrypt($encIdRequestLine);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_ORDER_GET000: Ocurrió un error al obtener el contenido.", [], 500);
        }
        try {
            $arrRequestLines = DB::table('S002V01TLINE')
                ->where("LINE_NULI", "=", $line)
                ->where("LINE_IDLI", "=", $idRequestLine)
                ->first([
                    'LINE_IDLI AS ID_LINEA_SOLICITUD',
                    'LINE_DESC AS DESCRIPCION',
                    'LINE_ESTA AS ESTADO',
                    'LINE_FERE AS FECHA_REGISTRA',
                    'LINE_FEMO AS FECHA_MODIFICA',
                    'LINE_USRE AS USUARIO_MODIFICA',
                    'LINE_USRE AS USUARIO_MODIFICA'
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_ORDER_GET001: No se pudo realizar la consulta a la base.", [], 500);
        }

        try {
            $arrProducts = DB::table('S002V01TARSE')
                ->where("ARSE_NULI", "=", $line)
                ->where('ARSE_IDLI', '=', $idRequestLine)
                ->where('PROV_ESTA', '=', 'Activo')
                ->join('S002V01TPROV', 'ARSE_NUPR', '=', 'PROV_NUPR')
                ->join('S002V01TINAR', 'ARSE_IDIN', '=', 'INAR_IDIN')
                ->get([
                    'ARSE_IDAS AS NUMERO_ARTI_SELE',
                    'ARSE_IDAR AS NUMERO_ARTICULO',
                    'ARSE_NUPR AS NUMERO_PRODUCTO',
                    'INAR_MODE AS MODELO',
                    'INAR_CODI AS CODIGO',
                    'INAR_CARA AS CARACTERISTICAS',
                    'ARSE_CANT AS CANTIDAD',
                    'INAR_PREC AS PRECIO_UNITARIO',
                    'INAR_MONE AS MONEDA',
                    'ARSE_PRTO AS PRECIO_TOTAL',
                    'ARSE_ESTA AS ESTADO',
                    'ARSE_USRE AS USUARIO_REGISTRA',
                    'ARSE_FERE AS FECHA_REGISTRA',
                    'ARSE_USMO AS USUARIO_MODIFICA',
                    'ARSE_FEMO AS FECHA_MODIFICA',
                    'PROV_NUPR AS NUMERO_PROVEEDOR',
                    'PROV_NOCO AS PROVEEDOR',
                    'PROV_ESTA AS ESTADO_PROVEEDOR'
                ]);

                foreach ($arrProducts as $productos) {
                    if ($productos == 'Eliminado') {
                        return $this->responseController->makeResponse(true, "ERR_ORDER_GET002: Existe un usuario en la solicitud que se encuentra eliminado", [], 500);
                    }
                }

            $arrRequestLines->PRODUCTOS = $arrProducts;
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_ORDER_GET003: No se pudo realizar la consulta a la base.", [], 500);
        }

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

    // Se cancalan la linea de solicitud de compra
    public function cancelRequestLine(Request $request){
        $validator = Validator::make($request->all(), [
            'line' => 'required|string',
            'user' => 'required|string',
            'idRequestLine' => 'required|string',
        ]);

        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_ORDER_CAN000: 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['user']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_CAN001: Ocurrió un error al obtener el contenido.", [], 500);
        }
        try {
            $line = $this->encController->decrypt($requestData['line']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_CAN002: Ocurrió un error al obtener la línea.", [], 500);
        }
        try {
            $idRequestLine = $this->encController->decrypt($requestData['idRequestLine']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_CAN003: Ocurrió un error al obtener el identificador de la línea de solicitud de compra.", [], 500);
        }

        $currentDate = Carbon::now()->timezone('America/Mazatlan')->toDateTimeString();
        $objRequest = [
            'LINE_ESTA' => 'Cancelado',
            'LINE_USMO' => $user,
            'LINE_FEMO' => $currentDate,
            'LINE_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
        ];

        try {
            $response = DB::table('S002V01TLINE')->where('LINE_IDLI', '=', $idRequestLine)->update($objRequest);
            if ($response == null || $response <= 0) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_ORDER_CAN004: Ocurrió un error al hacer la inserción en la base.", [], 500);
            }
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_CAN005: No se pudo realizar la modificación a la base.", [], 500);
        }
        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Cancelación Exitosa");
    }

    public function updateStatusRequestLine(Request $request) {
        $validator = Validator::make($request->all(), [
            'NUMERO_SOLICITUD' => 'required|string',
            'ESTADO' => 'required|string',
            'USUARIO' => 'required|string',
            'METODO_PAGO' => 'required|string',
            'NUMERO_LINEA' => 'required|string',
            // 'COMENTARIOS' => 'string',
        ]);

        if ($validator->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_ORDER_UPST000: 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_ORDER_UPST001: Ocurrió un error al obtener el usuario.", [], 500);
        }

        $arrUpdate = [
            'LINE_ESTA' => $requestData['ESTADO'],
            'LINE_IDME' => $requestData['METODO_PAGO'],
            'LINE_COME' => $requestData['COMENTARIOS'] === '' ? null : $requestData['COMENTARIOS'],
            'LINE_USMO' => $user,
            'LINE_FEMO' => Carbon::now()->timezone('America/Mazatlan')->toDateTimeString(),
            'LINE_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
        ];

        try {
            $validateUpdate = DB::table('S002V01TLINE')
                ->where('LINE_IDLI', '=', $requestData['NUMERO_SOLICITUD'])
                ->where('LINE_NULI', '=', $requestData['NUMERO_LINEA'])
                ->update($arrUpdate);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_UPST002: Ocurrió un error al modificar el estado.", $th->getMessage(), 500);
        }

        if ( !$validateUpdate ) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_ORDER_UPST003: No se pudo modificar el estado de la línea de solicitud.", [], 500);
        }

        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Modificación de Estado Exitoso");

    }
}
