package com.sqx.modules.app.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.map.MapProxy;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.tea.ValidateException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.Constant;
import com.sqx.common.utils.PageUtils;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.dao.UserPrizeExchangeDao;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.entity.UserPrizeExchange;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.app.service.UserPrizeExchangeService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.discSpinning.dao.DiscSpinningRecordDao;
import com.sqx.modules.discSpinning.entity.DiscSpinningRecord;
import com.sqx.modules.taskCenter.dao.TaskCenterRecordDao;
import com.sqx.modules.taskCenter.dao.TaskCenterRewardDao;
import com.sqx.modules.taskCenter.entity.TaskCenterRecord;
import com.sqx.modules.taskCenter.entity.TaskCenterReward;
import com.sqx.modules.userSign.dto.UserSignDTO;
import com.sqx.modules.userSign.service.UserSignRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * @author tankaikai
 * @since 2024-12-20 18:10
 */
@Slf4j
@Service
public class UserPrizeExchangeServiceImpl extends ServiceImpl<UserPrizeExchangeDao, UserPrizeExchange> implements UserPrizeExchangeService {

    @Resource
    private DiscSpinningRecordDao discSpinningRecordDao;
    @Resource
    private TaskCenterRecordDao taskCenterRecordDao;
    @Resource
    private TaskCenterRewardDao taskCenterRewardDao;
    @Resource
    private CommonInfoService commonRepository;
    @Resource
    private UserMoneyService userMoneyService;
    @Resource
    private UserMoneyDetailsService userMoneyDetailsService;
    @Resource
    private UserSignRecordService userSignRecordService;

    @Resource
    private UserDao userDao;

    @Override
    public PageUtils page(Map<String, Object> params) {
        MapProxy proxy = MapProxy.create(params);
        Long foreignId = proxy.getLong("foreignId");
        String foreignType = proxy.getStr("foreignType");
        Long userId = proxy.getLong("userId");
        String userName = proxy.getStr("userName");
        String prizeName = proxy.getStr("prizeName");
        Integer status = proxy.getInt("status");
        String phone = proxy.getStr("phone");
        String remark = proxy.getStr("remark");
        String beginDate = proxy.getStr("beginDate");
        String endDate = proxy.getStr("endDate");
        LambdaQueryWrapper<UserPrizeExchange> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(foreignId != null, UserPrizeExchange::getForeignId, foreignId);
        wrapper.eq(StrUtil.isNotEmpty(foreignType), UserPrizeExchange::getForeignType, foreignType);
        wrapper.eq(userId != null, UserPrizeExchange::getUserId, userId);
        wrapper.like(StrUtil.isNotEmpty(userName), UserPrizeExchange::getUserName, userName);
        wrapper.like(StrUtil.isNotEmpty(prizeName), UserPrizeExchange::getPrizeName, prizeName);
        wrapper.eq(status != null, UserPrizeExchange::getStatus, status);
        wrapper.like(StrUtil.isNotEmpty(phone), UserPrizeExchange::getPhone, phone);
        wrapper.like(StrUtil.isNotEmpty(remark), UserPrizeExchange::getRemark, remark);
        if (StrUtil.isNotEmpty(beginDate)) {
            wrapper.apply("create_time >= str_to_date({0}, '%Y-%m-%d %H:%i:%s')", beginDate + " 00:00:00");
        }
        if (StrUtil.isNotEmpty(endDate)) {
            wrapper.apply("create_time <= str_to_date({0}, '%Y-%m-%d %H:%i:%s')", endDate + " 23:59:59");
        }
        wrapper.orderByDesc(UserPrizeExchange::getId);
        long pageNum = proxy.getLong(Constant.PAGE, 1L);
        long pageSize = proxy.getLong(Constant.LIMIT, 10L);
        PageHelper.startPage((int) pageNum, (int) pageSize);
        return PageUtils.page(new PageInfo<>(this.list(wrapper)));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void exchange(Long currentUserId, UserPrizeExchange dto) {
        if (dto.getForeignId() == null) {
            throw new SqxException("中奖记录ID不能为空");
        }
        if (StrUtil.isEmpty(dto.getForeignType())) {
            throw new SqxException("活动类型不能为空");
        }
        if (!ArrayUtil.contains(new String[]{"spinning", "task"}, dto.getForeignType())) {
            throw new SqxException("仅限大转盘、任务活动兑换奖品");
        }
        if (StrUtil.isBlank(dto.getPhone())) {
            throw new SqxException("用户手机号码不能为空");
        }
        try {
            Validator.isMobile(dto.getPhone());
        } catch (ValidateException e) {
            throw new SqxException("用户手机号码不合法");
        }
        Dict dict = Dict.create();
        if ("spinning".equals(dto.getForeignType())) {
            DiscSpinningRecord record = discSpinningRecordDao.selectById(dto.getForeignId());
            if (record == null) {
                throw new SqxException("中奖记录不存在");
            }
            dict.put("userId", record.getUserId());
            dict.put("name", record.getName());
            dict.put("imgUrl", record.getImgUrl());
            dict.put("type", record.getType());
        } else if ("task".equals(dto.getForeignType())) {
            TaskCenterRecord record = taskCenterRecordDao.selectById(dto.getForeignId());
            if (record == null) {
                throw new SqxException("中奖记录不存在");
            }
            if (record.getSourceId() == null) {
                throw new SqxException("中奖记录未关联奖品");
            }
            TaskCenterReward reward = taskCenterRewardDao.selectById(record.getSourceId());
            if (reward == null) {
                throw new SqxException("对应的奖品信息不存在");
            }
            dict.put("userId", record.getUserId());
            dict.put("name", record.getName());
            dict.put("imgUrl", reward.getImg());
            dict.put("type", reward.getType());
        }
        Long userId = dict.getLong("userId");
        String name = dict.getStr("name");
        String imgUrl = dict.getStr("imgUrl");
        Integer type = dict.getInt("type");
        if (userId == null) {
            throw new SqxException("中奖用户数据不完整");
        }
        if (currentUserId == null) {
            throw new SqxException("未获取当前登录用户id");
        }
        if (!currentUserId.equals(userId)) {
            throw new SqxException("兑奖用户和获奖用户不一致");
        }
        UserEntity user = userDao.selectById(userId);
        if (user == null) {
            throw new SqxException("兑奖用户不存在");
        }
        if (ArrayUtil.contains(new int[]{1, 2}, type)) {
            throw new SqxException("仅限兑换实物、会员卡等奖项");
        }
        Integer count = baseMapper.selectCount(Wrappers.<UserPrizeExchange>lambdaQuery()
                .eq(UserPrizeExchange::getForeignId, dto.getForeignId())
                .eq(UserPrizeExchange::getForeignType, dto.getForeignType())
        );
        if (count != null && count > 0) {
            throw new SqxException("奖品已兑换，请勿重复操作");
        }
        dto.setPrizeName(name);
        dto.setUserId(userId);
        dto.setUserName(user.getUserName());
        dto.setStatus(0);
        dto.setCreateTime(new Date());
        dto.setImgUrl(imgUrl);
        baseMapper.insert(dto);
        if ("spinning".equals(dto.getForeignType())) {
            discSpinningRecordDao.update(null,
                    Wrappers.<DiscSpinningRecord>lambdaUpdate()
                            .set(DiscSpinningRecord::getTarget, "3")
                            .set(DiscSpinningRecord::getTargetId, dto.getId())
                            .eq(DiscSpinningRecord::getId, dto.getForeignId())
            );
        } else if ("task".equals(dto.getForeignType())) {
            taskCenterRecordDao.update(null,
                    Wrappers.<TaskCenterRecord>lambdaUpdate()
                            .set(TaskCenterRecord::getTargetId, dto.getId())
                            .eq(TaskCenterRecord::getId, dto.getForeignId())
            );
        }
    }

    @Override
    public void deliver(UserPrizeExchange dto) {
        Long id = dto.getId();
        if (id == null) {
            throw new SqxException("兑奖id不能为空");
        }
        UserPrizeExchange entity = baseMapper.selectById(id);
        if (entity == null) {
            throw new SqxException("兑奖订单不存在");
        }
        entity.setStatus(1);
        if (StrUtil.isNotEmpty(dto.getAddress())) {
            entity.setAddress(dto.getAddress());
        }
        if (StrUtil.isNotEmpty(dto.getRemark())) {
            entity.setRemark(dto.getRemark());
        }
        entity.setUpdateTime(new Date());
        baseMapper.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void receive(Long currentUserId) {
        if (currentUserId == null) {
            throw new SqxException("未获取当前登录用户id");
        }
        UserEntity userEntity = userDao.selectById(currentUserId);
        if (userEntity == null) {
            throw new SqxException("该用户信息不存在");
        }
        CommonInfo one = commonRepository.findOne(918);
        if (one == null) {
            throw new SqxException("奖品配置信息不存在");
        }
        String value = one.getValue();
        String signDays = value.split(",")[0];
        String moneyStr = value.split(",")[1];
        UserSignDTO userSignData = userSignRecordService.getUserSignData(currentUserId);
        if (userSignData.getSignDays() < Convert.toInt(signDays)) {
            throw new SqxException(StrUtil.format("连续签到天数不足{}天，无法领取奖励", signDays));
        }
        int count = userMoneyDetailsService.count(
                Wrappers.<UserMoneyDetails>lambdaQuery()
                        .eq(UserMoneyDetails::getUserId, currentUserId)
                        .eq(UserMoneyDetails::getType, 1)
                        .eq(UserMoneyDetails::getClassify, 7)
                        .eq(UserMoneyDetails::getMoneyType, 1)
                        .likeLeft(UserMoneyDetails::getTitle, "[连续签到")
                        .likeRight(UserMoneyDetails::getTitle, "天]")
        );
        if (count > 0) {
            throw new SqxException("已经领取过连续签到奖励，无需重复操作");
        }
        BigDecimal money = new BigDecimal(moneyStr);
        userMoneyService.updateAmount(1, currentUserId, money.doubleValue());
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setUserId(currentUserId);
        userMoneyDetails.setTitle(StrUtil.format("[连续签到{}天]", signDays));
        userMoneyDetails.setContent("现金红包奖励：" + moneyStr + "元");
        // 充值
        userMoneyDetails.setType(1);
        // 任务领取
        userMoneyDetails.setClassify(7);
        userMoneyDetails.setMoney(money);
        userMoneyDetails.setCreateTime(DateUtil.now());
        userMoneyDetails.setMoneyType(1);
        userMoneyDetailsService.save(userMoneyDetails);
    }
}
