package com.xkrs.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xkrs.common.config.RedisUtil;
import com.xkrs.common.encapsulation.PromptMessageEnum;
import com.xkrs.dao.RelRoleAuthorityDao;
import com.xkrs.dao.RelUserRoleDao;
import com.xkrs.dao.SysRoleDao;
import com.xkrs.dao.SysUserDao;
import com.xkrs.model.entity.RelRoleAuthorityEntity;
import com.xkrs.model.entity.RelUserRoleEntity;
import com.xkrs.model.entity.SysRoleEntity;
import com.xkrs.model.entity.SysUserEntity;
import com.xkrs.model.qo.SysUserQo;
import com.xkrs.model.qo.UserUpdate;
import com.xkrs.model.vo.SysUserVo;
import com.xkrs.service.SysUserService;
import com.xkrs.utils.PhotoUtil;
import com.xkrs.utils.RequestUtil;
import org.apache.kafka.common.requests.RequestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.crypto.keygen.KeyGenerators;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static com.xkrs.common.encapsulation.OutputEncapsulation.outputEncapsulationObject;
import static com.xkrs.utils.DateTimeUtil.getNowTime;
import static com.xkrs.utils.EncryptDecryptUtil.encry256;

/**
 * 系统用户服务实现
 * @author tajochen
 */
@Service
public class SysUserServiceImpl implements SysUserService {

    Logger logger = LoggerFactory.getLogger(SysUserServiceImpl.class);

    @Resource
    private SysUserDao sysUserDao;

    @Resource
    private SysRoleDao sysRoleDao;

    @Resource
    private RelUserRoleDao relUserRoleDao;

    @Resource
    private RelRoleAuthorityDao relRoleAuthorityDao;

    @Resource
    private RedisUtil redisUtil;

    /**
     * 检查用户名是否存在
     * @param userName
     * @return
     */
    @Override
    public boolean checkUserName(String userName) {
        int num = sysUserDao.checkUserName(userName);
        return (num == 0);
    };

    /**
     * 新增用户
     * @param sysUserQo
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void addUser(SysUserQo sysUserQo) {
        String salt = KeyGenerators.string().generateKey();
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setUserName(sysUserQo.getUserName());
        sysUserEntity.setSalt(salt);
        sysUserEntity.setPassword(encry256(sysUserQo.getPassword() + salt));
//        sysUserEntity.setTelephone(sysUserQo.getTelephone());
        sysUserEntity.setActiveFlag(0);
        sysUserEntity.setStatusCode(0);
        sysUserEntity.setAddTime(getNowTime());
        sysUserEntity.setProvince(sysUserQo.getProvince());
        sysUserEntity.setCity(sysUserQo.getCity());
        sysUserEntity.setCounty(sysUserQo.getCounty());
        sysUserEntity.setDeleteFlag(0);
        int i = (int)(Math.random()*9+1)*100000;
        sysUserEntity.setIdentifier(String.valueOf(i));
        sysUserEntity.setIdentity(sysUserQo.getIdentity());

        sysUserDao.save(sysUserEntity);

        RelUserRoleEntity relUserRoleEntity = new RelUserRoleEntity();
        relUserRoleEntity.setUserId(sysUserEntity.getId().longValue());
        relUserRoleEntity.setRoleId(sysUserQo.getRoleId());

        RelRoleAuthorityEntity relRoleAuthorityEntity = new RelRoleAuthorityEntity();
        relRoleAuthorityEntity.setRoleId(sysUserQo.getRoleId());
        relRoleAuthorityEntity.setAuthorityId(sysUserQo.getAuthorityId());
        relRoleAuthorityEntity.setUserId(sysUserEntity.getId());
        relUserRoleDao.save(relUserRoleEntity);

        relRoleAuthorityDao.save(relRoleAuthorityEntity);

        //sysRoleDao.insertRelUserRole(sysUserEntity.getUserName(),"role_general_user");
    }

    /**
     * 查询所有用户Vo
     * @return
     */
    /*@Transactional(rollbackFor=Exception.class)
    @Override
    public Iterable<SysUserVo> getAllSysUser() {
        Iterable<SysUserVo> ls = sysUserDao.selectAllSysUser();
        return ls;
    }*/

    @Transactional(rollbackFor=Exception.class)
    @Override
    public SysUserEntity getSysUserByUserName(String userName) {
        return sysUserDao.selectByUserName(userName);
    }

    /**
     * 获取用户信息
     * @param userName
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public SysUserVo selectUserByUserName(String userName) {
        return sysUserDao.selectUserByUserName(userName);
    }

    @Transactional(rollbackFor=Exception.class)
    @Override
    public int updateSysUserLogin(String userName,String ipAddress) {
        return  sysUserDao.updateSysUserLogin(userName,ipAddress);
    }

    /**
     * 更新用户
     * @param sysUserQo
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public int updateSysUser(SysUserQo sysUserQo) {
        SysUserEntity sysUserEntity = new SysUserEntity();
        sysUserEntity.setNickName(sysUserQo.getNickName());
        sysUserDao.save(sysUserEntity);
        return  1;
    }

    /**
     * 软删除普通用户
     * @param id
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public int softDeleteGeneralUser(Integer id) {
        String adminRole = "role_administor";
        String sysRole ="role_system_manager";

        List<SysRoleEntity> list =  sysRoleDao.selectByUserId(id);
        if(list.size()>0){
            SysRoleEntity sysRoleEntity = list.get(1);
            if(sysRole.equals(sysRoleEntity.getRoleName())||adminRole.equals(sysRoleEntity.getRoleName())){
                sysUserDao.softDeleteGeneralUserById(id);
                return 0;
            }
        }
        return 1;
    }

    /**
     * 用户绑定手机号
     * @param userId
     * @param phone
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public String bindPhone(Integer userId, String phone) {
        Locale locale = LocaleContextHolder.getLocale();
        SysUserEntity byTelephone = sysUserDao.findByTelephone(phone);
        if(byTelephone != null){
            return outputEncapsulationObject(PromptMessageEnum.FILE_EXISTS,"该手机号已用于该平台的绑定！",locale);
        }
        sysUserDao.updatePhoneByUserId(userId,phone);
        return outputEncapsulationObject(PromptMessageEnum.SUCCESS,"绑定成功！！",locale);
    }

    /**
     * 手机号登录
     * @param phone
     * @param verificationCode
     * @return
     */
    @Override
    public String loginByPhone(String phone, String verificationCode) {
        Locale locale = LocaleContextHolder.getLocale();
        SysUserEntity byTelephone = sysUserDao.findByTelephone(phone);
        if(byTelephone == null){
            return outputEncapsulationObject(PromptMessageEnum.DATA_WRONG,"您还未绑定手机号！不能使用手机号登录！",locale);
        }
        String o = (String) redisUtil.get(phone);
        if("".equals(o) || o == null){
            return outputEncapsulationObject(PromptMessageEnum.DATA_WRONG,"请先发送验证码！",locale);
        }
        if(!redisUtil.get(phone).equals(verificationCode)){
            return outputEncapsulationObject(PromptMessageEnum.DATA_WRONG,"验证码错误，请重新输入！",locale);
        }
        String url = "http://localhost:6809/api/login";
        Map<String,String> map = new HashMap(3);
        map.put("userName",byTelephone.getUserName());
        map.put("password",byTelephone.getPassword());
        String userLogin = RequestUtil.doGet(url, map);
        JSONObject jsonObject = JSON.parseObject(userLogin);
        JSONObject data = (JSONObject) jsonObject.get("data");
        return outputEncapsulationObject(PromptMessageEnum.SUCCESS,data,locale);
    }

    /**
     * 用户完善个人信息
     * @param
     * @param
     * @param userId
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public String updateUserByUserId(String avatar, String nickName, Integer userId) throws IOException {
        Locale locale = LocaleContextHolder.getLocale();
        sysUserDao.updateUserByUserId(userId,nickName,avatar);
        return outputEncapsulationObject(PromptMessageEnum.SUCCESS,"提交成功！",locale);
    }

    /**
     * 启用
     * @param userId
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void updateEnable(Integer userId) {
        sysUserDao.updateEnable(userId);
    }

    /**
     * 禁用
     * @param userId
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void updateDisable(Integer userId) {
        sysUserDao.updateDisable(userId);
    }

    /**
     * 用户修改账号密码
     * @param oldPassword
     * @param newPassword
     * @param confirmPassword
     * @param userName
     * @param sysUserEntity
     * @return
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public String updatePassword(String oldPassword, String newPassword, String confirmPassword, String userName, SysUserEntity sysUserEntity) {
        Locale locale = LocaleContextHolder.getLocale();
        String oldFrontPassword = encry256(oldPassword + sysUserEntity.getSalt());
        if(!oldFrontPassword.equals(sysUserEntity.getPassword())){
            return outputEncapsulationObject(PromptMessageEnum.PROCESS_FAIL,"旧密码输入错误",locale);
        }
        if(!newPassword.equals(confirmPassword)){
            return outputEncapsulationObject(PromptMessageEnum.PROCESS_FAIL,"两次密码输入不一致",locale);
        }
        String newAfterPassword = encry256(newPassword + sysUserEntity.getSalt());
        sysUserDao.updatePassword(sysUserEntity.getId(),newAfterPassword,userName);
        return outputEncapsulationObject(PromptMessageEnum.SUCCESS,"密码修改成功",locale);
    }

}
