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

import cn.hutool.core.bean.BeanUtil;
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.ProductUnitExportDTO;
import com.czg.product.dto.ShopProdUnitDTO;
import com.czg.product.entity.ShopProdUnit;
import com.czg.product.enums.UnitTypeEnum;
import com.czg.product.service.ShopProdUnitService;
import com.czg.sa.StpKit;
import com.czg.service.product.mapper.ShopProdUnitMapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;

import java.util.List;


/**
 * 商品单位Service实现类
 *
 * @author Tankaikai tankaikai@aliyun.com
 * @since 1.0 2025-02-10
 */
@Service
public class ShopProdUnitServiceImpl extends ServiceImpl<ShopProdUnitMapper, ShopProdUnit> implements ShopProdUnitService {

    private QueryWrapper buildQueryWrapper(ShopProdUnitDTO param) {
        QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
        if (StrUtil.isNotEmpty(param.getName())) {
            queryWrapper.like(ShopProdUnit::getName, param.getName());
        }
        Long shopId = StpKit.USER.getShopId(0L);
        queryWrapper.and(q -> {
            q.eq(ShopProdUnit::getShopId, shopId).or(q1 -> {
                q1.eq(ShopProdUnit::getShopId, 1L);
            }).or(q2 -> {
                q2.eq(ShopProdUnit::getIsSystem, SystemConstants.OneZero.ONE);
            });
        });
        queryWrapper.orderBy(ShopProdUnit::getId, false);
        return queryWrapper;
    }

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

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

    @Override
    public void exportShopProdUnit(ShopProdUnitDTO param, HttpServletResponse response) {
        QueryWrapper queryWrapper = buildQueryWrapper(param);
        queryWrapper.eq(ShopProdUnit::getStatus,SystemConstants.OneZero.ONE);
        List<ProductUnitExportDTO> unitExportDTOList = listAs(queryWrapper, ProductUnitExportDTO.class);
        ExcelExportUtil.exportToResponse(unitExportDTOList, ProductUnitExportDTO.class, "单位列表", response);
    }

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

    @Override
    public Long addShopProdUnit(ShopProdUnitDTO dto) {
        Long shopId = StpKit.USER.getShopId(0L);
        boolean exists = super.exists(query().eq(ShopProdUnit::getName, dto.getName())
                .and(q -> {
                    q.eq(ShopProdUnit::getShopId, shopId).or(q1 -> {
                        q1.eq(ShopProdUnit::getShopId, 1L);
                    }).or(q2 -> {
                        q2.eq(ShopProdUnit::getIsSystem, SystemConstants.OneZero.ONE);
                    });
                }));
        if (exists) {
            throw new CzgException("单位名称已存在");
        }
        ShopProdUnit entity = BeanUtil.copyProperties(dto, ShopProdUnit.class);
        // 单位类型 number-计数 weight-记重
        entity.setUnitType(UnitTypeEnum.NUMBER.value());
        // 单位来源 1-系统预设 0-商家创建
        entity.setIsSystem(SystemConstants.OneZero.ZERO);
        entity.setStatus(SystemConstants.OneZero.ONE);
        entity.setShopId(shopId);
        super.save(entity);
        return entity.getId();
    }

    @Override
    public void updateShopProdUnit(ShopProdUnitDTO dto) {
        checkShopProdUnit(dto.getId());
        Long shopId = StpKit.USER.getShopId(0L);
        dto.setShopId(shopId);
        boolean exists = super.exists(query().eq(ShopProdUnit::getName, dto.getName())
                .ne(ShopProdUnit::getId, dto.getId())
                .and(q -> {
                    q.eq(ShopProdUnit::getShopId, shopId).or(q1 -> {
                        q1.eq(ShopProdUnit::getShopId, 1L);
                    }).or(q2 -> {
                        q2.eq(ShopProdUnit::getIsSystem, SystemConstants.OneZero.ONE);
                    });
                })
        );
        if (exists) {
            throw new CzgException("单位名称已存在");
        }
        ShopProdUnit entity = BeanUtil.copyProperties(dto, ShopProdUnit.class);
        super.updateById(entity);
    }

    @Override
    public void deleteShopProdUnit(Long id) {
        checkShopProdUnit(id);
        Long shopId = StpKit.USER.getShopId(0L);
        super.remove(query().eq(ShopProdUnit::getId, id).eq(ShopProdUnit::getShopId, shopId));
    }

    @Override
    public void disableShopProdUnit(Long id) {
        checkShopProdUnit(id);
        Long shopId = StpKit.USER.getShopId(0L);
        UpdateChain.of(ShopProdUnit.class)
                .set(ShopProdUnit::getStatus, SystemConstants.OneZero.ZERO)
                .eq(ShopProdUnit::getId, id)
                .eq(ShopProdUnit::getShopId, shopId)
                .update();
    }

    @Override
    public void enableShopProdUnit(Long id) {
        checkShopProdUnit(id);
        Long shopId = StpKit.USER.getShopId(0L);
        UpdateChain.of(ShopProdUnit.class)
                .set(ShopProdUnit::getStatus,SystemConstants.OneZero.ONE)
                .eq(ShopProdUnit::getId, id)
                .eq(ShopProdUnit::getShopId, shopId)
                .update();
    }

    private void checkShopProdUnit(Long id) {
        Long shopId = StpKit.USER.getShopId(0L);
        ShopProdUnit entity = super.getById(id);
        if (entity == null) {
            throw new CzgException("单位信息不存在");
        }
        if (SystemConstants.OneZero.ONE == entity.getIsSystem()) {
            throw new CzgException("系统预设单位不可操作");
        }
        if (!shopId.equals(entity.getShopId())) {
            throw new CzgException("公共单位不可操作");
        }
    }
}
