package com.czg.service.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.czg.constants.SystemConstants;
import com.czg.excel.ExcelExportUtil;
import com.czg.exception.CzgException;
import com.czg.product.dto.ProductCategoryExportDTO;
import com.czg.product.dto.ShopProdCategoryDTO;
import com.czg.product.entity.ShopProdCategory;
import com.czg.product.service.ProductService;
import com.czg.product.service.ShopProdCategoryService;
import com.czg.sa.StpKit;
import com.czg.service.product.mapper.ShopProdCategoryMapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.context.annotation.Lazy;

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

/**
 * 店铺商品分类
 *
 * @author Tankaikai tankaikai@aliyun.com
 * @since 1.0 2025-02-10
 */
@DubboService
public class ShopProdCategoryServiceImpl extends ServiceImpl<ShopProdCategoryMapper, ShopProdCategory> implements ShopProdCategoryService {

    @Resource
    @Lazy
    private ProductService productService;

    private QueryWrapper buildQueryWrapper(ShopProdCategoryDTO param) {
        QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
        if (StrUtil.isNotEmpty(param.getName())) {
            queryWrapper.like(ShopProdCategory::getName, param.getName());
        }
        if (param.getShopId() == null) {
            Long shopId = StpKit.USER.getShopId(0L);
            param.setShopId(shopId);
        }
        queryWrapper.eq(ShopProdCategory::getShopId, param.getShopId());
        queryWrapper.orderBy(ShopProdCategory::getSort, true);
        queryWrapper.orderBy(ShopProdCategory::getId, false);
        return queryWrapper;
    }

    @Override
    public Page<ShopProdCategoryDTO> getShopProdCategoryPage(ShopProdCategoryDTO param) {
        QueryWrapper queryWrapper = buildQueryWrapper(param);
        return super.pageAs(PageUtil.buildPage(), queryWrapper, ShopProdCategoryDTO.class);
    }

    @Override
    public List<ShopProdCategoryDTO> getShopProdCategoryList(ShopProdCategoryDTO param) {
        QueryWrapper queryWrapper = buildQueryWrapper(param);
        queryWrapper.eq(ShopProdCategory::getStatus, SystemConstants.OneZero.ONE);
        return super.listAs(queryWrapper, ShopProdCategoryDTO.class);
    }

    @Override
    public Map<Long, String> getCategoryIdNameMap(Long shopId) {
        QueryWrapper queryWrapper = query().select(ShopProdCategory::getId, ShopProdCategory::getName)
                .eq(ShopProdCategory::getShopId, shopId).eq(ShopProdCategory::getStatus, SystemConstants.OneZero.ONE);
        List<ShopProdCategory> list = list(queryWrapper);
        if (CollUtil.isEmpty(list)) {
            return Map.of();
        }
        return list.stream().collect(Collectors.toMap(ShopProdCategory::getId, ShopProdCategory::getName));
    }

    @Override
    public void exportShopProdCategory(ShopProdCategoryDTO param, HttpServletResponse response) {
        QueryWrapper queryWrapper = buildQueryWrapper(param);
        queryWrapper.eq(ShopProdCategory::getStatus, SystemConstants.OneZero.ONE);
        List<ProductCategoryExportDTO> exportList = listAs(queryWrapper, ProductCategoryExportDTO.class);
        ExcelExportUtil.exportToResponse(exportList, ProductCategoryExportDTO.class, "商品分类列表", response);
    }

    @Override
    public ShopProdCategoryDTO getShopProdCategoryById(Long id) {
        Long shopId = StpKit.USER.getShopId(0L);
        return super.getOneAs(query().eq(ShopProdCategory::getId, id).eq(ShopProdCategory::getShopId, shopId), ShopProdCategoryDTO.class);
    }

    @Override
    public void addShopProdCategory(ShopProdCategoryDTO dto) {
        Long shopId = StpKit.USER.getShopId(0L);
        boolean exists = super.exists(query().eq(ShopProdCategory::getName, dto.getName()).eq(ShopProdCategory::getShopId, shopId));
        if (exists) {
            throw new CzgException("商品分类已存在");
        }
        ShopProdCategory entity = BeanUtil.copyProperties(dto, ShopProdCategory.class);
        // 简称
        entity.setShortName(dto.getName());
        if (entity.getStatus() == null) {
            entity.setStatus(SystemConstants.OneZero.ONE);
        }
        entity.setPid(0L);
        entity.setShopId(shopId);
        super.save(entity);
        dto.setId(entity.getId());
    }

    @Override
    public void updateShopProdCategory(ShopProdCategoryDTO dto) {
        Long shopId = StpKit.USER.getShopId();
        dto.setShopId(shopId);
        boolean exists = super.exists(query().eq(ShopProdCategory::getName, dto.getName()).eq(ShopProdCategory::getShopId, shopId).ne(ShopProdCategory::getId, dto.getId()));
        if (exists) {
            throw new CzgException("商品分类已存在");
        }
        ShopProdCategory entity = BeanUtil.copyProperties(dto, ShopProdCategory.class);
        entity.setPid(0L);
        super.updateById(entity);
    }

    @Override
    public void deleteShopProdCategory(Long id) {
        Long shopId = StpKit.USER.getShopId(0L);
        super.remove(query().eq(ShopProdCategory::getId, id).eq(ShopProdCategory::getShopId, shopId));
        productService.clearProductCache(id);
    }

    @Override
    public void disableShopProdCategory(Long id) {
        Long shopId = StpKit.USER.getShopId(0L);
        ShopProdCategory prodCategory = new ShopProdCategory();
        prodCategory.setStatus(SystemConstants.OneZero.ZERO);
        update(prodCategory, query().eq(ShopProdCategory::getId, id).eq(ShopProdCategory::getShopId, shopId));
        productService.clearProductCache(id);
    }

    @Override
    public void enableShopProdCategory(Long id) {
        Long shopId = StpKit.USER.getShopId(0L);
        ShopProdCategory prodCategory = new ShopProdCategory();
        prodCategory.setStatus(SystemConstants.OneZero.ONE);
        update(prodCategory, query().eq(ShopProdCategory::getId, id).eq(ShopProdCategory::getShopId, shopId));
        productService.clearProductCache(id);
    }
}