<?php

namespace App\Http\Controllers;

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

use Illuminate\Support\Carbon;

class MESMCCController extends Controller{
    public function update(Request $request){
        //Se valida la información del usuario
        $validator = Validator::make($request->all(), [
            'numero_empleado' => 'required|string',
            'prev_password' => 'required|string|min:6',
            'new_password' => 'required|string|min:6|confirmed',
        ]);

        if ($validator->fails()) {
            return $this->makeResponse(
                true,
                "ERR_MESMCC_USU_UPD000: No se enviaron campos requeridos",
                $this->makeErrors($validator->errors()->messages()),
                401
            );
        }
        $passArr = $request->all();
        $pdo = DB::connection()->getPdo();

        $qryRFCE = "SELECT USUA_RFCE FROM S001V01TUSUA WHERE USUA_IDUS = :idus";
        $gstRFCE = $pdo->prepare($qryRFCE);
        $gstRFCE->bindParam(":idus", $passArr['numero_empleado']);

        $gstRFCE->execute();
        $rfce = $gstRFCE->fetchObject()->USUA_RFCE;

        $qry = "SELECT USUA_CONT, USUA_ULCC, USUA_HICO FROM S001V01TUSUA WHERE USUA_IDUS = :idus AND USUA_RFCE = :rfce";
        $gst = $pdo->prepare($qry);

        $gst->bindParam(":idus", $passArr['numero_empleado']);
        $gst->bindParam(":rfce", $rfce);
        //Se regresa un error si no se puede ejecutar la consulta
        if(!$gst->execute()){
            return $this->makeResponse(true, "ERR_MESMCC_SER_UPD001: No se ejecutó la consulta de la contraseña actual", [], 500);
        }
        //Se comprueba que el usuario exista
        $usr = $gst->fetchObject();
        if(!$usr){
            return $this->makeResponse(true, "ERR_MESMCC_USU_UPD002: El usuario introducido no existe", [], 404);
        }
        //Se verifica que el último cambio de contraseña haya sido hace más de un día
        $ulCam = new Carbon($usr->USUA_ULCC);
        $hoy = Carbon::now()->timezone('America/Mexico_City');
        $diff = $hoy->diffinDays($ulCam);

        if($diff < 1){
            return $this->makeResponse(true, "ERR_MESMCC_USU_UPD003: Para cambiar su contraseña de nuevo debe esperar al menos un día", [], 401);
        }

        $histCont = explode("|", $usr->USUA_HICO);

        foreach($histCont as $contStr){
            if(Hash::check($passArr['new_password'], $contStr)){
                return $this->makeResponse(true, "ERR_MESMCC_USU_UPD004: La contraseña que desea registrar ya fue utilizada previamente", [], 401);
            }
        }

        if(count($histCont) >= 5){
            array_pop($histCont);
        }

        $cont = Hash::make($passArr['new_password']);
        $histStr = $cont;

        foreach($histCont as $contStr){
            $histStr .= "|" . $contStr;
        }
        //Si el usuario existe, se valida que su contraseña sea correcta
        if(!Hash::check($passArr['prev_password'], $usr->USUA_CONT)){
            return $this->makeResponse(true, "ERR_MESMCC_USU_UPD005: La contraseña previa es incorrecta", [], 401);
        }
        //Si su contraseña es correcta entonces se procede a la modificación
        $qryUpd = "UPDATE S001V01TUSUA SET USUA_ULCC = :ulcc, USUA_HICO = :hico, USUA_CONT = :cont WHERE USUA_IDUS = :idus AND USUA_RFCE = :rfce";
        $gstUpd = $pdo->prepare($qryUpd);
        //Se hace el bind de los parámetros
        $ulcc = $hoy->toDateTimeString();
        $gstUpd->bindParam(":ulcc", $ulcc);
        $gstUpd->bindParam(":hico", $histStr);
        $gstUpd->bindParam(":cont", $cont);
        $gstUpd->bindParam(":idus", $passArr['numero_empleado']);
        $gstUpd->bindParam(":rfce", $rfce);
        //Se verifica que se pueda ejecutar la consulta
        if(!$gstUpd->execute()){
            return $this->makeResponse(true, "ERR_MESMCC_SER_UPD006: No se ejecutó la actualización de la contraseña", [], 500);
        }
        //Se retorn un mensaje de exito
        return $this->makeResponse(false, "EXITO");
    }

    private function makeResponse($error, $msg, $response = [], $code = 200){
        $respuesta = json_encode([
            "error" => $error,
            "msg" => $msg,
            "response" => $response
        ]);

        return response($respuesta, $code)->header('Content-Type', 'application/json');
    }

    private function makeErrors($erroresObj){
        $erroresArr = array();

        foreach ($erroresObj as $key => $value) {
            foreach ($value as $key0 => $value0) {
                if(array_key_exists($key, $erroresArr)){
                    $val = $erroresArr[$key] . "|" . $value0;
                    $erroresArr[$key] = $val;
                }else{
                    $erroresArr[$key] = $value0;
                }
            }
        }

        return $erroresArr;
    }
}