package cn.palmte.work.model;

import cn.palmte.work.utils.InterfaceUtil;
import cn.palmte.work.utils.ObjectKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import top.jfunc.common.db.bean.Page;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Repository
public class AdminRepositoryImpl implements AdminRepositoryCustom {
    private static final Logger logger = LoggerFactory.getLogger(AdminRepositoryImpl.class);
    @Autowired
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<String> getAuthoritiesName(String adminId) {
        List<String> returnList = new ArrayList<>();
        String sql = " select p.permission from sys_user u, sys_user_role ur, sys_role r, sys_role_permission rp, sys_permission p "
                + " where u.is_deleted = 0 and ur.is_deleted = 0 and r.is_deleted = 0 and rp.is_deleted = 0 and p.is_deleted = 0 "
                + " and u.id = ur.user_id and ur.role_id = r.id and r.id = rp.role_id and rp.permission_id = p.id "
                + " and r.is_enable=1 and u.id=:adminId";
        Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.setParameter("adminId", adminId);
        List<String> resultList = nativeQuery.getResultList();
        for (String objects : resultList) {
            String permission = objects;
            returnList.add(permission);
        }
        return returnList;
    }

    @Override
    public List<String> getAuthoritieUrls(String adminId) {
        List<String> returnList = new ArrayList<>();
        String sql = " select p.url from sys_user u, sys_user_role ur, sys_role r, sys_role_permission rp, sys_permission p "
                + " where u.is_deleted = 0 and ur.is_deleted = 0 and r.is_deleted = 0 and rp.is_deleted = 0 and p.is_deleted = 0 "
                + " and u.id = ur.user_id and ur.role_id = r.id and r.id = rp.role_id and rp.permission_id = p.id "
                + " and r.is_enable=1 and u.id=:adminId";
        Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.setParameter("adminId", adminId);
        List<String> resultList = nativeQuery.getResultList();
        for (String objects : resultList) {
            String permission = objects;
            returnList.add(permission);
        }
        return returnList;
    }


    @Override
    public List<String> getRolesName(String adminId) {
        String sql = " select r.name,r.id from sys_user u, sys_user_role ur, sys_role r where u.is_deleted = 0 " +
                "and ur.is_deleted = 0 and r.is_deleted = 0 and r.is_enable=1 and u.id = ur.user_id and " +
                " r.id = ur.role_id and u.id=:id";
        List<String> returnList = new ArrayList<>();

        Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.setParameter("id", adminId);
        List<Object[]> resultList = nativeQuery.getResultList();
        for (Object[] objects : resultList) {
            String permission = (objects != null && objects.length > 0) ? objects[0].toString() : "";
            returnList.add(permission);
        }
        return returnList;
    }

    @Override
    public Admin findAdminByUserName(String userName) {
        String sql = "  select u.id,u.user_name,u.real_name,r.type,r.id as rId,r.name,u.salt,r.level from sys_user u, sys_user_role ur, sys_role r where u.is_deleted = 0 " +
                "and ur.is_deleted = 0 and r.is_deleted = 0 and u.id = ur.user_id and " +
                " r.id = ur.role_id and u.user_name=:userName";

        Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.setParameter("userName", userName);
        List<Object[]> resultList = nativeQuery.getResultList();
        Admin admin = null;
        if (!resultList.isEmpty()) {
            for (Object[] objects : resultList) {
                admin = new Admin();
                admin.setId(ObjectKit.toInt(objects[0]));
                admin.setUserName(ObjectKit.toString(objects[1]));
                admin.setRealName(ObjectKit.toString(objects[2]));
                admin.setRoleType(ObjectKit.toInt(objects[3]));
                admin.setRoleId(ObjectKit.toInt(objects[4]));
                admin.setRoleName(ObjectKit.toString(objects[5]));
                admin.setSalt(ObjectKit.toString(objects[6]));
                admin.setRoleLevel(ObjectKit.toInt(objects[7]));
            }
        }
        return admin;
    }

    @Override
    public SysRole getRole(String adminId) {
        String sql = " select r.* from sys_user u, sys_user_role ur, sys_role r where u.is_deleted = 0 " +
                "and ur.is_deleted = 0 and r.is_deleted = 0 and r.is_enable=1 and u.id = ur.user_id and " +
                " r.id = ur.role_id and u.id=:id";

        Query nativeQuery = entityManager.createNativeQuery(sql, SysRole.class);
        nativeQuery.setParameter("id", adminId);
        SysRole object = (SysRole) nativeQuery.getSingleResult();
        return object;
    }

    @Override
    public Page<Admin> getAdminList(Map<String, String> searchInfo, int pageSize, int pageNum) {
        Page<Admin> page = new Page(pageNum, pageSize);
        int thisPage = (pageNum - 1) * pageSize;
        String sql = getSelect() + getSqlExceptSelect(searchInfo) + " limit " + thisPage + "," + pageSize;
        String countSql = " SELECT COUNT(*) FROM(" + getSelect() + getSqlExceptSelect(searchInfo) + ") count_table";
        Query nativeQuery = entityManager.createNativeQuery(sql.toString());
        Query countQuery = entityManager.createNativeQuery(countSql);
        List<Object[]> resultList = nativeQuery.getResultList();
        List<Admin> admins = new ArrayList<>();
        Admin admin = null;
        page.setTotalRow(((BigInteger) countQuery.getSingleResult()).intValue());
        for (Object[] objects : resultList) {
            admin = new Admin();
            admin.setId(ObjectKit.toInt(objects[0]));
            admin.setUserName(ObjectKit.toString(objects[1]));
            admin.setEnabled(ObjectKit.toInt(objects[4]));
            admin.setRealName(ObjectKit.toString(objects[2]));
            admin.setTelephone(ObjectKit.toString(objects[7]));
            admin.setRoleName(ObjectKit.toString(objects[6]));

            admin.setWorkLocation(ObjectKit.toString(objects[10]));
            admin.setEmpCode(ObjectKit.toString(objects[9]));
            admin.setDeptName(ObjectKit.toString(objects[11]));
            admin.setPositionName(ObjectKit.toString(objects[13]));
            admin.setDirectManager(ObjectKit.toString(objects[12]));
            admin.setCompanyEmail(ObjectKit.toString(objects[14]));
            try {
                admin.setCreatedTime(ObjectKit.toDate(objects[3]));
            } catch (ParseException e) {
                logger.error("账号创建时间转换错误" + e.toString());
            }
            admins.add(admin);
        }
        page.setList(admins);
        return page;
    }

    public String getSelect() {
        String select = "  select u.id,u.user_name,u.real_name,u.created_time,u.enabled,r.type,r.name,u.telephone,u.role_name,u.emp_code,u.work_location,u.dept_name,u.direct_manager,u.position_name,u.company_email";
        return select;
    }

    public String getSqlExceptSelect(Map<String, String> searchInfo) {
        StringBuffer sqlExceptSelect = new StringBuffer(" from sys_user u LEFT JOIN sys_user_role ur on u.id = ur.user_id LEFT JOIN sys_role r on r.id = ur.role_id ");

        Admin admin = InterfaceUtil.getAdmin();

        //String sql = " where u.is_deleted = 0 and ur.is_deleted = 0 and r.is_deleted = 0 and r.is_enable=1 and u.id!=1 and u.id!=" + InterfaceUtil.getAdminId();
        String sql = " where u.is_deleted = 0 and ur.is_deleted = 0 and r.is_deleted = 0 and r.is_enable=1 ";
        sqlExceptSelect.append(sql);
        for (Map.Entry<String, String> item : searchInfo.entrySet()) {
            sqlExceptSelect.append(buildQuery(item));
        }
        sqlExceptSelect.append(" order by u.id desc ");
        return sqlExceptSelect.toString();
    }

    private String buildQuery(Map.Entry<String, String> item) {
        String sql = "";
        if (item.getKey().equals("realName")) {
            sql += " and u.real_name like '%" + item.getValue() + "%' ";
        } else if (item.getKey().equals("telephone")) {
            sql += " and u.telephone= " + item.getValue();
        } else if (item.getKey().equals("empCode")) {
            sql += " and u.emp_code= " + item.getValue();
        } else if (item.getKey().equals("workLocation")) {
            sql += " and u.work_location= " + item.getValue();
        } else if (item.getKey().equals("startTime")) {
            sql += " and u.created_time >= " + item.getValue() + " 00:00:00";
        } else if (item.getKey().equals("endTime")) {
            sql += " and u.created_time <= " + item.getValue() + " 23:59:59";
        } else if (item.getKey().equals("deptId")) {
            if (!item.getValue().equals("-1")) {
                sql += " and u.dept_id= " + item.getValue();
            }
        } else if (item.getKey().equals("roleId")) {
            if (!item.getValue().equals("-1")) {
                sql += " and r.id= " + item.getValue();
            }
        }
        return sql;
    }

    /**
     * 获取指定角色的所有用户
     *
     * @param type
     * @return
     */
    private List<Admin> getAllRolesByType(int type) {
        String sql = "select * from sys_user u " +
                " left join sys_user_role ur on ur.user_id=u.id" +
                " left join sys_role r on r.id = ur.role_id" +
                " where u.is_deleted = 0 and ur.is_deleted = 0 and r.is_deleted = 0 and r.is_enable=1" +
                " and r.type=:type";

        return entityManager.createNativeQuery(sql, Admin.class).setParameter("type", type).getResultList();
    }

    @Override
    public Admin findAdminById(int userId) {
        String sql = "  select u.id,u.user_name,u.real_name,r.type,r.id as rId,u.telephone,u.region_id,r.level from sys_user u, sys_user_role ur, sys_role r where u.is_deleted = 0 " +
                "and ur.is_deleted = 0 and r.is_deleted = 0 and r.is_enable=1 and u.id = ur.user_id and " +
                " r.id = ur.role_id and u.id=:userId";

        Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.setParameter("userId", userId);
        List<Object[]> resultList = nativeQuery.getResultList();
        Admin admin = null;
        if (!resultList.isEmpty()) {
            for (Object[] objects : resultList) {
                admin = new Admin();
                admin.setId(ObjectKit.toInt(objects[0]));
                admin.setUserName(ObjectKit.toString(objects[1]));
                admin.setRealName(ObjectKit.toString(objects[2]));
                admin.setRoleType(ObjectKit.toInt(objects[3]));
                admin.setRoleId(ObjectKit.toInt(objects[4]));
                admin.setTelephone(ObjectKit.toString(objects[5]));
                admin.setRoleLevel(ObjectKit.toInt(objects[7]));
            }
        }
        return admin;
    }

    @Override
    public List<SysPermission> getAuthoritieUrlsByParentPermission(String adminId, String permission) {
        List<SysPermission> returnList = new ArrayList<>();
        String sql = " select distinct p.url,p.name,p.permission,p.sort from sys_user u, sys_user_role ur, sys_role r, sys_role_permission rp, sys_permission p "
                + " where u.is_deleted = 0 and ur.is_deleted = 0 and r.is_deleted = 0 and rp.is_deleted = 0 and p.is_deleted = 0 "
                + " and u.id = ur.user_id and ur.role_id = r.id and r.id = rp.role_id and rp.permission_id = p.id "
                + " and r.is_enable=1 and u.id=:adminId and p.parent_id = (select id from sys_permission sp where sp.permission=:permission)";
        Query nativeQuery = entityManager.createNativeQuery(sql);
        nativeQuery.setParameter("adminId", adminId);
        nativeQuery.setParameter("permission", permission);
        List<Object[]> resultList = nativeQuery.getResultList();
        for (Object[] objects : resultList) {
            SysPermission sysPermission = new SysPermission();
            sysPermission.setUrl((String) objects[0]);
            sysPermission.setName((String) objects[1]);
            sysPermission.setPermission((String) objects[2]);
            sysPermission.setSort((Integer) objects[3]);
            returnList.add(sysPermission);
        }
        return returnList;
    }
}
