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.DistributorStatus;
import com.haha.common.exception.BusinessException;
import com.haha.common.vo.StatusLabel;
import com.haha.entity.Distributor;
import com.haha.entity.DistributorReferral;
import com.haha.entity.dto.DistributorCreateDTO;
import com.haha.entity.dto.DistributorQueryDTO;
import com.haha.entity.dto.DistributorUpdateDTO;
import com.haha.mapper.DistributorMapper;
import com.haha.mapper.DistributorReferralMapper;
import com.haha.service.DistributorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Slf4j
@Service
@RequiredArgsConstructor
public class DistributorServiceImpl extends ServiceImpl<DistributorMapper, Distributor> implements DistributorService {

    private final DistributorMapper distributorMapper;
    private final DistributorReferralMapper distributorReferralMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Distributor create(DistributorCreateDTO dto, Long creatorId, String creatorName) {
        int phoneCount = distributorMapper.countByPhone(dto.getPhone(), 0L);
        if (phoneCount > 0) {
            throw new BusinessException(400, "手机号已存在");
        }

        String maxCode = distributorMapper.selectMaxCode();
        int nextNum = 1;
        if (maxCode != null && maxCode.startsWith("DS")) {
            String numPart = maxCode.substring(2);
            try {
                nextNum = Integer.parseInt(numPart) + 1;
            } catch (NumberFormatException e) {
                nextNum = 1;
            }
        }
        String code = "DS" + String.format("%06d", nextNum);

        Distributor distributor = new Distributor();
        distributor.setCode(code);
        distributor.setName(dto.getName());
        distributor.setPhone(dto.getPhone());
        distributor.setStatus(DistributorStatus.PENDING.getCode());
        distributor.setRemark(dto.getRemark());
        distributor.setCreatorId(creatorId);
        distributor.setCreatorName(creatorName);
        distributor.setCreateTime(LocalDateTime.now());
        distributor.setUpdateTime(LocalDateTime.now());
        distributor.setDeleted(CommonConstants.NOT_DELETED);

        this.save(distributor);

        log.info("[分销员] 创建成功 - id: {}, code: {}, name: {}", distributor.getId(), distributor.getCode(), distributor.getName());
        return distributor;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Distributor update(DistributorUpdateDTO dto) {
        Distributor distributor = this.getById(dto.getId());
        if (distributor == null || distributor.getDeleted() == CommonConstants.DELETED) {
            throw new BusinessException(404, "分销员不存在");
        }

        if (dto.getPhone() != null && !dto.getPhone().equals(distributor.getPhone())) {
            int phoneCount = distributorMapper.countByPhone(dto.getPhone(), dto.getId());
            if (phoneCount > 0) {
                throw new BusinessException(400, "手机号已存在");
            }
            distributor.setPhone(dto.getPhone());
        }

        if (dto.getName() != null) {
            distributor.setName(dto.getName());
        }
        if (dto.getRemark() != null) {
            distributor.setRemark(dto.getRemark());
        }
        distributor.setUpdateTime(LocalDateTime.now());

        this.updateById(distributor);

        log.info("[分销员] 更新成功 - id: {}, name: {}", distributor.getId(), distributor.getName());
        return distributor;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean activate(Long id) {
        Distributor distributor = this.getById(id);
        if (distributor == null || distributor.getDeleted() == CommonConstants.DELETED) {
            throw new BusinessException(404, "分销员不存在");
        }
        if (!DistributorStatus.isPending(distributor.getStatus())) {
            throw new BusinessException(400, "当前状态不允许激活");
        }

        distributor.setStatus(DistributorStatus.ACTIVE.getCode());
        distributor.setUpdateTime(LocalDateTime.now());
        this.updateById(distributor);

        // TODO: 触发二维码生成

        log.info("[分销员] 激活成功 - id: {}, code: {}", distributor.getId(), distributor.getCode());
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deactivate(Long id) {
        Distributor distributor = this.getById(id);
        if (distributor == null || distributor.getDeleted() == CommonConstants.DELETED) {
            throw new BusinessException(404, "分销员不存在");
        }
        if (!DistributorStatus.isActive(distributor.getStatus())) {
            throw new BusinessException(400, "当前状态不允许停用");
        }

        distributor.setStatus(DistributorStatus.DISABLED.getCode());
        distributor.setUpdateTime(LocalDateTime.now());
        this.updateById(distributor);

        log.info("[分销员] 停用成功 - id: {}, code: {}", distributor.getId(), distributor.getCode());
        return true;
    }

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

        LambdaQueryWrapper<Distributor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(queryDTO.getCode() != null, Distributor::getCode, queryDTO.getCode());
        wrapper.like(queryDTO.getName() != null, Distributor::getName, queryDTO.getName());
        wrapper.eq(queryDTO.getPhone() != null, Distributor::getPhone, queryDTO.getPhone());
        wrapper.eq(queryDTO.getStatus() != null, Distributor::getStatus, queryDTO.getStatus());
        wrapper.eq(Distributor::getDeleted, CommonConstants.NOT_DELETED);
        wrapper.orderByDesc(Distributor::getCreateTime);

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

        return result;
    }

    @Override
    public Distributor getDetail(Long id) {
        Distributor distributor = this.getById(id);
        if (distributor == null || distributor.getDeleted() == CommonConstants.DELETED) {
            throw new BusinessException(404, "分销员不存在");
        }
        fillStatusLabel(distributor);
        return distributor;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        Distributor distributor = this.getById(id);
        if (distributor == null || distributor.getDeleted() == CommonConstants.DELETED) {
            throw new BusinessException(404, "分销员不存在");
        }

        LambdaQueryWrapper<DistributorReferral> referralWrapper = new LambdaQueryWrapper<>();
        referralWrapper.eq(DistributorReferral::getDistributorId, id);
        Long referralCount = distributorReferralMapper.selectCount(referralWrapper);
        if (referralCount > 0) {
            throw new BusinessException(400, "该分销员已有推荐记录，无法删除");
        }

        distributor.setDeleted(CommonConstants.DELETED);
        distributor.setUpdateTime(LocalDateTime.now());
        this.updateById(distributor);

        log.info("[分销员] 删除成功 - id: {}, code: {}", distributor.getId(), distributor.getCode());
        return true;
    }

    private void fillStatusLabel(Distributor distributor) {
        if (distributor.getStatus() == null) {
            return;
        }
        StatusLabel statusLabel = DistributorStatus.getLabelByCode(distributor.getStatus());
        if (statusLabel != null) {
            distributor.setStatusLabel(statusLabel.getLabel());
        }
    }
}
