package com.ruoyi.member.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.base.domain.BaseConfig;
import com.ruoyi.base.service.IBaseCityService;
import com.ruoyi.base.service.IBaseConfigService;
import com.ruoyi.busi.service.IBusiEvaluateService;
import com.ruoyi.busi.service.IBusiNoticeService;
import com.ruoyi.common.config.DlRightsConfig;
import com.ruoyi.common.config.WxAppConfig;
import com.ruoyi.common.core.domain.DlBaseEntity;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.constant.DictConstants;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.member.domain.MemberCard;
import com.ruoyi.member.domain.MemberUser;
import com.ruoyi.member.mapper.MemberUserMapper;
import com.ruoyi.member.service.*;
import com.ruoyi.member.vo.MemberUserVO;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.List;
import java.util.Optional;

/**
 * 会员Service业务层处理
 *
 * @author pqz
 * @date 2025-03-17
 */
@Service
public class MemberUserServiceImpl extends ServiceImpl<MemberUserMapper, MemberUser> implements IMemberUserService {
    @Autowired
    private MemberUserMapper memberUserMapper;
    @Resource
    private IBusiEvaluateService evaluateService;
    @Resource
    private IMemberCardService cardService;

    @Resource
    private IMemberBusiCardService busiCardService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private DlRightsConfig dlRightsConfig;
    @Resource
    private IMemberAddressService addressService;
    @Resource
    private IMemberPointsService pointsService;
    @Autowired
    private ISysUserService userService;
    @Resource
    private IMemberCouponService couponService;
    @Autowired
    @Lazy
    private IMemberCardService memberCardService;
    @Autowired
    private IBaseConfigService baseConfigService;

    /**
     * 分页列表查询
     *
     * @param pageReqVO {@link MemberUserVO}
     * @param page      分页参数
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.ruoyi.member.domain.MemberUser>
     * @author PQZ
     * @date 15:32 2025/3/17
     **/
    @Override
    public IPage<MemberUserVO> queryListPage(MemberUserVO pageReqVO, Page<MemberUserVO> page) {
        return memberUserMapper.queryListPage(pageReqVO, page);
    }

    /**
     * 根据用户表id获取通告主信息
     *
     * @param userId 用户表id
     * @return com.ruoyi.member.vo.MemberUserVO
     * @author PQZ
     * @date 11:42 2025/3/21
     **/
    @Override
    public MemberUserVO announcerDetail(Long userId) {
        //查询通告主基本信息
        MemberUserVO result = memberUserMapper.queryByUserId(userId, "01");
        //评价信息
        result.setEvaluates(evaluateService.listByToUserId(userId));
        //会员开通记录
        result.setCards(cardService.listByUserId(userId, "01"));
        return result;
    }

    /**
     * 获取博主详情
     *
     * @param userId 用户表id
     * @return com.ruoyi.member.vo.MemberUserVO
     * @author PQZ
     * @date 10:41 2025/3/22
     **/
    @Override
    public MemberUserVO bloggerDetail(Long userId) {
        //博主基本信息
        MemberUserVO result = memberUserMapper.queryByUserId(userId, "02");
        //名片信息
        result.setBusiCards(busiCardService.queryListByUserId(userId,"1"));
        //积分
        result.setPointsBalance(pointsService.getBloggerBalance(userId));
        //报名
        result.setReport(cardService.getCardRightsValue(userId,"02","report"));
        //地址信息
        result.setAddresses(addressService.listByUserId(userId));
        //会员开通记录
        result.setCards(cardService.listByUserId(userId, "02"));
        return result;
    }

    /**
     * 通过用户id查询用户详情信息
     *
     * @param userId   用户id
     * @param userType userType
     * @return com.ruoyi.member.vo.MemberUserVO
     * @author PQZ
     * @date 11:40 2025/4/9
     **/
    @Override
    public MemberUserVO queryByUserId(Long userId, String userType) {
        //博主，通告主基本信息
        MemberUserVO result = memberUserMapper.queryByUserId(userId, userType);
        //查是否开通的会员以及会员到期的时间
        MemberCard card = memberCardService.getUserCardEndDate(userId,userType);
        if (null != card) {
            result.setMemberEndDate(DateUtil.formatDate(card.getEndDate()));
            result.setCardName(card.getCardName());
        }
        if ("02".equals(userType)) {
            //积分
            result.setPointsBalance(pointsService.getBloggerBalance(userId));
            //报名
            Integer report = cardService.getCardRightsValue(userId, "02", "report");
            //赠送的报名次数
            MemberUserVO memberUserVO = memberUserMapper.queryByUserId(userId, "02");

            result.setReport(report+Integer.parseInt(memberUserVO.getSendReportNum().toString()));
        } else {
            //通告券
            result.setCoupon(couponService.getCoupon(userId));
            //剩余发布通告额度
            result.setAddNotice(cardService.getCardRightsValue(userId,"01","add_notice"));
        }
        return result;
    }


    /**
     * 微信授权登陆
     *
     * @param openid        TODO
     * @param decryptResult TODO
     * @return java.lang.String
     * @author vinjor-M
     * @date 15:53 2025/3/26
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String wxLogin(String openid, String decryptResult,String unionid) {
        //字符串转json
        JSONObject jsonObject = JSONObject.parseObject(decryptResult);
        //手机号
        String phone = jsonObject.getString("phoneNumber");
        //根据openid判断数据库中是否有该用户
        //根据openid查询用户信息
        SysUser wxUser = userMapper.selectWxUserByOpenIdOrPhone(openid,null,null,null);
        if(null==wxUser){
            //根据openId没查到，再根据手机号查
            wxUser = userMapper.selectWxUserByOpenIdOrPhone(null,phone,null,null);
            if(null==wxUser&& StringUtils.isNotEmpty(unionid)){
                //根据openId没查到，再根据unionid查
                wxUser = userMapper.selectWxUserByOpenIdOrPhone(null,null,null,unionid);
            }
        }
        //如果查不到，则新增，查到了，则更新
        SysUser user = new SysUser();
        if (wxUser == null) {
            // 新增
            // 设置姓名 ，默认使用昵称+随机数，防止重复姓名的发生 数据库中把username的长度修改的长一点
            user.setUserName(phone);
            user.setNickName("微信用户");
            user.setOpenId(openid);
            user.setPhonenumber(phone);
            user.setSex("2");
            user.setCreateTime(DateUtils.getNowDate());
            user.setUnionId(unionid);
            //新增 用户
            userMapper.insertUser(user);
            //插入用户扩展信息表数据
            this.save(new MemberUser(DictConstants.USER_TYPE_TGZ,user,dlRightsConfig.getAddNotice()));
            this.save(new MemberUser(DictConstants.USER_TYPE_BZ,user,null));
            //开通会员卡
            cardService.dealMemberCard(user.getUserId(),"01","67def5ba1e4c60754e68defb3fb027a5","04",null);
            cardService.dealMemberCard(user.getUserId(),"02","7530cf7b7a5d0100a7b41605d1642ef1","04",null);
        }else {
            //,查到了
            if(!"0".equals(wxUser.getStatus())){
                //非正常状态，无法登录
                throw new ServiceException("账号状态异常");
            }
            // 更新
            user = wxUser;
            if(!openid.equals(user.getOpenId())){
                user.setOpenId(openid);
                user.setUpdateTime(DateUtils.getNowDate());
                user.setUnionId(unionid);
                user.setPhonenumber(phone);
                userMapper.updateUser(user);
            }
        }
        //组装token信息
        LoginUser loginUser = new LoginUser();
        loginUser.setOpenId(openid);
        loginUser.setUser(user);
        loginUser.setUserId(user.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }

    /**
     * uniApp保存会员信息
     *
     * @param memberUser {@link MemberUserVO}
     * @author PQZ
     * @date 14:54 2025/4/9
     **/
    @Override
    public void uniSaveMember(MemberUserVO memberUser) {
        //更新用户信息
        SysUser sysUser = new SysUser();
        sysUser.setUserId(memberUser.getUserId());
        sysUser.setAvatar(memberUser.getAvatar());
        sysUser.setNickName(memberUser.getNickName());
        sysUser.setPhonenumber(memberUser.getPhonenumber());
        userService.updateUserProfile(sysUser);
        //更新会员表信息
        MemberUser member = new MemberUser();
        BeanUtils.copyProperties(memberUser,member);
        updateById(member);
    }

    @Override
    public String gzhLogin(String wxOpenId, cn.hutool.json.JSONObject userInfo) {
        //根据openid判断数据库中是否有该用户
        //根据openid查询用户信息
        SysUser wxUser = userMapper.selectWxUserByOpenIdOrPhone(null,null,wxOpenId,null);
        if(null==wxUser&& StringUtils.isNotEmpty((String) userInfo.get("unionid"))){
            //根据openId没查到，再根据unionid查
            wxUser = userMapper.selectWxUserByOpenIdOrPhone(null,null,null,(String) userInfo.get("unionid"));
        }
        //如果查不到，则新增，查到了，则更新
        SysUser user = new SysUser();
        if (wxUser == null) {
            // 新增
            // 设置姓名 ，默认使用昵称+随机数，防止重复姓名的发生 数据库中把username的长度修改的长一点
            user.setUserName((String) userInfo.get("openid"));
            user.setNickName((String) userInfo.get("nickname"));
            user.setWxOpenId((String) userInfo.get("openid"));
            user.setUnionId((String) userInfo.get("unionid"));
            user.setSex( userInfo.get("sex").equals("1")?"0":"1");
            user.setCreateTime(DateUtils.getNowDate());
            //新增 用户
            userMapper.insertUser(user);
            //插入用户扩展信息表数据
            this.save(new MemberUser(DictConstants.USER_TYPE_TGZ,user,dlRightsConfig.getAddNotice()));
            this.save(new MemberUser(DictConstants.USER_TYPE_BZ,user,null));
            //开通会员卡
            cardService.dealMemberCard(user.getUserId(),"01","67def5ba1e4c60754e68defb3fb027a5","04",null);
            cardService.dealMemberCard(user.getUserId(),"02","7530cf7b7a5d0100a7b41605d1642ef1","04",null);
        }else {
            //,查到了
            if(!"0".equals(wxUser.getStatus())){
                //非正常状态，无法登录
                throw new ServiceException("账号状态异常");
            }
            // 更新
            user = wxUser;
            if(!userInfo.get("openid").equals(user.getOpenId())){
                user.setWxOpenId((String) userInfo.get("openid"));
                user.setUnionId((String) userInfo.get("unionid"));
                user.setUpdateTime(DateUtils.getNowDate());
                userMapper.updateUser(user);
            }
        }
        //组装token信息
        LoginUser loginUser = new LoginUser();
        loginUser.setWxOpenId((String) userInfo.get("openid"));
        loginUser.setUser(user);
        loginUser.setUserId(user.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }
    //新人好礼
    @Override
    public void sendNewGift() throws Exception {
        Object getGift = this.isGetGift();
        if ("1".equals(getGift)){
            throw new Exception("已领取过");
        }
        //赠送博主报名次数
        List<BaseConfig> sendNewGift = baseConfigService.queryConfigByCode("send_new_gift");
        if(CollectionUtil.isNotEmpty(sendNewGift)){
            JSONArray array = JSONArray.parseArray(sendNewGift.get(0).getJsonStr());
            Long sendReportNum = array.getJSONObject(0).getLong("sendReportNum");
            Long userId = SecurityUtils.getUserId();
            //博主，通告主基本信息
            MemberUserVO result = memberUserMapper.queryByUserId(userId, "02");
            result.setSendReportNum(null==result.getSendReportNum()?sendReportNum:result.getSendReportNum()+sendReportNum);
            result.setIsGetGift("1");
            memberUserMapper.updateById(result);
        }
    }
    /**
     * 判断是否领取过新人好礼
     */
    @Override
    public Object isGetGift() {
        Long userId = SecurityUtils.getUserId();
        MemberUserVO result = memberUserMapper.queryByUserId(userId, "02");
        return Optional.ofNullable(result.getIsGetGift()).orElse("0");
    }
}
