package cn.palmte.work.service;

import cn.palmte.work.bean.RegexConstant;
import cn.palmte.work.bean.ResponseMsg;
import cn.palmte.work.model.*;
import cn.palmte.work.utils.DESCrypto;
import cn.palmte.work.utils.InterfaceUtil;
import cn.palmte.work.utils.StrKit;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.jfunc.common.db.QueryHelper;
import top.jfunc.common.db.bean.Page;
import top.jfunc.common.db.bean.Record;
import top.jfunc.common.db.utils.Pagination;

import java.beans.Transient;
import java.util.*;

/**
 * Created by wang.lin@esstx.cn on 2018/4/20.
 */
@Service
public class AccountService {
    private static final Logger logger = LoggerFactory.getLogger(AccountService.class);

    @Autowired
    public AdminRepository adminRepository;

    @Autowired
    public AdminRepositoryImpl adminRepositoryImpl;

    @Autowired
    public SysUserRoleRepository sysUserRoleRepository;

    @Autowired
    private Pagination pagination;

    @Autowired
    private SysRoleRepository sysRoleRepository;

    @Autowired
    private DeptRepository deptRepository;

    @Autowired
    private UserPositionRepository userPositionRepository;

    public Page<Admin> getAdminList(Map<String, String> searchInfo, int pageSize, int pageNum) {
        Page<Admin> adminList = adminRepositoryImpl.getAdminList(searchInfo, pageSize, pageNum);
        return adminList;
    }

    public Page<Admin> list(Map<String, String> searchInfo, int pageNumber, int pageSize) {
        QueryHelper queryHelper = new QueryHelper("*", "sys_user u");
        queryHelper.addCondition("u.is_deleted = 0");
        queryHelper.addCondition("u.id > 1");
        queryHelper.addCondition(searchInfo.containsKey("realName"), "u.real_name like ?", "%" +
                searchInfo.get("realName") + "%");
        queryHelper.addCondition(searchInfo.containsKey("telephone"), "u.telephone =?", searchInfo.get("telephone"));
        queryHelper.addCondition(searchInfo.containsKey("userName"), "u.user_name =?", searchInfo.get("userName"));
        queryHelper.addCondition(searchInfo.containsKey("deptId") &&
                        StrKit.notBlank(searchInfo.get("deptId")) && !"-1".equals(searchInfo.get("deptId")),
                "u.dept_id =?", searchInfo.get("deptId"));
        queryHelper.addCondition(searchInfo.containsKey("roleId") &&
                        StrKit.notBlank(searchInfo.get("roleId")) && !"-1".equals(searchInfo.get("roleId")),
                "u.role_id =?", searchInfo.get("roleId"));
        queryHelper.addCondition(searchInfo.containsKey("workLocation"), "u.work_location like ?", "%" +
                searchInfo.get("workLocation") + "%");
        queryHelper.addCondition(searchInfo.containsKey("startTime"), "u.created_time >= ?",
                searchInfo.get("startTime") + " 00:00:00");
        queryHelper.addCondition(searchInfo.containsKey("endTime"), "u.created_time <= ?",
                searchInfo.get("endTime") + " 23:59:59");
        queryHelper.addOrderProperty("u.created_time", false);
        Page<Admin> page = pagination.paginate(queryHelper.getSql(), Admin.class, pageNumber, pageSize);
        return page;

    }

    @Transient
    public boolean changeStatus(int userId, int enabled) {
        Admin admin = adminRepository.findOne(userId);
        if (admin == null) {
            return false;
        }
        admin.setEnabled(enabled);
        adminRepository.save(admin);
        return true;
    }

    public Admin findUserById(int userId) {
        Admin admin = adminRepository.findOne(userId);
        return admin;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdateAccount(int userId, int roleId, Admin admin, String privateKey) {
        int createAdminId = InterfaceUtil.getAdminId();
        Admin oldAdmin = adminRepository.findOne(userId);
        Dept dept = deptRepository.findOne(admin.getDeptId());
        SysRole sysRole = sysRoleRepository.findOne(admin.getRoleId());
//        UserPosition userPosition = userPositionRepository.findOne(admin.getPositionId());
        if (oldAdmin == null) {
            oldAdmin = new Admin();
            String userName = admin.getUserName();
            oldAdmin.setUserName(userName);
            String salt = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
            String newPassword = decEncPassword(admin.getTelephone().substring(5), salt, privateKey);

            BeanUtils.copyProperties(admin, oldAdmin);

            oldAdmin.setRealName(admin.getRealName());
            oldAdmin.setDeptName(dept.getName());
            oldAdmin.setPositionName(admin.getPositionName());
            oldAdmin.setPassword(newPassword);
            oldAdmin.setSalt(salt);
            oldAdmin.setEnabled(1);
            oldAdmin.setCreatedBy(createAdminId);
            oldAdmin.setTelephone(admin.getTelephone());
            oldAdmin.setCreatedTime(new Date());

        } else {
            String userName = admin.getUserName();
            oldAdmin.setDeptId(admin.getDeptId());
//            oldAdmin.setPositionId(admin.getPositionId());
            oldAdmin.setRealName(admin.getRealName());
            oldAdmin.setDeptName(dept.getName());
            oldAdmin.setPositionName(admin.getPositionName());
            //oldAdmin.setEmpCode(admin.getEmpCode());
            oldAdmin.setWorkLocation(admin.getWorkLocation());
            oldAdmin.setDirectManager(admin.getDirectManager());
            oldAdmin.setCompanyEmail(admin.getCompanyEmail());
            oldAdmin.setUserName(userName);
            oldAdmin.setRealName(admin.getRealName());
            oldAdmin.setTelephone(admin.getTelephone());
            oldAdmin.setLastUpdatedBy(createAdminId);
            oldAdmin.setLastUpdatedTime(new Date());
        }
        oldAdmin.setRoleId(admin.getRoleId());
        SysRole one = sysRoleRepository.findOne(admin.getRoleId());
        if (null != one) {
            oldAdmin.setRoleName(one.getName());
        }
        admin = adminRepository.saveAndFlush(oldAdmin);
        //设置当前用户角色关系状态为删除
        userId = admin.getId();
        sysUserRoleRepository.deleteSysUserRoleByUserId(createAdminId, new Date(), userId);
        SysUserRole sysUserRole = new SysUserRole();
        //保存用户角色关系
        sysUserRole.setUserId(userId);
        sysUserRole.setRoleId(roleId);
        sysUserRole.setCreatedBy(createAdminId);
        sysUserRole.setCreatedTime(new Date());
        sysUserRoleRepository.save(sysUserRole);
    }

    /**
     * 检查用户是否存在于系统中
     */
    public String validateUserExistInfo(int userId, Admin admin) {
        String message = "";
        //校验手机号格式
        String phone = admin.getTelephone();
        if (!phone.matches(RegexConstant.REGEX)) {
            return "请填写正确的电话号码！";
        }

        //工号重复校验
        /*Admin empCode = adminRepository.findByEmpCode(admin.getEmpCode());
        if (userId == -1) {
            if (null != empCode) {
                message = "该工号已存在！";
                return message;
            }
        } else {
            if (null != empCode && empCode.getId() != userId) {
                message = "该工号已存在！";
                return message;
            }
        }*/

        //手机号重复校验
        Admin byTelephoneEquals = adminRepository.findByTelephone(phone);
        if (userId == -1) {
            if (null != byTelephoneEquals) {
                message = "该手机号已存在！";
                return message;
            }
        } else {
            if (null != byTelephoneEquals && byTelephoneEquals.getId() != userId) {
                message = "该手机号已存在！";
                return message;
            }
        }

        if (StringUtils.isEmpty(admin.getUserName())) {
            message = "工号不能为空！";
            return message;
        }
        Admin existAdmin = adminRepository.getAdminByUsername(admin.getUserName());
        if (userId == -1) {
            if (existAdmin != null) {
                message = "该工号已存在！";
                return message;
            }
        } else {
            if (existAdmin != null && existAdmin.getId() != userId) {
                message = "该工号已存在！";
                return message;
            }
        }

        Admin realName = adminRepository.getAdminByRealName(admin.getRealName());
        if (userId == -1) {
            if (realName != null) {
                message = "该姓名已存在！";
                return message;
            }
        } else {
            if (realName != null && realName.getId() != userId) {
                message = "该姓名已存在！";
                return message;
            }
        }
        return message;
    }


    public String decEncPassword(String password, String salt, String privateKey) {
        try {
            return DESCrypto.encryptPassword(password, salt);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public boolean resetPassword(int userId, String privateKey) {
        try {
            Admin oldAdmin = adminRepository.findOne(userId);
            if (oldAdmin == null) {
                return false;
            }
            String salt = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
            String telephone = oldAdmin.getTelephone();
            String newPassword = decEncPassword(telephone.substring(5), salt, privateKey);
            oldAdmin.setPassword(newPassword);
            oldAdmin.setSalt(salt);
            oldAdmin.setLastUpdatedBy(InterfaceUtil.getAdminId());
            oldAdmin.setLastUpdatedTime(new Date());
            adminRepository.save(oldAdmin);
        } catch (Exception e) {
            logger.error("充值密码错误！" + e.toString());
            return false;
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAccount(int userId) {
        try {
            Admin admin = adminRepository.findOne(userId);
            admin.setDeleted(true);
            admin.setLastUpdatedBy(InterfaceUtil.getAdminId());

            //删除用户角色关系
            sysUserRoleRepository.deleteSysUserRoleByUserId(InterfaceUtil.getAdminId(), new Date(), userId);

            adminRepository.save(admin);
            return true;
        } catch (Exception e) {
            logger.error("账户ID:" + userId + "删除错误！" + e.toString());
        }
        return false;
    }

    @Transactional
    public ResponseMsg check(Collection<Map> excelMap) {
        int successCount = 0;
        int errorCount = 0;
        List<String> errorList = new ArrayList<>();
        int createAdminId = InterfaceUtil.getAdminId();
        Admin admin = null;

        if (excelMap.size() == 0) {
            ResponseMsg msg = ResponseMsg.buildSuccessMsg("请填写人员数据！");
            msg.setData(errorList);
            return msg;
        }

        for (Map m : excelMap) {

            try {
                Object empCode = m.get("工号");
                if (empCode == null || StrKit.isBlank(empCode.toString())) {
                    throw new Exception("工号不能为空");
                }

                Admin byEmpCode = adminRepository.getAdminByUsername(empCode.toString());

                if (null != byEmpCode) {
                    throw new Exception("工号" + empCode.toString() + "已存在");
                }

                Object telephone = m.get("手机号码");
                if (telephone == null || StrKit.isBlank(telephone.toString())) {
                    throw new Exception("手机号码不能为空");
                }

                Admin byTelephone = adminRepository.findByTelephone(telephone.toString());
                if (null != byTelephone) {
                    throw new Exception("手机号码" + telephone.toString() + "已存在");
                }

                /*Object userName = m.get("登录名称");
                if (userName == null || StrKit.isBlank(userName.toString())) {
                    throw new Exception("登录名称不能为空");
                }

                Admin byUsername = adminRepository.getAdminByUsername(userName.toString());
                if (null != byUsername) {
                    throw new Exception("登录名称" + byUsername.toString() + "已存在");
                }*/

                Object realName = m.get("姓名");
                if (realName == null || StrKit.isBlank(realName.toString())) {
                    throw new Exception("姓名不能为空");
                }

                Admin byRealName = adminRepository.getAdminByRealName(realName.toString());
                if (null != byRealName) {
                    throw new Exception("姓名" + realName.toString() + "已存在");
                }

                Object workLocation = m.get("常驻地");
                if (workLocation == null || StrKit.isBlank(workLocation.toString())) {
                    throw new Exception("常驻地不能为空");
                }

                Object deptName = m.get("一级部门");
                if (deptName == null || StrKit.isBlank(deptName.toString())) {
                    throw new Exception("一级部门不能为空");
                }

                Dept dept = deptRepository.findByNameEquals(deptName.toString());

                if (null == dept) {
                    throw new Exception("一级部门" + deptName.toString() + "不存在");
                }

                Object directManager = m.get("直接主管");
                if (directManager == null || StrKit.isBlank(directManager.toString())) {
                    throw new Exception("直接主管不能为空");
                }

                Object positionName = m.get("职位");
                if (positionName == null || StrKit.isBlank(positionName.toString())) {
                    throw new Exception("职位不能为空");
                }

//                UserPosition userPosition = userPositionRepository.findByPositionNameEquals(positionName.toString());
//
//                if (null == userPosition) {
//                    throw new Exception("职位" + positionName.toString() + "不存在");
//                }

                Object sysRole = m.get("角色名称");
                if (sysRole == null || StrKit.isBlank(sysRole.toString())) {
                    throw new Exception("角色名称不能为空");
                }

                SysRole role = sysRoleRepository.findByNameEqualsAndDeletedEquals(sysRole.toString(), 0);

                if (null == role) {
                    throw new Exception("角色" + sysRole.toString() + "不存在");
                }

                Object companyEmail = m.get("公司邮件地址");
                if (companyEmail == null || StrKit.isBlank(companyEmail.toString())) {
                    throw new Exception("公司邮件地址不能为空");
                }

                admin = new Admin();
                //admin.setEmpCode(empCode.toString());
                admin.setTelephone(telephone.toString());
                admin.setUserName(empCode.toString());
                admin.setRealName(realName.toString());
                admin.setWorkLocation(workLocation.toString());
                admin.setDeptId(dept.getId());
                admin.setDeptName(dept.getName());
                admin.setDirectManager(directManager.toString());
//                admin.setPositionId(userPosition.getId());
                admin.setPositionName(positionName.toString());
                admin.setRoleId(role.getId());
                admin.setRoleName(role.getName());
                admin.setCompanyEmail(companyEmail.toString());

                String salt = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
                String password = decEncPassword(admin.getTelephone().substring(5), salt, "");

                admin.setSalt(salt);
                admin.setPassword(password);
                admin.setCreatedBy(createAdminId);
                admin.setCreatedTime(new Date());
                admin.setLastUpdatedBy(createAdminId);
                admin.setLastUpdatedTime(new Date());
                admin.setEnabled(1);
                adminRepository.saveAndFlush(admin);

                //设置当前用户角色关系状态为删除
                sysUserRoleRepository.deleteSysUserRoleByUserId(createAdminId, new Date(), admin.getId());
                SysUserRole sysUserRole = new SysUserRole();
                //保存用户角色关系
                sysUserRole.setUserId(admin.getId());
                sysUserRole.setRoleId(role.getId());
                sysUserRole.setCreatedBy(createAdminId);
                sysUserRole.setCreatedTime(new Date());
                sysUserRoleRepository.save(sysUserRole);

                successCount++;
            } catch (Exception e) {
                logger.error("", e);
                errorCount++;
                errorList.add(e.getMessage());
            }
        }
        final ResponseMsg msg = ResponseMsg.buildSuccessMsg(String.format("成功：%d, 失败：%d", successCount, errorCount));
        msg.setData(errorList);
        return msg;
    }


    /**
     * 通过id查询姓名
     *
     * @param id
     * @return
     */
    public String getNameById(int id) {
        Admin one = adminRepository.findOne(id);
        return one == null ? "" : one.getRealName();
    }

    /**
     * 通过角色id查询用户姓名列表
     *
     * @param roleIds
     * @return
     */
    public List<String> getUserIsByRole(List<String> roleIds) {
        if (roleIds == null || roleIds.isEmpty()) {
            return new ArrayList<>();
        }
        String sql = "select u.id as id from sys_user_role ur left join sys_user u on u.id=ur.user_id " +
                "  where  ur.is_deleted=0 and ur.role_id in (?) and u.enabled=1 and u.is_deleted=0";
        String ids = String.join("", roleIds);
        List<Record> records = pagination.find(sql, ids);
        if (records == null || records.isEmpty()) {
            return new ArrayList<>();
        }

        List<String> userIds = new ArrayList<>(roleIds.size());
        for (Record record : records) {
            Integer id = record.getInt("id");
            if (id != null) {
                userIds.add(id.toString());
            }
        }
        return userIds;
    }
}
