package org.jeecg.modules.shop.user.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.jeecg.modules.sequence.service.IMiddleSequenceService;
import org.jeecg.config.shiro.util.ShopTokenUtil;
import org.jeecg.modules.shop.captcha.enums.CaptchaKeyEnum;
import org.jeecg.modules.shop.captcha.enums.CaptchaTypeEnum;
import org.jeecg.modules.shop.captcha.service.ICaptchaService;
import org.jeecg.modules.shop.commission.entity.PartnerCommission;
import org.jeecg.modules.shop.commission.service.IPartnerCommissionService;
import org.jeecg.modules.shop.customer.entity.PartnerCustomer;
import org.jeecg.modules.shop.customer.service.IPartnerCustomerService;
import org.jeecg.modules.shop.order.entity.PartnerOrder;
import org.jeecg.modules.shop.order.service.IPartnerOrderService;
import org.jeecg.modules.shop.user.entity.PartnerUser;
import org.jeecg.modules.shop.user.entity.dto.UserInfoDTO;
import org.jeecg.modules.shop.user.entity.dto.UserLoginDTO;
import org.jeecg.modules.shop.user.entity.vo.DataCountVO;
import org.jeecg.modules.shop.user.entity.vo.PageListCostomerVO;
import org.jeecg.modules.shop.user.entity.vo.UserInfoVO;
import org.jeecg.modules.shop.user.entity.vo.UserLoginVO;
import org.jeecg.modules.shop.user.mapper.PartnerUserMapper;
import org.jeecg.modules.shop.user.service.IPartnerUserService;
import org.jeecg.modules.shop.user.util.partnerUserHolder;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Description: partner_user
 * @Author: jeecg-boot
 * @Date:   2025-07-09
 * @Version: V1.0
 */
@Service
@RequiredArgsConstructor
public class PartnerUserServiceImpl extends ServiceImpl<PartnerUserMapper, PartnerUser> implements IPartnerUserService {

    private final ICaptchaService captchaService;

    private final IMiddleSequenceService middleSequenceService;

    private final IPartnerCommissionService commissionService;

    private final IPartnerOrderService orderService;

    private final IPartnerCustomerService customerService;

    private final ShopTokenUtil shopTokenUtil;

    private final RedisTemplate<String, String> redisTemplate;
    @Override
    public UserLoginVO login(UserLoginDTO loginDTO) {
        PartnerUser user = null;
        String email = loginDTO.getEmail();
        String captchaKey = CaptchaKeyEnum.generateEmailCaptchaKey(
                CaptchaTypeEnum.SUPPLIER_LOGIN.getType(), email);
        String captcha = captchaService.getCaptcha(captchaKey, 5);
        Assert.isTrue(StrUtil.equals(loginDTO.getCaptcha(), captcha), "验证码无效");
        captchaService.clearCaptcha(captchaKey);
        // 查询用户
        LambdaQueryWrapper<PartnerUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PartnerUser::getEmail, email);
        user = this.getOne(queryWrapper);
        if (user == null) {
            // 创建新用户
            user = new PartnerUser();
            user.setId(String.valueOf(IdWorker.getId()));
            user.setEmail(email);
            user.setRegisterTime(DateUtil.date());
            user.setState(1);
            user.setLoginCount(1);
            user.setLoginTime(DateUtil.date());
            user.setBillNo(middleSequenceService.generate("HZ", 6));
            user.setInfoState(0);
            user.setAuditState(0);
            this.save(user);
        } else {
            // 更新登录信息
            user.setLoginCount(user.getLoginCount() + 1);
            user.setLoginTime(DateUtil.date());
            this.updateById(user);
        }
        UserLoginVO vo = new UserLoginVO();
        if (user.getState()==1) {
            vo.setToken(shopTokenUtil.createPartnerCustomerUserToken(user.getId()));
        }
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);
        vo.setUserInfo(userInfoVO);
        return vo;
    }

    @Override
    public void logout(String token) {
        if (StrUtil.isNotBlank(token)) {
            long remainingSeconds = shopTokenUtil.getRemainingSeconds(token);
            if (remainingSeconds > 0) {
                redisTemplate.opsForValue().set("shop:user:invalid-token:" + token, "1", remainingSeconds, TimeUnit.SECONDS);
            }
        }
    }

    @Override
    public UserInfoVO getUserInfo() {
        PartnerUser customerUser = getCurrentLoginCustomerUser();
        if (null == customerUser) {
            throw new RuntimeException("获取用户信息失败");
        }
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(customerUser, userInfoVO);
        return userInfoVO;
    }

    @Override
    public void updateUserInfo(UserInfoDTO dto) {
        PartnerUser updateCustomerUser = new PartnerUser();
        BeanUtils.copyProperties(dto, updateCustomerUser);
        updateCustomerUser.setId(partnerUserHolder.currentLoginUserId());
        baseMapper.updateById(updateCustomerUser);
    }

    @Override
    public void submitInfo(UserInfoDTO dto) {
        PartnerUser updateCustomerUser = new PartnerUser();
        BeanUtils.copyProperties(dto, updateCustomerUser);
        updateCustomerUser.setId(partnerUserHolder.currentLoginUserId());
        updateCustomerUser.setInfoSubmitTime(DateUtil.date());
        baseMapper.updateById(updateCustomerUser);
    }

    @Override
    public DataCountVO dataCount(String year) {
        //待发放
        BigDecimal money = BigDecimal.ZERO;
        String userId = partnerUserHolder.currentLoginUserId();
        List<PartnerCommission> cos = commissionService.list(
                new LambdaQueryWrapper<PartnerCommission>()
                        .eq(PartnerCommission::getUserId, userId)
                        .eq(PartnerCommission::getState, 0));
        for (PartnerCommission co : cos) {
            money = money.add(co.getMoney());
        }
        //客户数量
        Integer customCount = (int)customerService.count(new LambdaQueryWrapper<PartnerCustomer>().eq(PartnerCustomer::getUserId, userId)
                .apply("DATE_FORMAT(create_time, '%Y') ={0}", year));
        //客户佣金
        BigDecimal customerCommission = commissionService.getCommissionByUserAndYear(userId, year);
        //客户下单人数
        Integer takeOrderUser = orderService.getTakeOrderUserCountByUserAndYear(userId, year);
        //订单数量
        Integer orderCount = orderService.getOrderCountByUserAndYear(userId, year);
        //订单佣金
        BigDecimal orderCommission = commissionService.getOrderCommissionByUserAndYear(userId, year);
        DataCountVO vo = new DataCountVO();
        vo.setMoney(money);
        vo.setCustomerCount(customCount);
        vo.setCustomerMoney(customerCommission);
        vo.setCustomerOrderCount(takeOrderUser);
        vo.setOrderCount(orderCount);
        vo.setOrderMoney(orderCommission);
        return vo;
    }

    @Override
    public IPage<PageListCostomerVO> customerList(Integer pageNo, Integer pageSize) {
        String userId = partnerUserHolder.currentLoginUserId();
        return baseMapper.customerList(userId,new Page<PageListCostomerVO>(pageNo, pageSize));
    }

    @Override
    public IPage<PageListCostomerVO> orderList(Integer pageNo, Integer pageSize) {
        String userId = partnerUserHolder.currentLoginUserId();
        return baseMapper.orderList(userId,new Page<PageListCostomerVO>(pageNo, pageSize));
    }

    private PartnerUser getCurrentLoginCustomerUser() {
        try {
            String userId = partnerUserHolder.currentLoginUserId(); // 此方法也提供给其他模块调用，所以加一下登录和类型判断
            PartnerUser customerUser = getById(userId);
            return customerUser;
        } catch (Exception e) {
            return null;
        }
    }
}
