package com.mvc.service.wx;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.config.WxProperties;
import com.mvc.constant.WxConstant;
import com.mvc.dao.WxUserProfileMapper;
import com.mvc.entity.WxUserProfile;
import com.mvc.entity.WxUserProfileExample;
import com.mvc.model.*;
import com.mvc.model.wx.WxCode2SessionResultModel;
import com.mvc.model.wx.WxUserDevicesModel;
import com.mvc.model.wx.WxUserProfileModel;
import com.mvc.service.copy.TAireadService;
import com.mvc.utils.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class WxUserProfileService {

    private static Logger log = LoggerFactory.getLogger(WxUserProfileService.class);

    @Resource
    private WxUserProfileMapper wxUserProfileMapper;

    @Resource
    private WxProperties wxProperties;

    @Resource
    private TAireadService aireadService;

    @Resource
    private WxUserDevicesService wxUserDevicesService;

    /**
     * 分页查询全部记录
     *
     * @param queryModel
     * @return
     */
    public ResPageModel findAllWxUserProfile(WxUserProfileModel queryModel) {
        WxUserProfileExample example = new WxUserProfileExample();
        WxUserProfileExample.Criteria criteria = example.createCriteria();
        example.setOrderByClause("OPERATION_TIME desc");
        Page<Object> pageObject = PageHelper.startPage(1, 10);
        List<WxUserProfile> wxUserProfiles = wxUserProfileMapper.selectByExample(example);
        List<WxUserProfileModel> resList = new ArrayList<>();
        for (WxUserProfile wxUserProfile : wxUserProfiles) {
            WxUserProfileModel model = new WxUserProfileModel();
            BeanUtils.copyProperties(wxUserProfile, model);
            resList.add(model);
        }
        ResPageModel resPageModel = new ResPageModel(resList, pageObject);
        return resPageModel;
    }

    /**
     * 保存新增对象
     *
     * @param model
     * @return
     */
    public WxUserProfileModel saveWxUserProfile(WxUserProfileModel model) {
        model.setRegisterTime(new Date());
        model.setUseFlag(1);

        WxUserProfile wxUserProfile = new WxUserProfile();
        BeanUtils.copyProperties(model, wxUserProfile);
        wxUserProfileMapper.insert(wxUserProfile);
        model.setId(wxUserProfile.getId());

        return model;
    }

    public WxUserProfileModel updateWxUserProfile(WxUserProfileModel model) {
        WxUserProfile wxUserProfile = wxUserProfileMapper.selectByPrimaryKey(model.getId());
        if (wxUserProfile != null) {
            BeanUtils.copyProperties(model,wxUserProfile);
            wxUserProfileMapper.updateByPrimaryKey(wxUserProfile);
        }

        return model;
    }

    /**
     * 微信用户登陆
     *
     * @param jsCode
     * @param avatarUrl
     * @param nickName
     * @return
     */
    public WxUserProfileModel login(String jsCode, String avatarUrl, String nickName) {
        WxUserProfileModel model = null;
        String url = getCode2SessionUrl(jsCode);
        String json = HttpUtil.getForEntity(url);
        if (StringUtils.isNotEmpty(json)) {
            log.info("微信用户登陆:" + json);
            WxCode2SessionResultModel resultModel = JSON.parseObject(json, WxCode2SessionResultModel.class);
            model = findWxUserProfileModelByOpenId(resultModel.getOpenid());
            if (model == null) {
                //用户首次使用,自动注册
                model = new WxUserProfileModel();
                model.setOpenId(resultModel.getOpenid());
                model.setUnionId(resultModel.getUnionid());
                model.setAvatarUrl(avatarUrl);
                model.setNickName(nickName);
                model = saveWxUserProfile(model);
            } else {
                //用户已存在,但头像或昵称发生变化了
                if (!model.getAvatarUrl().equals(avatarUrl) || !model.getNickName().equals(nickName)) {
                    model.setAvatarUrl(avatarUrl);
                    model.setNickName(nickName);
                    updateWxUserProfile(model);
                }
            }
            return model;
        }
        return null;
    }

    /**
     * 根据openId获取对象
     *
     * @param openId
     * @return
     */
    private WxUserProfileModel findWxUserProfileModelByOpenId(String openId) {
        if (StringUtils.isEmpty(openId)) {
            return null;
        }
        WxUserProfileExample example = new WxUserProfileExample();
        WxUserProfileExample.Criteria criteria = example.createCriteria();
        criteria.andOpenIdEqualTo(openId);
        List<WxUserProfile> userProfiles = wxUserProfileMapper.selectByExample(example);
        if (userProfiles != null && userProfiles.size() > 0) {
            WxUserProfileModel model = new WxUserProfileModel();
            BeanUtils.copyProperties(userProfiles.get(0), model);
            return model;
        }
        return null;
    }

    /**
     * 获取微信登陆API URL
     *
     * @param jsCode
     * @return
     */
    private String getCode2SessionUrl(String jsCode) {
        StringBuilder sb = new StringBuilder();
        sb.append(WxConstant.API_CODE2SESSION);
        sb.append("?");
        sb.append("appid=");
        //小程序 appId(在开发者工具和后台均可查询)
        sb.append(wxProperties.getAppId());
        sb.append("&secret=");
        //小程序 appSecret(在小程序管理后台获取,只可查看一次)
        sb.append(wxProperties.getAppSecret());
        sb.append("&js_code=");
        sb.append(jsCode);//登录时获取的 code，可通过wx.login获取
        sb.append("&grant_type=authorization_code");
        return sb.toString();
    }

    /**
     * 根据userProfileId获取对应的最新数据
     *
     * @param userProfileId
     * @return
     */
    public List<TAireadModel> findWxUserDevicesAireads(Integer userProfileId) {
        List<WxUserDevicesModel> devicesModels = wxUserDevicesService.findWxUserDevicesModelsByUserProfileId(userProfileId);

        String[] devices = new String[devicesModels.size()];
        for (int i = 0; i < devicesModels.size(); i++) {
            devices[i] = devicesModels.get(i).getDeviceCode();
        }
        return aireadService.findLatestDataByDeviceSns_Wx(devices);
    }
}
