<?php

namespace App\Domain\Users\Repository;

use PDO;
use Illuminate\Database\Connection;
use Psr\Http\Message\ServerRequestInterface as Request;
use App\Util\TokenManager;
use Firebase\JWT\JWT;
use Exception;

/**
 * Repository.
 */
class UsersRepository {

    /**
     * @var PDO The database connection
     */

    private $connection;
    private $tokenManager;

    /**
     * Constructor.
     *
     * @param PDO $connection The database connection
     */

    public function __construct(Connection $connection) {

        $this->connection = $connection;
        $this->$tokenManager = new TokenManager();
    }

    /**
     * Insert user row.
     *
     * @param array $datos de los usuarios
     *
     * @return int The new ID
     */
    
    public function InsertRecord(array $User):array {

      //Hash Pass
      $pass = password_hash($User['pass'], PASSWORD_DEFAULT)."\n";

            $row = [
                'correo' => $User['email'],
                'nombre' => $User['name'],
                'clave' => $pass,
                'tipo' => $User['type'],
                'id_cities' => $User['cities']
            ];

            try { 

                $this->connection->table('usuarios')->insert($row);
                $vErr = 0;
                $result = [
                            'SqlState' => 'Transaccion ejecutada correctamente',
                            'ErrNumber' => $vErr,
                            'UniqueViolation' => 'Ok',
                            'Description' => 'El registro se creo correctamente',
                        ];

              } catch(\Illuminate\Database\QueryException $ex){ 

                $error=explode(":",$ex->getMessage());
                  //$descripcion=
                $err=substr($error[0],9,-1);
                  $result = [
                            'SqlState' => $error[0],
                            'ErrNumber' => $err,
                            'UniqueViolation' => $error[1],
                            'Description' => 'Ocurrio un error al momento de crear el registro',
                            'FullInfo' => trim($error[4])
                    ];
                // Note any method of class PDOException can be called on $ex.
                
              }
            
       return $result;
       // return (int)$this->connection->lastInsertId();
    }

    public function SearchRecords():string {
        $payload=$this->connection->table('usuarios')
        ->select('correo as email', 'nombre as name', 'clave as pass',
                'tipo as type', 'id_cities as cities')
        ->sharedLock()->get();
        return $payload;  
    }

    public function SearchRecord(string $id):string{
        $payload=$this->connection->table('activos')
        ->where('id_activo','=', $id)->get();
        return $payload;  
    }

    public function LoginVerify(Request $request, string $email, string $pass):array {
      
      //get data
      $payload = $this->connection->table('usuarios')
      ->where('correo','=', $email)->get();
      
      //access control
      if(sizeof($payload) != 0){
          
          $data = json_decode($payload, true);
          
          $emailId = $data[0]['correo'];
          $name = $data[0]['nombre'];
          $hash = trim($data[0]['clave'],"\n");
          $type = $data[0]['tipo'];
          $cities = $data[0]['id_cities'];
          
          if (password_verify($pass,$hash)){
              
               $result = [

                    'SqlState' => 'Transaccion ejecutada correctamente',
                    'ErrNumber' => '0',
                    'UniqueViolation' => 'Ok',
                    'Description' => 'Los datos ingresados son correctos',
                    'Email' => $emailId,
                    'Name' => $name,
                    'Pass' => $hash,
                    'Type' => $type,
                    'Cities' => $cities,
                    'Token' => $this->$tokenManager->ValidateToken($request, $emailId, $name)
                ];

          } else {
              
               $result = [

                    'SqlState' => 'Ocurrio un error',
                    'ErrNumber' => '01',
                    'UniqueViolation' => 'Failed',
                    'Password' => $hash,
                    'Description' => 'La contraseña es incorrecta',
                ];
  
          }
          
      } else {
        
        $result = [

            'SqlState' => 'Ocurrio un error',
            'ErrNumber' => '01',
            'UniqueViolation' => 'Failed',
            'Password' => $email,
            'Description' => 'El email ingresasdo no existe',
        ];
        
      }
      
      return $result;  
  }

    public function DeleteRecord(string $id):array {

        try { 

            $this->connection->table('usuarios')
            ->where(['correo' => $id])
            ->delete();

            $result = [
                    'SqlState' => 'Transaccion ejecutada correctamente',
                    'ErrNumber' => '0',
                    'UniqueViolation' => 'Ok',
                    'Description' => 'El registro se elimino correctamente',
                    'FullInfo' => ""
                ];

        } catch(\Illuminate\Database\QueryException $ex){ 

            //var_dump($ex->getMessage());  
            $error=explode(":",$ex->getMessage());
            //$descripcion=
            $err=substr($error[0],9,-1);

            $result = [
                    'SqlState' => $error[0],
                    'ErrNumber' => $err,
                    'UniqueViolation' => $error[1],
                    'Description' => 'Ocurrio un error al momento de eliminar el registro',
                    'FullInfo' => trim($error[4])
                ];
        // Note any method of class PDOException can be called on $ex.
      }

        return $result;
    }

    public function UpdateRecord(array $User):array {

        //Get password
        $pass = $User['pass'];

        if($pass != "Null") {

            //Hash Pass
            $pass = password_hash($User['pass'], PASSWORD_DEFAULT)."\n";

            $row = [

                //'correo' => $User['email'],
                'nombre' => $User['name'],
                'clave' => $pass,
                'tipo' => $User['type'],
                'id_cities' => $User['cities']

            ];

        } else {

            $row = [
                'nombre' => $User['name'],
                'tipo' => $User['type'],
                'id_cities' => $User['cities']
            ];

        }

            try { 

                $this->connection->table('usuarios')
                ->where(['correo' => $User['email']])
                ->update($row);

                $result = [
                            'SqlState' => 'Transaccion ejecutada correctamente',
                            'ErrNumber' => '0',
                            'UniqueViolation' => 'Ok',
                            'Description' => 'El registro se actualizo correctamente',
                            'FullInfo' => ''
                        ];

              } catch(\Illuminate\Database\QueryException $ex){ 
                //var_dump($ex->getMessage());  
                $error=explode(":",$ex->getMessage());
                  //$descripcion=
                $err=substr($error[0],9,-1);

                  $result = [
                            'SqlState' => $error[0],
                            'ErrNumber' => $err,
                            'UniqueViolation' => $error[1],
                            'Description' => 'Ocurrio un error al momento de actualizar el registro',
                            'FullInfo' => trim($error[4])
                        ];

                // Note any method of class PDOException can be called on $ex.
              }

       return $result;
    }

     public function UpdateCity(string $email, string $cities, int $city): array {

        // convert and unit
        $ids = $cities .",". $city;

        $row = [
            'id_cities' => $ids
        ];

        try {

            $this->connection->table('usuarios')
            ->Where('correo', '=', $email)
            ->Update($row);

            $result = [
                            'SqlState' => 'Transaccion ejecutada correctamente',
                            'ErrNumber' => '0',
                            'UniqueViolation' => 'Ok',
                            'Description' => 'Se actualizaron las ciudades del administrador',
                            'FullInfo' => ''. $city
                        ];

        } catch(\Illuminate\Database\QueryException $ex) {
 
                $error=explode(":",$ex->getMessage());
                $err=substr($error[0],9,-1);

                  $result = [
                            'SqlState' => $error[0],
                            'ErrNumber' => $err,
                            'UniqueViolation' => $error[1],
                            'Description' => 'Ocurrio un error al actualizar las ciudades',
                            'FullInfo' => trim($error[4])
                        ];

                // Note any method of class PDOException can be called on $ex.
              }

              return $result;
        }
}