package com.ruoyi.xq.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
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.common.utils.BeanConvertUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.xq.domain.*;
import com.ruoyi.xq.dto.admin.activity.ActivityShopAdminUpdateReq;
import com.ruoyi.xq.dto.app.activity.ActivityShopAppInfo;
import com.ruoyi.xq.dto.app.activity.ActivityShopAppList;
import com.ruoyi.xq.dto.app.activity.FreeJoinReq;
import com.ruoyi.xq.dto.app.activity.JoinResp;
import com.ruoyi.xq.enums.activity.ActivityShopStatusEnum;
import com.ruoyi.xq.enums.common.AuditEnum;
import com.ruoyi.xq.enums.userinfo.UserGenderEnum;
import com.ruoyi.xq.enums.vip.VipTypeEnum;
import com.ruoyi.xq.kit.CodeKit;
import com.ruoyi.xq.mapper.ActivityShopMapper;
import com.ruoyi.xq.service.*;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 相亲会Service业务层处理
 *
 * @author 77
 * @date 2024-05-09
 */
@Service
public class ActivityShopServiceImpl extends ServiceImpl<ActivityShopMapper,ActivityShop> implements ActivityShopService {

    @Autowired
    private UserService userService;
    @Autowired
    private UserAuthService userAuthService;
    @Autowired
    private ActivityUserService activityUserService;

    @Override
    public IPage<ActivityShopAppList> pageApp(PageQuery pageQuery) {
        IPage<ActivityShopAppList> page = baseMapper.pageApp(pageQuery.build());
        List<ActivityShopAppList> records = page.getRecords();
        for (ActivityShopAppList record : records) {
            record.setOpenStatus(ActivityShopStatusEnum.getEnumByTime(record.getStartTime(), record.getEndTime()).getCode());
        }
        return page;
    }

    @Override
    public ActivityShop getByCode(String activityCode){
        return this.getOne(Wrappers.lambdaQuery(ActivityShop.class).eq(ActivityShop::getActivityCode, activityCode).last("limit 1"));
    }

    @Override
    public void resetActivityShopUser(Long activityId,Integer gender){
        ActivityShop activityShop = this.getById(activityId);
        if(activityShop == null){
            return;
        }
        if(gender != null){
            Long count = activityUserService.countByActivityIdAndGender(activityId, gender);
            if(gender.equals(UserGenderEnum.MAN.getCode())){
                this.update(Wrappers.lambdaUpdate(ActivityShop.class).eq(ActivityShop::getId, activityId)
                        .set(ActivityShop::getJoinManNum, count));
            }else if(gender.equals(UserGenderEnum.WOMEN.getCode())){
                this.update(Wrappers.lambdaUpdate(ActivityShop.class).eq(ActivityShop::getId, activityId)
                        .set(ActivityShop::getJoinWomenNum, count));
            }
        } else {
            Long womenCount = activityUserService.countByActivityIdAndGender(activityId, UserGenderEnum.WOMEN.getCode());
            this.update(Wrappers.lambdaUpdate(ActivityShop.class).eq(ActivityShop::getId, activityId)
                    .set(ActivityShop::getJoinWomenNum, womenCount));
            Long manCount = activityUserService.countByActivityIdAndGender(activityId, UserGenderEnum.MAN.getCode());
            this.update(Wrappers.lambdaUpdate(ActivityShop.class).eq(ActivityShop::getId, activityId)
                    .set(ActivityShop::getJoinManNum, manCount));
        }

    }

    @Override
    public ActivityShopAppInfo info(Long activityId, String activityCode) {
        ActivityShop activityShop = null;
        if(activityId != null){
            activityShop = this.getById(activityId);
        }else if(StringUtils.isNotEmpty(activityCode)){
            activityShop = getByCode(activityCode);
        }
        if(activityShop == null){
            return null;
        }
        Long userId = LoginHelper.getUserId();
        boolean joinActivity = false;
        if(userId != null){
            joinActivity = activityUserService.checkJoin(userId, activityId);
        }
        ActivityShopAppInfo appInfo = new ActivityShopAppInfo();
        appInfo.setMustVip(activityShop.getMustVip());
        appInfo.setMustAuth(activityShop.getMustAuth());
        appInfo.setPriceText(activityShop.getPriceText());
        appInfo.setJoinWomenNum(activityShop.getJoinWomenNum()+activityShop.getHandWomenNum());
        appInfo.setJoinManNum(activityShop.getJoinManNum()+ activityShop.getHandManNum());
        appInfo.setId(activityShop.getId());
        appInfo.setActivityText(activityShop.getActivityText());
        appInfo.setOpenStatus(ActivityShopStatusEnum.getEnumByTime(activityShop.getStartTime(), activityShop.getEndTime()).getCode());
        appInfo.setActivityCode(activityShop.getActivityCode());
        appInfo.setActivityTitle(activityShop.getActivityTitle());
        appInfo.setActivityBanner(activityShop.getActivityBanner());
        appInfo.setStartTime(activityShop.getStartTime());
        appInfo.setEndTime(activityShop.getEndTime());
        appInfo.setCityName(activityShop.getCityName());
        appInfo.setCityCode(activityShop.getCityCode());
        appInfo.setWomenMaxNum(activityShop.getWomenMaxNum());
        appInfo.setManMaxNum(activityShop.getManMaxNum());
        appInfo.setJoinWomenPrice(activityShop.getJoinWomenPrice());
        appInfo.setJoinManPrice(activityShop.getJoinManPrice());
        appInfo.setJoinActivity(joinActivity);
        appInfo.setActivityStartTime(activityShop.getActivityStartTime());
        appInfo.setActivityEndTime(activityShop.getActivityEndTime());
        return appInfo;
    }

    @Override
    public JoinResp join(FreeJoinReq req) {
        JoinResp joinResp = this.checkJoin(req.getUserId(), req.getActivityId());
        if(!joinResp.isJoinSuccess()){
            return joinResp;
        }
        activityUserService.joinActivity(req.getActivityId(),req.getMobile(),req.getUserId());
        return null;
    }

    /**
     * @return 1-未实名认证 2-未开启VIP 3-需要支付
     */
    @Override
    public JoinResp checkJoin(Long userId, Long activityId) {
        ActivityShop activityShop = this.getById(activityId);
        if(activityShop == null){
            throw new ServiceException("活动不存在");
        }
        User user = userService.getById(userId);
        if(user == null){
            throw new ServiceException("用户异常");
        }
        // 检测是否已经加入
        boolean join = activityUserService.checkJoin(userId,activityId);
        if(join){
            JoinResp resp = new JoinResp();
            resp.setJoinSuccess(false);
            resp.setFailCode(99);
            resp.setFailText("您已经参加该活动");
            return resp;
        }
        LocalDateTime now = LocalDateTime.now();
        if(now.isBefore(activityShop.getStartTime())){
            JoinResp resp = new JoinResp();
            resp.setJoinSuccess(false);
            resp.setFailCode(99);
            resp.setFailText("活动还未开始");
            return resp;
        }
        if(now.isAfter(activityShop.getEndTime())){
            JoinResp resp = new JoinResp();
            resp.setJoinSuccess(false);
            resp.setFailCode(99);
            resp.setFailText("活动已经结束");
            return resp;
        }
        // 人数检测
        if(UserGenderEnum.MAN.getCode().equals(user.getGender())){
            if(activityShop.getManMaxNum() <= activityShop.getJoinManNum() + activityShop.getHandManNum()){
                JoinResp resp = new JoinResp();
                resp.setJoinSuccess(false);
                resp.setFailCode(99);
                resp.setFailText("男用户报名人数已满");
                return resp;
            }
        }else if(UserGenderEnum.WOMEN.getCode().equals(user.getGender())){
            if(activityShop.getWomenMaxNum() <= activityShop.getJoinWomenNum() + activityShop.getHandWomenNum()){
                JoinResp resp = new JoinResp();
                resp.setJoinSuccess(false);
                resp.setFailCode(99);
                resp.setFailText("女用户报名人数已满");
                return resp;
            }
        }else{
            throw new ServiceException("用户异常");
        }
        // 实名检测
        if(activityShop.getMustAuth() == 1){
            UserAuth userAuth = userAuthService.getByUserId(userId);
            if(userAuth == null){
                throw new ServiceException("用户异常");
            }
            if(!AuditEnum.SUCCESS.getCode().equals(userAuth.getCardNumAuth())){
                JoinResp resp = new JoinResp();
                resp.setJoinSuccess(false);
                resp.setFailCode(1);
                resp.setFailText("未实名认证");
                return resp;
            }
        }
        // VIP检测
        if(activityShop.getMustAuth() == 1){
            if(BooleanUtils.isNotTrue(user.getOpenVip())){
                JoinResp resp = new JoinResp();
                resp.setJoinSuccess(false);
                resp.setFailCode(2);
                resp.setFailText("未开通VIP");
                return resp;
            }
        }
        // 需要支付
        BigDecimal price = getJoinPrice(user,activityShop);
        if(price.compareTo(BigDecimal.ZERO) > 0){
            JoinResp resp = new JoinResp();
            resp.setPrice(price);
            resp.setJoinSuccess(false);
            resp.setFailCode(3);
            resp.setFailText("需要支付");
            return resp;
        }
        JoinResp resp = new JoinResp();
        resp.setJoinSuccess(true);
        return resp;
    }

    private BigDecimal getJoinPrice(User user, ActivityShop activityShop) {
        boolean openVip = BooleanUtils.isTrue(user.getOpenVip());
        Integer vipType = user.getVipType();
        if(UserGenderEnum.MAN.getCode().equals(user.getGender())){
            if(openVip){
                if(VipTypeEnum.THREE.getCode().equals(vipType)){
                    return activityShop.getVip3ManPrice();
                }else if(VipTypeEnum.TWO.getCode().equals(vipType)){
                    return activityShop.getVip2ManPrice();
                }else{
                    return activityShop.getVip1ManPrice();
                }
            } else {
                return activityShop.getVip0ManPrice();
            }
        }else if(UserGenderEnum.WOMEN.getCode().equals(user.getGender())){
            if(openVip){
                if(VipTypeEnum.THREE.getCode().equals(vipType)){
                    return activityShop.getVip3WomenPrice();
                }else if(VipTypeEnum.TWO.getCode().equals(vipType)){
                    return activityShop.getVip2WomenPrice();
                }else{
                    return activityShop.getVip1WomenPrice();
                }
            } else {
                return activityShop.getVip0WomenPrice();
            }
        }else{
            throw new ServiceException("用户异常");
        }
    }


    @Autowired
    private AreaCodeService areaCodeService;
    @Autowired
    private CodeKit codeKit;

    @Override
    public void saveData(ActivityShop bo) {
        String code = codeKit.nextCodeActivity();
        bo.setActivityCode(code);
        if(bo.getStartTime().isAfter(bo.getEndTime())){
            throw new ServiceException("报名开始时间不能大于报名结束时间");
        }
        if(bo.getActivityStartTime().isAfter(bo.getActivityEndTime())){
            throw new ServiceException("活动开始时间不能大于活动结束时间");
        }
        AreaCode areaCode = areaCodeService.getById(bo.getCityCode());
        bo.setCityName(areaCode.getName());
        this.save(bo);
    }

    @Override
    public void updateData(ActivityShopAdminUpdateReq bo) {
        if(bo.getStartTime().isAfter(bo.getEndTime())){
            throw new ServiceException("报名开始时间不能大于报名结束时间");
        }
        if(bo.getActivityStartTime().isAfter(bo.getActivityEndTime())){
            throw new ServiceException("活动开始时间不能大于活动结束时间");
        }
        ActivityShop update = BeanConvertUtil.convertTo(bo, ActivityShop::new);
        AreaCode areaCode = areaCodeService.getById(bo.getCityCode());
        update.setCityName(areaCode.getName());
        this.updateById(update);
    }

    @Override
    public void updateDataUser(ActivityShop bo) {
        ActivityShop shop = new ActivityShop();
        shop.setId(bo.getId());
        shop.setHandWomenNum(bo.getHandWomenNum());
        shop.setHandManNum(bo.getHandManNum());
        this.updateById(bo);
    }

    @Override
    public void removeDataByIds(Long[] ids) {
        List<Long> idArray = Arrays.stream(ids).collect(Collectors.toList());
        this.update(Wrappers.lambdaUpdate(ActivityShop.class)
                .in(ActivityShop::getId, idArray)
                .set(ActivityShop::getDeleteFlag, 1));
    }
}
