<?php

declare(strict_types=1);

namespace App\Repository;

final class UserRepository
{
    private \PDO $database;

    public function __construct(\PDO $database)
    {
        $this->database = $database;
    }

    public function getDb(): \PDO
    {
        return $this->database;
    }

    public function checkAndGet(int $UserId): object
    {
        $query = 'SELECT `id`, `fecha`, `name`, `email`, `field1`, `field2`, `field3`, `field4`, `field5` FROM `User` WHERE `id` = :id';
        $statement = $this->getDb()->prepare($query);
        $statement->bindParam('id', $UserId);
        $statement->execute();
        $User = $statement->fetchObject();
        if (! $User) {
            throw new \Exception('User not found.', 404);
        }

        return $User;
    }

    public function getAll(): array
    {
        $query = 'SELECT `id`, `fecha`, `name`, `email`, `field1`, `field2`, `field3`, `field4`, `field5` FROM `User` ORDER BY `id`';
        $statement = $this->getDb()->prepare($query);
        $statement->execute();

        return (array) $statement->fetchAll();
    }

    public function create(object $User): object
    {
        $query = 'INSERT INTO `User` (`name`, `email`, `password`, `field1`, `field2`, `field3`, `field4`, `field5`) 
        VALUES (:name, :email, :password, :field1, :field2, :field3, :field4, :field5)';
        $statement = $this->getDb()->prepare($query);
//         $statement->bindParam('id', $User->id);
//         $statement->bindParam('fecha', $User->fecha);
        $statement->bindParam('name', $User->name);
        $statement->bindParam('email', $User->email);
        $statement->bindParam('password', $User->password);
        $statement->bindParam('field1', $User->field1);
        $statement->bindParam('field2', $User->field2);
        $statement->bindParam('field3', $User->field3);
        $statement->bindParam('field4', $User->field4);
        $statement->bindParam('field5', $User->field5);

        $statement->execute();

        return $this->checkAndGet((int) $this->getDb()->lastInsertId());
    }

    public function update(object $User, object $data): object
    {
        if (isset($data->fecha)) {
            $User->fecha = $data->fecha;
        }
        if (isset($data->name)) {
            $User->name = $data->name;
        }
        if (isset($data->email)) {
            $User->email = $data->email;
        }
        if (isset($data->password)) {
            $User->password = $data->password;
        }
        if (isset($data->field1)) {
            $User->field1 = $data->field1;
        }
        if (isset($data->field2)) {
            $User->field2 = $data->field2;
        }
        if (isset($data->field3)) {
            $User->field3 = $data->field3;
        }
        if (isset($data->field4)) {
            $User->field4 = $data->field4;
        }
        if (isset($data->field5)) {
            $User->field5 = $data->field5;
        }

        $query = 'UPDATE `User` SET `fecha` = :fecha, `name` = :name, `email` = :email, `password` = :password, `field1` = :field1, `field2` = :field2, `field3` = :field3, `field4` = :field4, `field5` = :field5 WHERE `id` = :id';
        $statement = $this->getDb()->prepare($query);
        $statement->bindParam('id', $User->id);
        $statement->bindParam('fecha', $User->fecha);
        $statement->bindParam('name', $User->name);
        $statement->bindParam('email', $User->email);
        $statement->bindParam('password', $User->password);
        $statement->bindParam('field1', $User->field1);
        $statement->bindParam('field2', $User->field2);
        $statement->bindParam('field3', $User->field3);
        $statement->bindParam('field4', $User->field4);
        $statement->bindParam('field5', $User->field5);

        $statement->execute();

        return $this->checkAndGet((int) $User->id);
    }

    public function delete(int $UserId): void
    {
        $query = 'DELETE FROM `User` WHERE `id` = :id';
        $statement = $this->getDb()->prepare($query);
        $statement->bindParam('id', $UserId);
        $statement->execute();
    }
  
   
    public function login(object $UserAux): object
    {
        if (! isset($UserAux->email)) {
            throw new \Exception('El campo "correo electrónico" es obligatorio.', 404);
        }
        if (! isset($UserAux->password)) {
            throw new \Exception('El campo "contraseña" es obligatorio.', 404);
        }
      
        $query = 'SELECT * FROM `User` WHERE `email` = :email';
        $statement = $this->getDb()->prepare($query);
        $statement->bindParam('email', $UserAux->email);
        $statement->execute();
        $User = $statement->fetchObject();
        
        if (! $User) {
            throw new \Exception('Usuario no encontrado.', 404);
        }
      
        if (! isset($User->password)) {
            throw new \Exception('Correo electrónico o contraseña incorrectos.', 404);
        }
      
        if (! password_verify($UserAux->password, $User->password)) {
            throw new \Exception('Correo electrónico o contraseña incorrectos.', 404);
        }
      
        if ( $User->field1 === "TblAdmin") {
//             $query = 'SELECT * FROM ' . $User->field1 . ' WHERE id = :id AND `CorreoElectronico` = :email AND estado = "ACTIVO"';
            $query = 'SELECT * FROM ' . $User->field1 . ' WHERE id = :id AND `CorreoElectronico` = :email';
            $statement = $this->getDb()->prepare($query);
            $statement->bindParam('id', $User->field2);
            $statement->bindParam('email', $User->email);
            $statement->execute();
            $UserAux = $statement->fetchObject();
          
            if ($UserAux->Estado !== "ACTIVO") {
                throw new \Exception('Usuario INACTIVO.', 404);
            }
        } else if ( $User->field1 === "TblUsuario") {
//             $query = 'SELECT * FROM ' . $User->field1 . ' WHERE id = :id AND `CorreoElectronico` = :email AND (field1 != "PENDIENTE" OR field1 IS NOT NULL)';
            $query = 'SELECT * FROM ' . $User->field1 . ' WHERE id = :id AND `CorreoElectronico` = :email';
            $statement = $this->getDb()->prepare($query);
            $statement->bindParam('id', $User->field2);
            $statement->bindParam('email', $User->email);
            $statement->execute();
            $UserAux = $statement->fetchObject();
          
            if ($UserAux->field1 == "PENDIENTE") {
                throw new \Exception('Usuario PENDIENTE de activar link en correo electrónico.', 404);
            } else if ($UserAux->field1 == "PENDIENTE ENVIADO") {
                throw new \Exception('Usuario PENDIENTE de activar link en correo electrónico.', 404);
            } else if ($UserAux->field1 == "RECUPERACION") {
                throw new \Exception('Usuario en RECUPERACIÓN de acceso, favor verificar correo electrónico con nueva contraseña.', 404);
            } else if ($UserAux->field1 == "RECUPERACION ENVIADO") {
                throw new \Exception('Usuario en RECUPERACIÓN de acceso, favor verificar correo electrónico con nueva contraseña.', 404);
            } else if ($UserAux->field1 !== "ACTIVO") {
                throw new \Exception('Usuario INACTIVO.', 404);
            }
        } else if ( $User->field1 === "TblRepresentante") {
//             $query = 'SELECT * FROM ' . $User->field1 . ' WHERE id = :id AND `field2` = :email AND field1 = "ACTIVO"';
            $query = 'SELECT * FROM ' . $User->field1 . ' WHERE id = :id AND `field2` = :email';
            $statement = $this->getDb()->prepare($query);
            $statement->bindParam('id', $User->field2);
            $statement->bindParam('email', $User->email);
            $statement->execute();
            $UserAux = $statement->fetchObject();
          
            if ($UserAux->field1 !== "ACTIVO") {
                throw new \Exception('Usuario INACTIVO.', 404);
            }
        } else if ( $User->field1 === "TblSupervisor") {
//             $query = 'SELECT * FROM ' . $User->field1 . ' WHERE id = :id AND `field2` = :email AND field1 = "ACTIVO"';
            $query = 'SELECT * FROM ' . $User->field1 . ' WHERE id = :id AND `field2` = :email';
            $statement = $this->getDb()->prepare($query);
            $statement->bindParam('id', $User->field2);
            $statement->bindParam('email', $User->email);
            $statement->execute();
            $UserAux = $statement->fetchObject();
          
            if ($UserAux->field1 !== "ACTIVO") {
                throw new \Exception('Usuario INACTIVO.', 404);
            }
        } else {
            throw new \Exception('Usuario no definido.', 404);
        }

        return $User;
    }
}
