package com.ruoyi.xq.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.WxTransData;
import com.ruoyi.xq.dto.admin.account.WxTransDataAdminVo;
import com.ruoyi.xq.dto.app.account.StarWxTransReq;
import com.ruoyi.xq.dto.app.account.WxTransDataApplyReq;
import com.ruoyi.xq.dto.app.account.WxTransDataListAppVo;
import com.ruoyi.xq.dto.app.account.WxTransDataQuery;
import com.ruoyi.xq.enums.ErrorEnum;
import com.ruoyi.xq.enums.account.WxTransDataStatusEnum;
import com.ruoyi.xq.enums.common.TraceIdEnum;
import com.ruoyi.xq.mapper.WxTransDataMapper;
import com.ruoyi.xq.service.UserExtendService;
import com.ruoyi.xq.service.UserService;
import com.ruoyi.xq.service.WxTransDataService;
import com.ruoyi.xq.util.BirthdayUtil;
import com.ruoyi.xq.util.PageConvert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 微信交换数据Service业务层处理
 *
 * @author 77
 * @date 2024-03-25
 */
@Service
public class WxTransDataServiceImpl extends ServiceImpl<WxTransDataMapper,WxTransData> implements WxTransDataService {

    @Autowired
    private UserExtendService userExtendService;
    @Autowired
    private UserService userService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void start(StarWxTransReq starWxTransReq) {
        if(starWxTransReq.getSponsorUserId().equals(starWxTransReq.getReceiveUserId())){
            throw new ServiceException("自己不能和自己交换微信哦");
        }
        User receiveUser = userService.getById(starWxTransReq.getReceiveUserId());
        if(receiveUser == null){
            throw new ServiceException("接受用户不存在");
        }
        String traceId = TraceIdEnum.WX_TRANS.getCode();
        boolean success = userExtendService.consumeWxTrans(starWxTransReq.getSponsorUserId(),receiveUser, traceId);
        if(!success){
            throw new ServiceException(ErrorEnum.WX_TRANS_ERROR);
        }
        User sponsorUser = userService.getById(starWxTransReq.getSponsorUserId());
        WxTransData data = new WxTransData();
        data.setTraceId(traceId);
        data.setSponsorUserId(sponsorUser.getId());
        data.setSponsorUsercode(sponsorUser.getUsercode());
        data.setSponsorWx(sponsorUser.getWxCode());
        data.setReceiveUserId(receiveUser.getId());
        data.setReceiveUsercode(receiveUser.getUsercode());
        data.setReceiveWx(receiveUser.getWxCode());
        data.setStatus(WxTransDataStatusEnum.READY.getCode());
        this.save(data);
    }

    @Override
    public void apply(WxTransDataApplyReq req){
        WxTransData wxTransData = this.getById(req.getId());
        if(wxTransData == null){
            throw new ServiceException("数据不存在");
        }
        if(!wxTransData.getReceiveUserId().equals(req.getUserId())){
            throw new ServiceException("不是接受者无法接受微信邀请");
        }
        if(req.getApply() == null){
            throw new ServiceException("数据异常");
        }
        WxTransDataStatusEnum statusEnum;
        if(req.getApply().equals(1)){
            statusEnum = WxTransDataStatusEnum.SUCCESS;
        }else if(req.getApply().equals(2)){
            statusEnum = WxTransDataStatusEnum.FAIL;
        }else {
            throw new ServiceException("数据异常");
        }
        boolean update = this.update(Wrappers.lambdaUpdate(WxTransData.class)
                .eq(WxTransData::getId, wxTransData.getId())
                .eq(WxTransData::getStatus, WxTransDataStatusEnum.READY.getCode())
                .set(WxTransData::getStatus, statusEnum.getCode())
                .set(WxTransData::getOpTime, LocalDateTime.now()));
    }

    @Override
    public Page<WxTransDataListAppVo> pageApp(PageQuery pageQuery,  WxTransDataQuery wxTransDataQuery) {
        Page<WxTransData> page = baseMapper.pageApp(pageQuery.build(), wxTransDataQuery);
        List<WxTransData> records = page.getRecords();
        if(CollectionUtils.isEmpty(records)){
            return PageConvert.convertEmpty(page);
        }
        Long userId = wxTransDataQuery.getUserId();
        List<Long> userIdList = new ArrayList<>();
        for (WxTransData record : records) {
            userIdList.add(record.getSponsorUserId());
            userIdList.add(record.getReceiveUserId());
        }
        List<User> users = userService.listByIds(userIdList);
        Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        List<WxTransDataListAppVo> res = new ArrayList<>();
        for (WxTransData record : records) {
            WxTransDataListAppVo vo = new WxTransDataListAppVo();
            vo.setId(record.getId());
            vo.setCreateTime(record.getCreateTime());
            vo.setStatus(record.getStatus());
            if(record.getSponsorUserId().equals(userId)){
                vo.setUserId(record.getReceiveUserId());
                vo.setUsercode(record.getReceiveUsercode());
                User user = userMap.get(record.getReceiveUserId());
                if(user != null){
                    vo.setAvatar(user.getAvatar());
                    vo.setGender(user.getGender());
                    vo.setNickname(user.getNickname());
                    vo.setBirthday(user.getBirthday());
                    vo.setBirthdayStr(BirthdayUtil.getMinBirthday(user.getBirthday()));
                    vo.setAge(BirthdayUtil.getAge(user.getBirthday()));
                    vo.setResidenceCityName(user.getResidenceCityName());
                    vo.setEducation(user.getEducation());
                    vo.setProfession(user.getProfession());
                }
                if(WxTransDataStatusEnum.SUCCESS.getCode().equals(record.getStatus())){
                    vo.setWxCode(record.getSponsorWx());
                }
            } else {
                vo.setUserId(record.getSponsorUserId());
                vo.setUsercode(record.getSponsorUsercode());
                User user = userMap.get(record.getSponsorUserId());
                if(user != null){
                    vo.setAvatar(user.getAvatar());
                    vo.setGender(user.getGender());
                    vo.setNickname(user.getNickname());
                    vo.setBirthday(user.getBirthday());
                    vo.setBirthdayStr(BirthdayUtil.getMinBirthday(user.getBirthday()));
                    vo.setAge(BirthdayUtil.getAge(user.getBirthday()));
                    vo.setResidenceCityName(user.getResidenceCityName());
                    vo.setEducation(user.getEducation());
                    vo.setProfession(user.getProfession());
                }
                if(WxTransDataStatusEnum.SUCCESS.getCode().equals(record.getStatus())){
                    vo.setWxCode(record.getReceiveWx());
                }
            }
            res.add(vo);
        }
        return PageConvert.convert(page,res);
    }

    @Override
    public Page<WxTransDataAdminVo> pageAdmin(PageQuery pageQuery, WxTransDataAdminVo bo) {
        return baseMapper.pageAdmin(pageQuery.build(), bo);
    }

    @Override
    public boolean allowAdmin(Long id) {
        boolean update = this.update(Wrappers.lambdaUpdate(WxTransData.class)
                .eq(WxTransData::getId, id)
                .eq(WxTransData::getStatus, WxTransDataStatusEnum.READY.getCode())
                .set(WxTransData::getStatus, WxTransDataStatusEnum.SUCCESS.getCode())
                .set(WxTransData::getOpTime, LocalDateTime.now())
                .set(WxTransData::getIsAdmin, 1)
                .set(WxTransData::getAdminId, LoginHelper.getUserId())
                .set(WxTransData::getAdminName, LoginHelper.getUsername()));
        return true;
    }

    @Override
    public boolean notAllowAdmin(Long id) {
        boolean update = this.update(Wrappers.lambdaUpdate(WxTransData.class)
                .eq(WxTransData::getId, id)
                .eq(WxTransData::getStatus, WxTransDataStatusEnum.READY.getCode())
                .set(WxTransData::getStatus, WxTransDataStatusEnum.FAIL.getCode())
                .set(WxTransData::getOpTime, LocalDateTime.now())
                .set(WxTransData::getIsAdmin, 1)
                .set(WxTransData::getAdminId, LoginHelper.getUserId())
                .set(WxTransData::getAdminName, LoginHelper.getUsername()));
        return true;
    }
}
