package com.haha.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.haha.common.constant.CommonConstants;
import com.haha.common.enums.DistributorReferralStatus;
import com.haha.common.enums.DistributorStatus;
import com.haha.common.exception.BusinessException;
import com.haha.entity.Distributor;
import com.haha.entity.DistributorReferral;
import com.haha.entity.User;
import com.haha.entity.dto.ReferralQueryDTO;
import com.haha.mapper.DistributorMapper;
import com.haha.mapper.DistributorReferralMapper;
import com.haha.mapper.UserMapper;
import com.haha.service.DistributorConfigService;
import com.haha.service.DistributorReferralService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

@Slf4j
@Service
@RequiredArgsConstructor
public class DistributorReferralServiceImpl extends ServiceImpl<DistributorReferralMapper, DistributorReferral> implements DistributorReferralService {

    private final DistributorReferralMapper referralMapper;
    private final DistributorMapper distributorMapper;
    private final DistributorConfigService configService;
    private final UserMapper userMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DistributorReferral bindReferral(String distributorCode, Long userId) {
        if (!StringUtils.hasText(distributorCode)) {
            throw new BusinessException(400, "分销员编码不能为空");
        }

        LambdaQueryWrapper<Distributor> distributorWrapper = new LambdaQueryWrapper<>();
        distributorWrapper.eq(Distributor::getCode, distributorCode);
        distributorWrapper.eq(Distributor::getStatus, DistributorStatus.ACTIVE.getCode());
        distributorWrapper.eq(Distributor::getDeleted, CommonConstants.NOT_DELETED);
        Distributor distributor = distributorMapper.selectOne(distributorWrapper);
        if (distributor == null) {
            throw new BusinessException(404, "分销员不存在或未激活");
        }

        if (distributor.getId().equals(userId)) {
            throw new BusinessException(400, "不能推荐自己");
        }

        int userReferralCount = referralMapper.countByUserId(userId);
        if (userReferralCount > 0) {
            throw new BusinessException(400, "该用户已有分销推荐关系");
        }

        int duplicateCount = referralMapper.countByDistributorAndUser(distributor.getId(), userId);
        if (duplicateCount > 0) {
            log.info("推荐关系已存在，跳过绑定: distributorId={}, userId={}", distributor.getId(), userId);
            return referralMapper.selectByUserId(userId);
        }

        DistributorReferral referral = new DistributorReferral();
        referral.setDistributorId(distributor.getId());
        referral.setUserId(userId);
        referral.setStatus(DistributorReferralStatus.PENDING.getCode());

        Integer validTimeWindowDays = configService.getValidTimeWindowDays();
        if (validTimeWindowDays != null && validTimeWindowDays > 0) {
            referral.setExpireTime(LocalDateTime.now().plusDays(validTimeWindowDays));
        }

        referralMapper.insert(referral);
        distributorMapper.incrementTotalReferrals(distributor.getId());

        log.info("绑定分销推荐关系成功: distributorId={}, userId={}", distributor.getId(), userId);
        return referral;
    }

    @Override
    public IPage<DistributorReferral> getPage(ReferralQueryDTO queryDTO) {
        queryDTO.validate();
        Page<DistributorReferral> page = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());

        LambdaQueryWrapper<DistributorReferral> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(queryDTO.getDistributorId() != null, DistributorReferral::getDistributorId, queryDTO.getDistributorId());
        wrapper.eq(queryDTO.getUserId() != null, DistributorReferral::getUserId, queryDTO.getUserId());
        wrapper.eq(queryDTO.getStatus() != null, DistributorReferral::getStatus, queryDTO.getStatus());
        if (queryDTO.getStartDate() != null) {
            wrapper.ge(DistributorReferral::getCreateTime, queryDTO.getStartDate());
        }
        if (queryDTO.getEndDate() != null) {
            wrapper.le(DistributorReferral::getCreateTime, queryDTO.getEndDate() + " 23:59:59");
        }
        wrapper.orderByDesc(DistributorReferral::getCreateTime);

        IPage<DistributorReferral> result = this.page(page, wrapper);
        result.getRecords().forEach(this::fillLabels);

        return result;
    }

    @Override
    public DistributorReferral getByUserId(Long userId) {
        return referralMapper.selectByUserId(userId);
    }

    private void fillLabels(DistributorReferral referral) {
        if (referral == null) {
            return;
        }

        if (referral.getStatus() != null) {
            com.haha.common.vo.StatusLabel label = DistributorReferralStatus.getLabelByCode(referral.getStatus());
            referral.setStatusLabel(label.getLabel());
        }

        if (referral.getDistributorId() != null) {
            Distributor distributor = distributorMapper.selectById(referral.getDistributorId());
            if (distributor != null) {
                referral.setDistributorName(distributor.getName());
            }
        }

        if (referral.getUserId() != null) {
            User user = userMapper.selectById(referral.getUserId());
            if (user != null) {
                referral.setUserName(user.getNickname());
            } else {
                referral.setUserName("未知用户");
            }
        }
    }
}
