package com.qiankun.controller.rainbowplan;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qiankun.annotation.Auth;
import com.qiankun.config.WxMaConfiguration;
import com.qiankun.config.WxMaProperties;
import com.qiankun.dao.RainbowPlanUserDao;
import com.qiankun.dao.WishDao;
import com.qiankun.dao.WishReplyDao;
import com.qiankun.entity.RainbowPlanUser;
import com.qiankun.entity.Wish;
import com.qiankun.entity.WishReply;
import com.qiankun.utils.JwtTokenUtil;
import com.qiankun.vo.*;
import com.sun.org.apache.regexp.internal.REUtil;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.util.UserDataDocumentFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

@RestController
@RequestMapping("/wx/rainbowplan")
public class RainbowPlanController {
    private final Logger logger = LoggerFactory.getLogger(RainbowPlanController.class);
    @Autowired
    private JwtTokenUtil tokenUtil;
    @Autowired
    private RainbowPlanUserDao userDao;
    @Autowired
    private WishDao wishDao;
    @Autowired
    private WishReplyDao wishReplyDao;
    @Autowired
    private WxMaProperties propertis;
    private ResourceBundle rb = ResourceBundle.getBundle("system");
    private String uploadAvatarPath = File.separator + "rainbowplan" + File.separator + "uploadAvatar";
    private String uploadWishImagePath = File.separator + "rainbowplan" + File.separator + "wishUploadImage";

    private String getAppid(){
        return propertis.getConfigs().get(0).getAppid();
    }


    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public Map<String,Object> login(@RequestParam String code){
        if (StringUtils.isBlank(code)) {
            return null;
        }

        final WxMaService wxService = WxMaConfiguration.getMaService(getAppid());

        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            this.logger.info(session.getSessionKey());
            this.logger.info(session.getOpenid());
            Map<String,Object> result = Maps.newConcurrentMap();

            RainbowPlanUser userInfo = userDao.findByOpenid(session.getOpenid());
            if (userInfo != null){
                String sKey = tokenUtil.generateToken(userInfo.getOpenid());
                result.put("sKey",sKey);
                result.put("userInfo",userInfo);
            }else {
                result.put("sKey","");
                result.put("userInfo","");
                result.put("openid",session.getOpenid());
            }

            return result;
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return null;
        }
    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/register",method = RequestMethod.POST)
    public Map<String,Object> register(@RequestBody RegisterInfo info) throws Exception {
        Map<String,Object> result = Maps.newConcurrentMap();
        if (Strings.isNullOrEmpty(info.getOpenid())){
            result.put("status","error");
            result.put("errorMsg","请求参数错误");
            return result;
        }
        RainbowPlanUser user = userDao.findByPhone(info.getPhone());
        if (info.getType() == RainbowPlanUser.TYPE_BABY && user != null){
            //红会人员录入过信息
            user.setName(info.getName());
            user.setGender(info.getGender());
            user.setOpenid(info.getOpenid());
            result.put("isExist",true);
            userDao.update(user);
        }else if (info.getType() == RainbowPlanUser.TYPE_BABY && user == null){
            //新注册用户
            user = new RainbowPlanUser();
            user.setPhone(info.getPhone());
            user.setName(info.getName());
            user.setGender(info.getGender());
            user.setOpenid(info.getOpenid());
            user.setType(info.getType());
            if (Strings.isNullOrEmpty(info.getInviter())){
                //无邀请码用户
                user.setStatus(RainbowPlanUser.STATUS_UNAUDIT);
            }else if (inviterExist(info.getInviter())){
                user.setStatus(RainbowPlanUser.STATUS_AUDIT);
                user.setInviterId(info.getInviter());
            }else {
                result.put("status","error");
                result.put("errorMsg","注册失败，邀请者不存在");
                return result;
            }
            userDao.save(user);
        }else if (info.getType() == RainbowPlanUser.TYPE_LOVE && user == null){
            //爱心人士
            user = new RainbowPlanUser();
            user.setPhone(info.getPhone());
            user.setName(info.getName());
            user.setType(info.getType());
            user.setOpenid(info.getOpenid());
            userDao.save(user);
        }else if (info.getType() == RainbowPlanUser.TYPE_LOVE && user != null){
            result.put("status","error");
            result.put("errorMsg","该手机号已存在");
            return result;
        }


        result.put("status","OK");
        result.put("userInfo",user);
        result.put("sKey",tokenUtil.generateToken(info.getOpenid()));
        return result;
    }

    private boolean inviterExist(String inviterId) {
        //TODO 判断邀请人是否存在
        return true;
    }

    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/userInfo",method = RequestMethod.GET)
    public RainbowPlanUser getUserInfo(@RequestHeader String sKey) throws Exception {
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);
        RainbowPlanUser user = userDao.findByOpenid(openid);
        if (user == null) {
            throw new Exception("请求的用户不存在");
        }

        return user;
    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/userInfo",method = RequestMethod.POST)
    public @ResponseBody RainbowPlanUser updateUserInfo(@RequestBody UserInfo info,@RequestHeader String sKey) throws Exception {
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);
        RainbowPlanUser user = userDao.findByOpenid(openid);
        if (user != null){
            user.setPhone(info.getPhone());
            user.setName(info.getName());
            user.setNickName(info.getNickName());
            user.setGender(info.getGender());
            user.setBirthday(info.getBirthday());
            user.setBedNum(info.getBedNum());
            user.setReceiveName(info.getReceiveName());
            user.setConnectTel(info.getConnectTel());
            user.setReceiveAddress(info.getReceiveAddress());
            userDao.update(user);
        }else {
            throw new Exception("保存失败，请求用户不存在");
        }

        return user;
    }

    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/userInfoWithAvatar",method = RequestMethod.POST)
    public @ResponseBody RainbowPlanUser updateUserInfoWithAvatar(UserInfo info, @RequestHeader String sKey) throws Exception {
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);
        RainbowPlanUser user = userDao.findByOpenid(openid);
        if (user != null){
            if (!info.getFile().isEmpty()){
                String originalFileName = info.getFile().getOriginalFilename();
                String rootPath = rb.getString("file_path");
                File destFile = new File(rootPath + uploadAvatarPath,originalFileName);
                FileUtils.writeByteArrayToFile(destFile,info.getFile().getBytes());
                user.setPhone(info.getPhone());
                user.setName(info.getName());
                user.setNickName(info.getNickName());
                user.setGender(info.getGender());
                user.setBirthday(info.getBirthday());
                user.setBedNum(info.getBedNum());
                user.setReceiveName(info.getReceiveName());
                user.setConnectTel(info.getConnectTel());
                user.setReceiveAddress(info.getReceiveAddress());
                user.setAvatar(uploadAvatarPath + File.separator + originalFileName);
                userDao.update(user);
            }else {
                throw new Exception("保存失败，请上传图片");
            }
        }else {
            throw new Exception("保存失败，请求用户不存在");
        }
        return user;
    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/publishWish",method = RequestMethod.POST)
    public String publishWish(PublishWish publishWish,@RequestHeader String sKey) throws Exception {
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);
        RainbowPlanUser user = userDao.findByOpenid(openid);
        if (user != null){
            if (!publishWish.getFile().isEmpty()){

                String originalFileName = publishWish.getFile().getOriginalFilename();
                String rootPath = rb.getString("file_path");
                File destFile = new File(rootPath + uploadWishImagePath,originalFileName);
                FileUtils.writeByteArrayToFile(destFile,publishWish.getFile().getBytes());
                Wish wish = new Wish();
                wish.setTitle(publishWish.getTitle());
                wish.setContent(publishWish.getWish());
                wish.setUploadImage(uploadWishImagePath + File.separator + originalFileName);
                wish.setStatus(Wish.STATUS_PUBLISH);
                wish.setRainbowPlanUserId(user.getId());
                wishDao.save(wish);
            }else {
                throw new Exception("保存失败，请上传图片");
            }
        }else {
            throw new Exception("保存失败，请求用户不存在");
        }

        return "OK";
    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/wish/list",method = RequestMethod.GET)
    public List<Wish> wishList(@RequestHeader String sKey) throws Exception {
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);
        RainbowPlanUser user = userDao.findByOpenid(openid);
        List<Wish> resultList = Lists.newArrayList();
        if (user != null){
            resultList = wishDao.findByRainbowPlanUserId(user.getId());
        }
        return resultList;
    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/wish",method = RequestMethod.GET)
    public WishDetailVo getWish(@RequestParam String id,@RequestHeader String sKey){
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);

        Wish wish = wishDao.findById(id);
        List<WishReply> replys = wishReplyDao.findByWishId(wish.getId());
        WishDetailVo vo = new WishDetailVo(wish,replys);
        return vo;

    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/reply",method = RequestMethod.POST)
    public String reply(@RequestBody WishReply reply,@RequestHeader String sKey){
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);

        //TODO 验证
        wishReplyDao.save(reply);
        return "OK";
    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value  ="/completeWish",method = RequestMethod.GET)
    public String completeWish(String wishId,@RequestHeader String sKey){
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);
        Wish wish = wishDao.findById(wishId);
        if (wish != null){
            wish.setStatus(Wish.STATUS_COMPLETE);
        }
        wishDao.update(wish);
        return "OK";
    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/isActivity",method = RequestMethod.GET)
    public boolean isActivity(@RequestHeader String sKey) throws Exception {
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);
        RainbowPlanUser user = userDao.findByOpenid(openid);
        if (user != null){
            //TODO 获取活动开放标识
            return true;
        }else {
            throw new Exception("获取数据失败，请求用户不存在");
        }
    }

    @Auth(verifyURL = false,verifyLogin = false)
    @RequestMapping(value = "/qrcode",method = RequestMethod.GET)
    public ResponseEntity<byte[]> getQrcode(@RequestHeader String sKey) throws WxErrorException {
        if (Strings.isNullOrEmpty(sKey)){
            throw new IllegalArgumentException("请求参数错误");
        }
        String openid = tokenUtil.getUsernameFromToken(sKey);
        WxMaService wxMaService = WxMaConfiguration.getMaService(getAppid());

        WxMaQrcodeService qrcodeService = wxMaService.getQrcodeService();
        byte[] codeBytes = qrcodeService.createWxaCodeUnlimitBytes("inviter="+openid,"pages/register",360,true,null,false);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<byte[]>(codeBytes,headers,HttpStatus.OK);
    }

    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/loadResource",method = RequestMethod.GET)
    public ResponseEntity<byte[]> loadResource(@RequestParam String imageName) throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        File file = new File(rb.getString("file_path"),imageName);
        return new ResponseEntity<>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
    }
    @Auth(verifyLogin = false,verifyURL = false)
    @RequestMapping(value = "/importWish",method = RequestMethod.POST)
    public @ResponseBody Map<String,Object> importWish(ImportWishVo importWishVo) throws Exception {
        Map<String,Object> result = Maps.newConcurrentMap();
        RainbowPlanUser user = new RainbowPlanUser();
        user.setPhone(importWishVo.getPhone());
        user.setName(importWishVo.getName());
        user.setNickName(importWishVo.getNickName());
        user.setReceiveAddress(importWishVo.getReceiveAddress());
        user.setConnectTel(importWishVo.getConnectTel());
        user.setReceiveName(importWishVo.getReceiveName());
        user.setBedNum(importWishVo.getBedNum());
        user.setBirthday(importWishVo.getBirthday());
        user.setGender(importWishVo.getGender());
        user.setCreateTime(new Date());
        user.setType(RainbowPlanUser.TYPE_BABY);
        user.setStatus(RainbowPlanUser.STATUS_AUDIT);

        userDao.save(user);

        if (!importWishVo.getFile().isEmpty()){

            String originalFileName = importWishVo.getFile().getOriginalFilename();
            String rootPath = rb.getString("file_path");
            File destFile = new File(rootPath + uploadWishImagePath,originalFileName);
            FileUtils.writeByteArrayToFile(destFile,importWishVo.getFile().getBytes());
            Wish wish = new Wish();
            wish.setContent(importWishVo.getWish());
            wish.setUploadImage(uploadWishImagePath + File.separator + originalFileName);
            wish.setStatus(Wish.STATUS_PUBLISH);
            wish.setRainbowPlanUserId(user.getId());
            wishDao.save(wish);
        }else {
            throw new Exception("保存失败，请上传图片");
        }
        result.put("status","OK");
        return result;
    }
}
