package com.example.cezenPBX.DAO;

import com.example.cezenPBX.DTO.ReturnStatus;
import com.example.cezenPBX.entity.user.Role;
import com.example.cezenPBX.entity.user.UserEntity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class UserOpsDAOImpl implements UserOpsDAO{

    @Autowired
    private EntityManager entityManager;

    @Override
    public boolean checkIfAdminExists(UserEntity userEntity){
        // check if info exists in the database users table
        // this enforces the fact that only one user can exist
        Query query = entityManager.createQuery(
                "SELECT COUNT(u) FROM UserEntity u JOIN u.roles r WHERE r.role = :roleName");
        query.setParameter("roleName", "ROLE_Admin");
        Long count = (Long) query.getSingleResult();
        return count > 0;

    }

    // get roles from the database

    // Admin sets a username and password for the first time
    @Override
    @Transactional
    public ReturnStatus adminSetUsernameAndPassword(UserEntity userEntity) {

        try {
            if (checkIfAdminExists(userEntity)) {
                return new ReturnStatus(false, "Admin already exists", "");
            }
            // Fetch existing ROLE_Admin from DB
            TypedQuery<Role> query = entityManager.createQuery("FROM Role r WHERE r.role = :roleName", Role.class)
                    .setParameter("roleName", "ROLE_Admin");

            Role role = query.getSingleResult();

            userEntity.setARole(role);
            // Persist the user
            entityManager.persist(userEntity);
            return new ReturnStatus(true, "Admin created", "");
        } catch (Exception e) {
            return new ReturnStatus(false, "Admin creation failed", e.getMessage());
        }
    }

    // get user details by username
    // throws an exception if the user doesn't exist
    // exception is caught and returns null ... custom authentication provider must catch the exception
    @Override
    public UserEntity getUserByUserName(String userName) {

        try{
            TypedQuery<UserEntity> query = this.entityManager
                    .createQuery("SELECT u FROM UserEntity u JOIN FETCH u.roles AS r WHERE u.userName = :userName", UserEntity.class);

            query.setParameter("userName", userName);

            return query.getSingleResult();

        }catch ( Exception e){
            return null;
        }
    }
}
