package com.iotechn.unimall.admin.api.user;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.iotechn.unimall.admin.config.WebSocket;
import com.iotechn.unimall.biz.utils.GeTuiUtils;
import com.iotechn.unimall.biz.utils.SendUtils;
import com.iotechn.unimall.core.exception.AdminServiceException;
import com.iotechn.unimall.core.exception.ExceptionDefinition;
import com.iotechn.unimall.core.exception.ServiceException;
import com.iotechn.unimall.core.util.MD5Util;
import com.iotechn.unimall.data.domain.*;
import com.iotechn.unimall.data.dto.AdminDTO;
import com.iotechn.unimall.data.dto.UserDTO;
import com.iotechn.unimall.data.mapper.*;
import com.iotechn.unimall.data.model.Page;
import org.apache.commons.codec.digest.Md5Crypt;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.sql.*;
import java.util.*;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: kbq
 * Date: 2019-07-11
 * Time: 下午7:57
 */
@Service
public class AdminUserServiceImpl implements AdminUserService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    TransactionDefinition transactionDefinition;
    @Autowired
    private SendUtils sendUtils;

    WebSocket webSocket = new WebSocket();
    GeTuiUtils geTuiUtils = new GeTuiUtils();
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addUser(Long adminId, UserDO user) throws ServiceException {
        if (user == null){
            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
        }
        if(user.getPhone() == null){
            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
        }
        if(userMapper.selectCount(new EntityWrapper<UserDO>().eq("phone",user.getPhone())) > 0){
            throw new AdminServiceException(ExceptionDefinition.USER_PHONE_ALREADY_EXIST);
        }
        Date now = new Date();
        user.setId(null);
        user.setPassword(Md5Crypt.md5Crypt(user.getPassword().getBytes(), "$1$" + user.getPhone().substring(0,7)));
        user.setGmtCreate(now);
        user.setGmtUpdate(now);
        return userMapper.insert(user) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteUser(Long adminId, Long id, String nickname) throws ServiceException {
        if(StringUtils.isEmpty(nickname)){
            return userMapper.delete(new EntityWrapper<UserDO>()
                    .eq("id", id)) > 0;
        }
        return userMapper.delete(new EntityWrapper<UserDO>()
                .eq("id", id)
                .eq("nickname",nickname)) > 0;
    }

    @Override
    public Boolean updateUser(Long adminId, UserDTO user,Long companyId) throws ServiceException {
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try{
            if (user == null || user.getId() == null){
                throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
            }
            if(user.getPhone() == null){
                throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
            }
            if(userMapper.selectCount(new EntityWrapper<UserDO>().eq("phone",user.getPhone()).notIn("id",user.getId())) > 0){
                throw new AdminServiceException(ExceptionDefinition.USER_PHONE_ALREADY_EXIST);
            }
            Date now = new Date();
            user.setGmtUpdate(now);

            if(user.getPassword() != null) {
                user.setPassword(Md5Crypt.md5Crypt(user.getPassword().getBytes(), "$1$" + user.getPhone().substring(0, 7)));
            }
            UserDO userDO = userMapper.selectById(user.getId());
            BeanUtils.copyProperties(user,userDO);
            userDO.setRoleIds(JSONObject.toJSONString(user.getRoleIds()));
            Wrapper wrapper = new EntityWrapper();
            wrapper.eq("user_id", user.getId());
            dataSourceTransactionManager.commit(transactionStatus);

            userDO.setGmtUpdate(new Date());
            UserDO userDOExist = userMapper.selectById(user.getId());
            if (!StringUtils.isEmpty(userDO.getPassword()) && !StringUtils.isEmpty(userDOExist.getUserName())) {
                userDO.setPassword(MD5Util.md5(userDO.getPassword(), userDOExist.getUserName()));
            }
            userDO.setUserName(user.getUserName());
            if (!CollectionUtils.isEmpty(user.getRoleIds())) {
                userDO.setRoleIds(JSONObject.toJSONString(user.getRoleIds()));
            }
            userDO.setCompanyId(companyId);
            if (userMapper.updateById(userDO) > 0) {
                return true;
            }
            else{
                dataSourceTransactionManager.rollback(transactionStatus);
                throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
            }
        }
        catch (Exception e){
            //手动回滚事务
            dataSourceTransactionManager.rollback(transactionStatus);
            throw new AdminServiceException(ExceptionDefinition.ADMIN_UNKNOWN_EXCEPTION);
        }

    }

    @Override
    public Boolean updateStatus(Long adminId, Long userId,Integer status) throws ServiceException {
        if(userId == null || status == null || (status != 0 && status != 1)){
            throw new AdminServiceException(ExceptionDefinition.USER_INFORMATION_MISSING);
        }
        UserDO userDO = new UserDO();
        userDO.setId(userId);
        userDO.setStatus(status);
        userDO.setGmtUpdate(new Date());
        return userMapper.updateById(userDO) > 0;
    }

    @Override
    public Page<UserDTO> getUser(Long adminId, Long id, String nickname, String userName, Integer gender,Integer status,String phone,Integer pageNo,Integer limit,Long companyId) throws ServiceException {
        Wrapper wrapper = new EntityWrapper();

        if (userName != null) {
            wrapper.like("user_name", userName);
        }
        if (nickname != null) {
            wrapper.like("nickname", nickname);
        }
        if (phone != null) {
            wrapper.like("phone", phone);
        }
        wrapper.eq("company_id",companyId);
        wrapper.orNew();
        wrapper.isNull("company_id");
        if (userName != null) {
            wrapper.like("user_name", userName);
        }
        if (nickname != null) {
            wrapper.like("nickname", nickname);
        }
        if (phone != null) {
            wrapper.like("phone", phone);
        }
        wrapper.orderBy("user_name",false);
        Integer count = userMapper.selectCount(wrapper);
        List<UserDO> userDOList = userMapper.selectPage(new RowBounds((pageNo - 1) * limit, limit), wrapper);

        List<UserDTO> userDTOS = new ArrayList<>();
        for (UserDO userDO : userDOList) {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(userDO, userDTO);
            userDTO.setPassword(null);
            if(userDO.getRoleIds() == null){
                userDTOS.add(userDTO);
                continue;
            }

            userDTO.setRoleIds(JSONObject.parseArray(userDO.getRoleIds(), Long.class));
            userDTOS.add(userDTO);
        }
        return new Page<UserDTO>(userDTOS, pageNo, limit, count);
    }

    @Override
    public List<UserDO> getUserList(String role, Long adminId,Long companyId) throws ServiceException {
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.like("name",role);
        wrapper.eq("company_id",companyId);
        List<RoleDO> list = roleMapper.selectList(wrapper);
        Long roleId = 0l;
        if(list.size() >0){
            roleId = list.get(0).getId();
        }
        wrapper = new EntityWrapper<>();
        wrapper.like("role_ids",roleId+"");
        wrapper.eq("status", "1");
        wrapper.isNotNull("user_name");
        List<UserDO> userDOList = userMapper.selectList(wrapper);

        return userDOList;
    }



    @Override
    public void test() throws Exception {
        String title="中秋快乐123";
        String content="国庆快乐123";
//        UserDO userDO = userMapper.selectById(21);
        geTuiUtils.pushByCid(title,content,21l);
//        geTuiUtils.pushToAll(title,content,"");
    }


}
