package com.bofeng.service;

import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.bofeng.Consts;
import com.bofeng.dao.UserMapper;
import com.bofeng.dao.UserOpenMapper;
import com.bofeng.dao.UserPlaceMapper;
import com.bofeng.entity.ParseCurrentOpenId;
import com.bofeng.entity.User;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.yvan.PageDb;
import com.yvan.platform.YvanUtil;
import com.yvan.springmvc.HttpParameterParser;
import com.yvan.springmvc.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;
import java.util.Map;

@Service
@Transactional(readOnly = true)
@Slf4j
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserOpenMapper userOpenMapper;

    @Autowired
    UserPlaceMapper userPlaceMapper;

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private UserOpenService userOpenService;

    public User login(String loginName) {
        User user = userMapper.selectByLoginName(loginName);
        if (user == null) {
            throw new UnknownAccountException();
        }
        if (Consts.ACT_DELETE.equals(user.getBeActive())) {
            throw new UnknownAccountException();
        }
        if (Consts.ACT_DISABLE.equals(user.getBeActive())) {
            throw new DisabledAccountException();
        }
        return user;
    }

    public User getUserById(Long userId) {
        return userMapper.selectById(userId);
    }

    @Transactional
    public int updateLoginCount(Long userId) {
        return userMapper.updateLoginCount(userId);
    }

    public List<User> selectAll(PageDb pageDb) {
        return userMapper.selectAll(pageDb);
    }

    @Transactional
    public String updateById(User user) {

        if (!Strings.isNullOrEmpty(user.getLoginName())) {
            int checkLoginNameCount = userMapper.checkLoginName(user);
            if (checkLoginNameCount > 0) {
                return "登录名不能重复!";
            }
        }

        userMapper.updateById(user);
        user.setVersion(YvanUtil.createUUID());
        return "";
    }

    @Transactional
    public String insert(User user) {
        user.setUserId(IdWorker.getId());
        user.setVersion(YvanUtil.createUUID());
        user.setBeActive(Consts.ACT_ENABLE);

        if (!Strings.isNullOrEmpty(user.getLoginName())) {
            int checkLoginNameCount = userMapper.checkLoginName(user);
            if (checkLoginNameCount > 0) {
                return "登录名不能重复!";
            }
        }

        userMapper.insert(user);
        return "";
    }

    @Transactional
    public int updateInfo(Map p) {
        return userMapper.updateInfo(p);
    }

    @Transactional
    public int updatePassword(Long userId, String password, String newPassword) {
        return userMapper.updatePassword(userId,password, newPassword);
    }

    @Transactional
    public int deleteOpenId(Long userId) {
        int rowEffect = 0;
        rowEffect += userPlaceMapper.deleteByUserId(userId);
        rowEffect += userMapper.deleteById(userId);
        rowEffect += userOpenMapper.deleteByUserId(userId);
        return rowEffect;
    }

    @Transactional
    public int unbind(Long userId, Long placeId) {
        //先删除关系
        int a = userPlaceMapper.deleteByUserIdAndPlaceId(userId, placeId);
        return a; //userMapper.deleteById(userId) + userOpenMapper.deleteByUserId(userId,placeId);
    }

    public ParseCurrentOpenId currentWxUser() {
        val r = new ParseCurrentOpenId();
        val parser = HttpParameterParser.newInstance(HttpUtils.currentRequest());
        String openId = parser.getString("openId");
        String code = parser.getString("code");

        Map<String, Object> model = Maps.newLinkedHashMap();
        model.put("title", "授权错误");

        if (!Strings.isNullOrEmpty(code)) {
            try {

                WxMpOAuth2AccessToken accessToken = wxMpService.oauth2getAccessToken(code);
                WxMpUser wxMpUser = wxMpService.oauth2getUserInfo(accessToken, null);
                r.setWxMpUser(wxMpUser);
                openId = wxMpUser.getOpenId();

            } catch (WxErrorException e) {
                model.put("message", "获取code失败 " + code);
                model.put("isError", true);
                r.setErrorResult(new ModelAndView("/prompt/prompt.ftl", model));
                r.setError(true);

                log.error("获取code失败 " + code, e);
                return r;
            }
        }

        if (Strings.isNullOrEmpty(openId)) {
            model.put("message", "OpenId 为空 " + code);
            model.put("isError", true);
            r.setErrorResult(new ModelAndView("/prompt/prompt.ftl", model));
            r.setError(true);
            log.error("OpenId 为空 " + code);
            return r;
        }

        val userOpen = userOpenService.getUserByOpenId(openId);
        if (userOpen == null) {
            model.put("message", "userOpen 不存在 " + openId);
            model.put("isError", true);
            r.setErrorResult(new ModelAndView("/prompt/prompt.ftl", model));
            r.setError(true);
            log.error("userOpen 不存在 " + openId);
            return r;
        }
        if (!Consts.ACT_ENABLE.equals(userOpen.getBeActive())) {
            model.put("message", "userOpen 被禁用 " + userOpen.getUserId());
            model.put("isError", true);
            r.setErrorResult(new ModelAndView("/prompt/prompt.ftl", model));
            r.setError(true);
            log.error("userOpen 被禁用 " + userOpen.getUserId());
            return r;
        }

//        val user = getUserById(userOpen.getUserId());
//        if (user == null) {
//            model.put("message", "user 不存在 " + userOpen.getUserId());
//            model.put("isError", true);
//            r.setErrorResult(new ModelAndView("/prompt/prompt.ftl", model));
//            r.setError(true);
//            log.error("user 不存在 " + userOpen.getUserId());
//            return r;
//        }
//        if (!Consts.ACT_ENABLE.equals(user.getBeActive())) {
//            model.put("message", "user 被禁用 " + userOpen.getUserId());
//            model.put("isError", true);
//            r.setErrorResult(new ModelAndView("/prompt/prompt.ftl", model));
//            r.setError(true);
//            log.error("user 被禁用 " + userOpen.getUserId());
//            return r;
//        }

        r.setUserOpen(userOpen);
//        r.setUser(user);
        r.setError(false);
        return r;
    }
}
