package com.jeesharp.business.modules.mall.service.impl;

import com.jeesharp.business.modules.common.enums.ShelfStatusEnum;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.mall.enums.MallSpuAuditStatusEnum;

import com.jeesharp.business.modules.mall.entity.MallSpu;
import com.jeesharp.business.modules.mall.mapper.MallSpuMapper;
import com.jeesharp.business.modules.mall.service.MallSpuService;
import com.jeesharp.business.modules.mall.vo.MallSpuQueryVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.mybatis.core.service.CrudService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商品SPU Service 实现类
 */
@Service
@Transactional(readOnly = true)
public class MallSpuServiceImpl extends CrudService<MallSpuMapper, MallSpu, MallSpuQueryVO> implements MallSpuService {

    @Override
    public List<MallSpu> listOnShelfSpusForPortal(int limit) {
        return listOnShelfSpusForPortal(limit, null);
    }

    @Override
    public List<MallSpu> listOnShelfSpusForPortal(int limit, String categoryId) {
        if (StrUtil.isNotBlank(categoryId)) {
            return listOnShelfSpusForPortalByCategoryIds(limit, List.of(categoryId.trim()));
        }
        return listOnShelfSpusForPortalByCategoryIds(limit, null);
    }

    @Override
    public List<MallSpu> listOnShelfSpusForPortalByCategoryIds(int limit, List<String> categoryIds) {
        int safeLimit = Math.max(1, limit);
        LambdaQueryWrapper<MallSpu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallSpu::getDelFlag, "0");
        wrapper.eq(MallSpu::getStatus, ShelfStatusEnum.ONLINE.getValue());
        wrapper.eq(MallSpu::getAuditStatus, MallSpuAuditStatusEnum.PASSED.getValue());
        if (categoryIds != null && !categoryIds.isEmpty()) {
            List<String> idList = categoryIds.stream()
                .filter(StrUtil::isNotBlank)
                .map(String::trim)
                .distinct()
                .collect(Collectors.toList());
            if (idList.isEmpty()) {
                return List.of();
            }
            wrapper.in(MallSpu::getCategoryId, idList);
        }
        wrapper.orderByAsc(MallSpu::getSortOrder);
        wrapper.last("LIMIT " + safeLimit);
        return getBaseMapper().selectList(wrapper);
    }

    @Override
    public List<MallSpu> listRecommendSpusForPortal(int limit) {
        MallSpuQueryVO query = new MallSpuQueryVO();
        query.setStatus(ShelfStatusEnum.ONLINE.getValue());
        query.setAuditStatus(MallSpuAuditStatusEnum.PASSED.getValue());
        query.setOrderBy("virtualSales desc");
        return findPage(new Page<>(1L, (long) limit), query).getRecords();
    }

    @Override
    public List<MallSpu> searchOnShelfSpusForPortal(int limit, String keyword) {
        if (StrUtil.isBlank(keyword)) {
            return List.of();
        }
        LambdaQueryWrapper<MallSpu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallSpu::getDelFlag, "0");
        wrapper.eq(MallSpu::getStatus, ShelfStatusEnum.ONLINE.getValue());
        wrapper.eq(MallSpu::getAuditStatus, MallSpuAuditStatusEnum.PASSED.getValue());
        wrapper.like(MallSpu::getSpuName, keyword.trim());
        wrapper.orderByAsc(MallSpu::getSortOrder);
        wrapper.last("LIMIT " + Math.max(1, limit));
        return getBaseMapper().selectList(wrapper);
    }

    @Override
    public List<String> findIdsBySpuNameLike(String spuName) {
        if (StrUtil.isBlank(spuName)) {
            return List.of();
        }
        LambdaQueryWrapper<MallSpu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallSpu::getDelFlag, "0");
        wrapper.like(MallSpu::getSpuName, spuName.trim());
        return getBaseMapper().selectList(wrapper).stream()
            .map(MallSpu::getId)
            .filter(StrUtil::isNotBlank)
            .distinct()
            .collect(Collectors.toList());
    }

    @Override
    public Map<String, String> mapSpuNameByIds(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return Collections.emptyMap();
        }
        List<String> idList = ids.stream().filter(StrUtil::isNotBlank).map(String::trim).distinct().collect(Collectors.toList());
        if (idList.isEmpty()) {
            return Collections.emptyMap();
        }
        LambdaQueryWrapper<MallSpu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallSpu::getDelFlag, "0");
        wrapper.in(MallSpu::getId, idList);
        return getBaseMapper().selectList(wrapper).stream()
            .filter(s -> s != null && StrUtil.isNotBlank(s.getId()))
            .collect(Collectors.toMap(MallSpu::getId, s -> StrUtil.blankToDefault(s.getSpuName(), ""), (a, b) -> a));
    }

    @Override
    public Page<MallSpu> findPageForPlatformAudit(Page<MallSpu> page, MallSpuQueryVO query) {
        LambdaQueryWrapper<MallSpu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MallSpu::getDelFlag, "0");
        Integer auditStatus = query != null && query.getAuditStatus() != null
            ? query.getAuditStatus()
            : MallSpuAuditStatusEnum.PENDING.getValue();
        wrapper.eq(MallSpu::getAuditStatus, auditStatus);
        if (query != null) {
            if (StrUtil.isNotBlank(query.getSpuName())) {
                wrapper.like(MallSpu::getSpuName, query.getSpuName().trim());
            }
            if (StrUtil.isNotBlank(query.getSpuCode())) {
                wrapper.eq(MallSpu::getSpuCode, query.getSpuCode().trim());
            }
            if (StrUtil.isNotBlank(query.getCategoryId())) {
                wrapper.eq(MallSpu::getCategoryId, query.getCategoryId().trim());
            }
            if (StrUtil.isNotBlank(query.getBrandId())) {
                wrapper.eq(MallSpu::getBrandId, query.getBrandId().trim());
            }
            if (StrUtil.isNotBlank(query.getTenantCode())) {
                wrapper.eq(MallSpu::getTenantCode, query.getTenantCode().trim());
            }
            if (query.getStatus() != null) {
                wrapper.eq(MallSpu::getStatus, query.getStatus());
            }
        }
        wrapper.orderByDesc(MallSpu::getCreateDate);
        return getBaseMapper().selectPage(page, wrapper);
    }

    @Override
    @Transactional(readOnly = false)
    public void auditSpu(String spuId, Integer auditStatus, String auditBy, String auditRemark) {
        if (StrUtil.isBlank(spuId)) {
            throw new BizErrorException("商品ID不能为空");
        }
        if (!MallSpuAuditStatusEnum.PASSED.getValue().equals(auditStatus)
            && !MallSpuAuditStatusEnum.REJECTED.getValue().equals(auditStatus)) {
            throw new BizErrorException("审核结果无效，仅支持通过或驳回");
        }
        if (MallSpuAuditStatusEnum.REJECTED.getValue().equals(auditStatus) && StrUtil.isBlank(auditRemark)) {
            throw new BizErrorException("驳回时请填写审核备注");
        }
        MallSpu spu = get(spuId);
        if (spu == null) {
            throw new BizErrorException("商品不存在");
        }
        if (!MallSpuAuditStatusEnum.PENDING.getValue().equals(spu.getAuditStatus())) {
            throw new BizErrorException("仅待审核商品可审核");
        }
        spu.setAuditStatus(auditStatus);
        spu.setAuditBy(auditBy);
        spu.setAuditRemark(StrUtil.trim(auditRemark));
        spu.setAuditTime(new Date());
        if (MallSpuAuditStatusEnum.PASSED.getValue().equals(auditStatus)) {
            spu.setStatus(ShelfStatusEnum.ONLINE.getValue());
        } else {
            spu.setStatus(ShelfStatusEnum.OFFLINE.getValue());
        }
        update(spu);
    }
}
