<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Validator;

class OrderDocumentsController extends Controller
{
    private $responseController;
    private $encController;
    private $resourcesController;
    private $documentManagementController;
    private $functionsController;

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

    public function getDocument($user, $line) {
        try {
            $arrDocuments = DB::table('S002V01TDLSC')
                ->where('DLSC_NULI', '=', $line)
                ->where('LINE_NULI', '=', $line)
                ->join('S002V01TLINE', 'DLSC_IDLI', '=', 'LINE_IDLI')
                ->get([
                    'LINE_IDLI',
                    'LINE_NUPR',
                    'LINE_OTPR',
                    'LINE_OTCO',
                    'LINE_ESTA',
                    'DLSC_IDDO',
                    'DLSC_IDLI',
                    'DLSC_IDFA',
                    'DLSC_CODO',
                    'DLSC_TIPO',
                    'DLSC_DESC',
                    'DLSC_TIAR',
                    'DLSC_ESTA',
                    'DLSC_USRE',
                    'DLSC_FERE',
                    'DLSC_USMO',
                    'DLSC_FEMO',
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_GET000: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
        }

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

    public function getDocumentByRequestLine($requestLine, $user, $line) {

        try {
            $requestLine = $this->encController->decrypt($requestLine);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_REG001: Ocurrió un error al desencriptar los datos.", $th->getMessage(), 401);
        }

        try {
            $arrDocuments = DB::table('S002V01TDLSC')
                ->where('DLSC_NULI', '=', $line)
                ->where('LINE_NULI', '=', $line)
                ->where('DLSC_IDLI', '=', $requestLine)
                ->join('S002V01TLINE', 'DLSC_IDLI', '=', 'LINE_IDLI')
                ->get([
                    'LINE_IDLI',
                    'LINE_NUPR',
                    'LINE_OTPR',
                    'LINE_OTCO',
                    'LINE_ESTA',
                    'DLSC_IDDO',
                    'DLSC_IDLI',
                    'DLSC_IDFA',
                    'DLSC_CODO',
                    'DLSC_TIPO',
                    'DLSC_DESC',
                    'DLSC_TIAR',
                    'DLSC_ESTA',
                    'DLSC_USRE',
                    'DLSC_FERE',
                    'DLSC_USMO',
                    'DLSC_FEMO',
                ]);
        } catch (\Throwable $th) {
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_GET000: No se pudo realizar la consulta a la base.", $th->getMessage(), 500);
        }

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

    public function registerDocumentOrder(Request $request) {
        $valitador = Validator::make($request->all(), [
            'LINEA_SOLICITUD' => 'required|string',
            'TIPO_DOCUMENTO' => 'required|string',
            'TIPO_ARCHIVO' => 'required|string|max:2',
            'DOCUMENTO' => 'required|string',
            'DESCRIPCION' => 'required|string',
            'USUARIO' => 'required|string',
            'NUMERO_LINEA' => 'required|string',
        ]);

        if ($valitador->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_DOCUMENT_ORDER_REG000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($valitador->errors()->messages()),
                401
            );
        }

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

        try {
            $user = $this->encController->decrypt($responseData['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_REG001: Ocurrió un error al desencriptar el usuario.", $th->getMessage(), 401);
        }

        try {
            $idFile = $this->encController->decrypt($responseData['DOCUMENTO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_REG002: Ocurrió un error al desencriptar el documento.", $th->getMessage(), 401);
        }

        $tempFile = DB::table('S002V01TARTE')->where([
            ['ARTE_NULI', '=', $responseData['NUMERO_LINEA']],
            ['ARTE_IDAR', '=', $idFile],
        ])->first();
  
        if(is_null($tempFile)){
            return $this->responseController->makeResponse(true, 'ERR_DOCUMENT_ORDER_REG003: El archivo consultado no está registrado', [], 404);
        }else if($tempFile->ARTE_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'ERR_DOCUMENT_ORDER_REG004: El archivo consultado está eliminado', [], 404);
        }
        $fileResponse = $this->documentManagementController->moveFinalFile(
            intval($responseData['LINEA_SOLICITUD']),
            'GEAD',
            $responseData['TIPO_ARCHIVO'],
            $tempFile,
            $user,
        );
        if(!$fileResponse[0]){
            return $this->responseController->makeResponse(true, 'ERR_DOCUMENT_ORDER_REG005: '.$fileResponse[1], [], 400);
        }
        $encCode = $this->encController->encrypt($fileResponse[1]);

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

        try {
            $validateInsert = DB::table('S002V01TDLSC')
                ->insert([
                    'DLSC_NULI' => $responseData['NUMERO_LINEA'],
                    'DLSC_IDLI' => $responseData['LINEA_SOLICITUD'],
                    'DLSC_CODO' => $encCode,
                    'DLSC_TIPO' => $responseData['TIPO_DOCUMENTO'],
                    'DLSC_TIAR' => $responseData['TIPO_ARCHIVO'],
                    'DLSC_DESC' => $responseData['DESCRIPCION'],
                    'DLSC_USRE' => $user,
                    'DLSC_FERE' => $currentDate,
                    'DLSC_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_REG006: Ocurrió un error al registrar el documento.", $th->getMessage(), 401);
        }
        if (!$validateInsert) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_REG007: No se pudo registrar el documento.", [], 401);
        }

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

    public function updateDocumentOrder(Request $request) {
        $valitador = Validator::make($request->all(), [
            'LINEA_SOLICITUD' => 'required|string',
            'ID_DOCUMENTO' => 'required|int',
            'TIPO_DOCUMENTO' => 'required|string',
            'TIPO_ARCHIVO' => 'required|string',
            'DOCUMENTO' => 'required|string',
            'DESCRIPCION' => 'required|string',
            'USUARIO' => 'required|string',
            'NUMERO_LINEA' => 'required|string',
        ]);
        if ($valitador->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_DOCUMENT_ORDER_UPD000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($valitador->errors()->messages()),
                401
            );
        }

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

        try {
            $user = $this->encController->decrypt($responseData['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_UPD001: Ocurrió un error al desencriptar el usuario.", $th->getMessage(), 401);
        }

        try {
            $idFile = $this->encController->decrypt($responseData['DOCUMENTO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_UPD002: Ocurrió un error al desencriptar el documento.", $th->getMessage(), 401);
        }

        $tempFile = DB::table('S002V01TARTE')->where([
            ['ARTE_NULI', '=', $responseData['NUMERO_LINEA']],
            ['ARTE_IDAR', '=', $idFile],
        ])->first();
  
        if(is_null($tempFile)){
            return $this->responseController->makeResponse(true, 'ERR_DOCUMENT_ORDER_UPD003: El archivo consultado no está registrado', [], 404);
        }else if($tempFile->ARTE_ESTA == 'Eliminado'){
            return $this->responseController->makeResponse(true, 'ERR_DOCUMENT_ORDER_UPD004: El archivo consultado está eliminado', [], 404);
        }
        $fileResponse = $this->documentManagementController->moveFinalFile(
            intval($responseData['LINEA_SOLICITUD']),
            'GEAD',
            $responseData['TIPO_ARCHIVO'],
            $tempFile,
            $user,
        );
        if(!$fileResponse[0]){
            return $this->responseController->makeResponse(true, 'ERR_DOCUMENT_ORDER_UPD005: '.$fileResponse[1], [], 400);
        }
        $encCode = $this->encController->encrypt($fileResponse[1]);

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

        try {
            $validateUpdate = DB::table('S002V01TDLSC')
                ->where('DLSC_IDDO', '=', $responseData['ID_DOCUMENTO'])
                ->where('DLSC_NULI', '=', $responseData['NUMERO_LINEA'])
                ->where('DLSC_ESTA', '=', 'Activo')
                ->where('DLSC_IDLI', '=', $responseData['LINEA_SOLICITUD'])
                ->update([
                    'DLSC_CODO' => $encCode,
                    'DLSC_TIPO' => $responseData['TIPO_DOCUMENTO'],
                    'DLSC_TIAR' => $responseData['TIPO_ARCHIVO'],
                    'DLSC_DESC' => $responseData['DESCRIPCION'],
                    'DLSC_USMO' => $user,
                    'DLSC_FEMO' => $currentDate,
                    'DLSC_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_UPD006: Ocurrió un error al registrar el documento.", $th->getMessage(), 401);
        }
        if (!$validateUpdate) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_UPD007: No se pudo registrar el documento.", [], 401);
        }

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

    public function deleteDocumentOrder(Request $request) {
        $valitador = Validator::make($request->all(), [
            'ID_DOCUMENTO' => 'required|integer',
            'NUMERO_LINEA' => 'required|string',
            'USUARIO' => 'required|string'
        ]);
        if ($valitador->fails()) {
            return $this->responseController->makeResponse(
                true,
                "ERR_DOCUMENT_ORDER_DEL000: Se encontraron uno o más errores.",
                $this->responseController->makeErrors($valitador->errors()->messages()),
                401
            );
        }
        DB::beginTransaction();
        $responseData = $request->all();
        try {
            $user = $this->encController->decrypt($responseData['USUARIO']);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL001: Ocurrió un error al desencriptar los datos.", $th->getMessage(), 401);
        }

        $arrDeleteFileCode = array();
        try {
            $arrDocument = (array) DB::table('S002V01TDLSC')
                ->where('DLSC_IDDO', '=', $responseData['ID_DOCUMENTO'])
                ->where('DLSC_NULI', '=', $responseData['NUMERO_LINEA'])
                ->first([
                    'DLSC_IDLI',
                    'DLSC_IDFA',
                    'DLSC_CODO',
                    'DLSC_TIPO',
                    'DLSC_TIAR',
                    'DLSC_DESC',
                    'DLSC_ESTA',
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL002: Ocurrió un error al obtener los datos del documento.", $th->getMessage(), 401);
        }
        if (empty($arrDocument)) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL003: No se encontró el documento seleccionado.", [], 401);
        }

        if ($arrDocument['DLSC_ESTA'] == 'Eliminado') {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL004: El documento ya se encuentra eliminado.", [], 401);
        }

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

        try {
            $validateUpdate = DB::table('S002V01TDLSC')
                ->where('DLSC_IDDO', '=', $responseData['ID_DOCUMENTO'])
                ->where('DLSC_NULI', '=', $responseData['NUMERO_LINEA'])
                ->update([
                    'DLSC_ESTA' => 'Eliminado',
                    'DLSC_USMO' => $user,
                    'DLSC_FEMO' => $currentDate,
                    'DLSC_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                ]);
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL005: Ocurrió un error al eliminar el documento.", $th->getMessage(), 401);
        }
        if (!$validateUpdate) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL006: No se pudo modificar el registro del documento.", [], 401);
        }

        $arrDeleteFileCode[] = $arrDocument['DLSC_CODO'];

        if ($arrDocument['DLSC_IDFA'] != null) {
            try {
                $arrInvoice = (array) DB::table('S002V01TFALS')
                    ->where('FALS_IDFA', '=', $arrDocument['DLSC_IDFA'])
                    ->where('FALS_NULI', '=', $responseData['NUMERO_LINEA'])
                    ->where('FALS_IDLI', '=', $arrDocument['DLSC_IDLI'])
                    ->first([
                        'FALS_IDLI',
                        'FALS_CODO',
                        'FALS_UUID',
                        'FALS_VERS',
                        'FALS_FEEM',
                        'FALS_RFCE',
                        'FALS_RFCR',
                        'FALS_FOLI',
                        'FALS_SERI',
                        'FALS_FOPA',
                        'FALS_MEPA',
                        'FALS_TICA',
                        'FALS_MONE',
                        'FALS_COPA',
                        'FALS_ESTA',
                    ]);
            } catch (\Throwable $th) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL007: Ocurrió un error al obtener los datos de la factura.", $th->getMessage(), 401);
            }
            if (empty($arrDocument)) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL008: No se encontró la factura.", [], 401);
            }

            if ($arrInvoice['FALS_ESTA'] == 'Eliminado') {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL009: La factura ya se encuentra eliminada.", [], 401);
            }

            try {
                $validateUpdate = DB::table('S002V01TFALS')
                    ->where('FALS_IDFA', '=', $arrDocument['DLSC_IDFA'])
                    ->where('FALS_NULI', '=', $responseData['NUMERO_LINEA'])
                    ->where('FALS_IDLI', '=', $arrDocument['DLSC_IDLI'])
                    ->update([
                        'FALS_ESTA' => 'Eliminado',
                        'FALS_USMO' => $user,
                        'FALS_FEMO' => $currentDate,
                        'FALS_FEAR' => DB::raw('CURRENT_TIMESTAMP'),
                    ]);
            } catch (\Throwable $th) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL010: Ocurrió un error al eliminar la factura.", $th->getMessage(), 401);
            }
            if (!$validateUpdate) {
                DB::rollBack();
                return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL011: No se pudo modificar el registro de la factura.", [], 401);
            }

            $arrDeleteFileCode[] = $arrInvoice['FALS_CODO'];
        }

        try {
            foreach ($arrDeleteFileCode as $key => $fileCode) {
                $arrDelete = [
                    'id_file' =>  $fileCode,
                    'id_user' =>  $responseData['USUARIO'],
                    'linea' =>  $responseData['NUMERO_LINEA'],
                ];
                $request = new Request($arrDelete);

                $responseDocument = $this->documentManagementController->deleteFile($request);
                $arrResponseDocument = json_decode($responseDocument->original, true);
                if ($arrResponseDocument['error']) {
                    return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL012: Ocurrió un error al eliminar el documento.", [], 500);
                }
            }
        } catch (\Throwable $th) {
            DB::rollBack();
            return $this->responseController->makeResponse(true, "ERR_DOCUMENT_ORDER_DEL013: Ocurrió un error la intentar eliminar los documentos.", $th->getMessage(), 401);
        }
        
        DB::commit();
        return $this->responseController->makeResponse(false, "ÉXITO: Eliminación de Documento Exitoso");
    }
}
