package com.iformall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.IdWorker;
import com.iformall.domain.dto.WxCUserBasicInfoDto;
import com.iformall.domain.po.WxAuthorizerInfo;
import com.iformall.domain.po.WxCUser;
import com.iformall.enums.EnumAppType;
import com.iformall.mapper.WxCUserMapper;
import com.iformall.service.WxCUserService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class WxCUserServiceImpl implements WxCUserService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    WxCUserMapper wxCUserMapper;

    @Override
    public PageInfo<WxCUser> listAsPage(WxCUser record, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCUserMapper.findList(record));
    }

    @Override
    public WxCUser getById(Long id) {
        return wxCUserMapper.selectByPrimaryKey(id);
    }

    @Override
    public WxCUser getByOpenId(WxCUser record) {
        return wxCUserMapper.findByOpenId(record);
    }

    @Override
    public WxCUser getByObject(WxCUser record) {
        try {
            return wxCUserMapper.selectOne(record);
        } catch (Exception e) {
            logger.error("NOT found: " + e.getMessage());
        }
        return null;
    }

    @Override
    public int saveOrUpdate(WxCUser user) {
        int ret = 0;
        Date curr = new Date();
        if (user.getId() == null) {
            // 检查用户是否已有同一微信开放平台账号
            if(StringUtils.isNotBlank(user.getUnionId()) && StringUtils.isNotBlank(user.getOpenAppId())) {
                WxCUser oldUser = wxCUserMapper.findByUnionId(user);
                if(oldUser != null) {
                    // 已有，更新
                    user.setId(oldUser.getId());
                    // TODO 是否其他信息需要更新
                    ret = wxCUserMapper.updateByPrimaryKeySelective(user);
                    return ret;
                }
            }
            final IdWorker idWorker = IdWorker.get();
            user.setId(idWorker.nextId());
            user.setLoginCount(1);
            user.setCreateDate(curr);
            user.setUpdateDate(curr);
            ret = wxCUserMapper.insertSelective(user);
        } else {
            user.setUpdateDate(curr);
            ret = wxCUserMapper.updateByPrimaryKeySelective(user);
        }

        return ret;
    }

    @Override
    public int saveOrUpdateMpUser(WxMpUser mpUser, WxAuthorizerInfo authorizerInfo) {
        // 1. check user exist
        WxCUser userQ = new WxCUser();
        userQ.setTenantId(authorizerInfo.getTenantId());
        boolean bHaveUnionId = false;
        if(StringUtils.isNotBlank(mpUser.getUnionId())) {
            userQ.setUnionId(mpUser.getUnionId());
            bHaveUnionId = true;
        } else {
            userQ.setOpenAppId(authorizerInfo.getOpenAppid());
            if(authorizerInfo.getType().equals(EnumAppType.MP_S.getCode())) {
                userQ.setMpOpenId(mpUser.getOpenId());
                userQ.setMpAppId(authorizerInfo.getAuthorizerAppid());
            } else if(authorizerInfo.getType().equals(EnumAppType.MP_P.getCode())) {
                userQ.setSubsOpenId(mpUser.getOpenId());
                userQ.setSubsAppId(authorizerInfo.getAuthorizerAppid());
            }
        }
        WxCUser oldUser = getByObject(userQ);
        boolean bHave = false;
        if(oldUser != null) {
            userQ.setId(oldUser.getId());
            bHave = true;
        }
        if(!bHave && !mpUser.getSubscribe()) {
            // 未找到，且是关注消息, 直接返回
            return 0;
        }
        if(bHaveUnionId) {
            userQ.setOpenAppId(authorizerInfo.getOpenAppid());
            if (authorizerInfo.getType().equals(EnumAppType.MP_S.getCode())) {
                userQ.setMpOpenId(mpUser.getOpenId());
                userQ.setMpAppId(authorizerInfo.getAuthorizerAppid());
            } else if (authorizerInfo.getType().equals(EnumAppType.MP_P.getCode())) {
                userQ.setSubsOpenId(mpUser.getOpenId());
                userQ.setSubsAppId(authorizerInfo.getAuthorizerAppid());
            }
        }
        if(((oldUser != null && StringUtils.isBlank(oldUser.getNickName())) || (oldUser == null))
                && StringUtils.isNotBlank(mpUser.getNickname())) {
            userQ.setNickName(mpUser.getNickname());
            userQ.setGender(mpUser.getSex());
            userQ.setAvatarUrl(mpUser.getHeadImgUrl());
            userQ.setCity(mpUser.getCity());
            userQ.setProvince(mpUser.getProvince());
            userQ.setLanguage(mpUser.getLanguage());
        }
        if(authorizerInfo.getType().equals(EnumAppType.MP_S.getCode())) {
            userQ.setMpSubscribe(mpUser.getSubscribe()?1:0);
            userQ.setMpSubscribeScene(mpUser.getSubscribeScene());
            userQ.setMpSubscribeTime(new Date(mpUser.getSubscribeTime()));
        } else if(authorizerInfo.getType().equals(EnumAppType.MP_P.getCode())) {
            userQ.setSubsSubscribe(mpUser.getSubscribe()?1:0);
            userQ.setSubsSubscribeScene(mpUser.getSubscribeScene());
            userQ.setMpSubscribeTime(new Date(mpUser.getSubscribeTime()));
        }
        return saveOrUpdate(userQ);
    }

    @Override
    public void deleteById(Long id) {
        wxCUserMapper.deleteByPrimaryKey(id);
    }

    @Override
    public long findCount(WxCUserBasicInfoDto dto) {
        return wxCUserMapper.findCount(dto);
    }

    @Override
    public PageInfo<WxCUser> listByChannel(WxCUser user, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxCUserMapper.listByChannel(user));
    }

    @Override
    public long countByChannel(WxCUser user) {
        return wxCUserMapper.countByChannel(user);
    }
}
