<?php

namespace App\Http\Controllers;

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

class DocumentManagementController extends Controller{
    private $responseController;
    private $encryptionController;
    private $functionsController;

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

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

        $tokenInfo = DB::table('S002V01TTODE')->where([
            ['TODE_NULI', '=', $line],
            ['TODE_TOKE', '=', $token]
        ])->first();

        if(is_null($tokenInfo)){
            return $this->responseController->makeResponse(true, 'El token de descarga no existe.', [], 404);
        }else if($tokenInfo->TODE_ESTA != 'Activo'){
            return $this->responseController->makeResponse(true, 'El token de descarga ya fue utilizado.', [], 401);
        }

        $token = $this->encryptionController->shortDec($token);
        if(!$token){
            return $this->responseController->makeResponse(true, 'El token de descarga no está encriptado correctamente.', [], 400);
        }

        $tokenArr = explode("|", $token);
        if(count($tokenArr) != 3){
            return $this->responseController->makeResponse(true, 'Estructura de token inválida.', [], 401);
        }else if(intval($tokenArr[1]) != $tokenInfo->TODE_LLAL){
            return $this->responseController->makeResponse(true, 'Token inválido.', [], 401);
        }else if($tokenArr[2] != 'syp'){
            return $this->responseController->makeResponse(true, 'Token inválido.', [], 401);
        }

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

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

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

        $id = $tokenArr[0];
        $codiArr = explode("=", $id);
        $prefArr = explode("-", $codiArr[0]);
        $suffArr = explode(".", $codiArr[2]);

        $nuli = intval($prefArr[0]);
        $como = $prefArr[1];
        $cldo = $prefArr[2];
        $fecr = $prefArr[3];
        $nuse = intval($prefArr[4]);
        $nuve = $codiArr[1];
        $noar = $suffArr[0];
        $exte = $suffArr[1];

        $nowStr = Carbon::now('America/Mexico_city')->toDateTimeString();
        DB::table('S002V01TTODE')->where([
            ['TODE_IDTO', '=', $tokenInfo->TODE_IDTO],
            ['TODE_NULI', '=', $line]
        ])->update([
            'TODE_ESTA' => 'Usado',
            'TODE_USDE' => $idUser,
            'TODE_FEDE' => $nowStr
        ]);
        
        $file = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $nuli],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
            ['AFAL_FECR', '=', $fecr],
            ['AFAL_NUSE', '=', $nuse],
            ['AFAL_NUVE', '=', $nuve],
            ['AFAL_NOAR', '=', $noar],
            ['AFAL_EXTE', '=', $exte],
        ])->first();

        if(is_null($usr)){
            return $this->responseController->makeResponse(true, 'El archivo solicitado no existe.', [], 404);
        }

        return response()->download($file->AFAL_UBIC);
    }

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

        $idFile = $this->encryptionController->shortDec($idFile);
        if(!$idFile){
            return $this->responseController->makeResponse(true, 'El ID del archivo requerido no está encriptado correctamente.', [], 400);
        }

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

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

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

        $codiArr = explode("=", $idFile);
        $prefArr = explode("-", $codiArr[0]);
        $suffArr = explode(".", $codiArr[2]);

        $nuli = intval($prefArr[0]);
        $como = $prefArr[1];
        $cldo = $prefArr[2];
        $fecr = $prefArr[3];
        $nuse = intval($prefArr[4]);
        $nuve = $codiArr[1];
        $noar = $suffArr[0];
        $exte = $suffArr[1];
        
        $file = DB::table('S002V01TAFAL')->where([
            ['AFAL_NULI', '=', $nuli],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
            ['AFAL_FECR', '=', $fecr],
            ['AFAL_NUSE', '=', $nuse],
            ['AFAL_NUVE', '=', $nuve],
            ['AFAL_NOAR', '=', $noar],
            ['AFAL_EXTE', '=', $exte],
        ])->first();

        if(is_null($file)){
            return $this->responseController->makeResponse(true, 'El archivo solicitado no existe.', [], 404);
        }

        $rand = rand(0, 99999);
        $tokenArr = [$idFile, $rand, "syp"];
        $tokenStr = join('|', $tokenArr);

        $token = $this->encryptionController->shortEnc($tokenStr);
        $token = str_replace("+", "=P=", $token);
        $token = str_replace("/", "=S=", $token);
        $nowStr = Carbon::now('America/Mexico_city')->toDateTimeString();

        DB::table('S002V01TTODE')->insert([
            'TODE_NULI' => $line,
            'TODE_TOKE' => $token,
            'TODE_CODO' => $idFile,
            'TODE_LLAL' => $rand,
            'TODE_USRE' => $idUser,
            'TODE_FERE' => $nowStr
        ]);

        return $this->responseController->makeResponse(false, 'EXITO', ['TOKEN' => $token]);
    }

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

        $id = $this->encryptionController->shortDec($id);
        if(!$id){
            return $this->responseController->makeResponse(true, 'El ID del archivo requerido no está encriptado correctamente.', [], 400);
        }

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

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

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

        $idArr = explode("=", $id);
        $codiArr = explode("-", $idArr[0]);

        $nuli = $line;
        $como = $codiArr[1];
        $cldo = $codiArr[2];
        $fecr = $codiArr[3];
        $nuse = intval($codiArr[4]);
        $nuve = intval($idArr[1]);

        $fileInfo = DB::table('S002V01TAFAL')->select([
            'AFAL_NOAR AS NOMBREARCHIVO',
            'AFAL_EXTE AS EXTENSION',
            'AFAL_TAMA AS PESO',
            'AFAL_USAC AS ACCESO',
            'AFAL_ESTA AS ESTADO'
        ])->where([
            ['AFAL_NULI', '=', $nuli],
            ['AFAL_COMO', '=', $como],
            ['AFAL_CLDO', '=', $cldo],
            ['AFAL_FECR', '=', $fecr],
            ['AFAL_NUSE', '=', $nuse],
            ['AFAL_NUVE', '=', $nuve],
        ])->first();

        if(is_null($fileInfo)){
            return $this->responseController->makeResponse(true, 'El archivo solicitado no está registrado.', [], 404);
        }else if($fileInfo->ESTADO != 'Activo'){
            return $this->responseController->makeResponse(true, 'El archivo solicitado no está disponible.', [], 404);
        }

        return $this->responseController->makeResponse(false, 'EXITO', $fileInfo);
    }
}