package cn.iocoder.yudao.module.member.service.storeevaluate;

import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.controller.admin.screen.vo.StoreEvaluateVO;
import cn.iocoder.yudao.module.member.controller.admin.storeevaluate.vo.StoreEvaluatePageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.storeevaluate.vo.StoreEvaluateSaveReqVO;
import cn.iocoder.yudao.module.member.controller.app.storeevaluate.vo.AppStoreEvaluateSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.storeevaluate.StoreEvaluateDO;
import cn.iocoder.yudao.module.member.dal.mysql.storeevaluate.StoreEvaluateMapper;
import cn.iocoder.yudao.module.member.util.MemberConstants;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.STORE_EVALUATE_NOT_EXISTS;


/**
 * 店铺评价 Service 实现类
 *
 * @author 开发账号
 */
@Service
@Validated
public class StoreEvaluateServiceImpl implements StoreEvaluateService {

    @Resource
    private StoreEvaluateMapper storeEvaluateMapper;

    @Override
    public Long createStoreEvaluate(StoreEvaluateSaveReqVO createReqVO) {
        // 插入
        StoreEvaluateDO storeEvaluate = BeanUtils.toBean(createReqVO, StoreEvaluateDO.class);
        storeEvaluateMapper.insert(storeEvaluate);
        // 返回
        return storeEvaluate.getId();
    }

    @Override
    public void updateStoreEvaluate(StoreEvaluateSaveReqVO updateReqVO) {
        // 校验存在
        validateStoreEvaluateExists(updateReqVO.getId());
        // 更新
        StoreEvaluateDO updateObj = BeanUtils.toBean(updateReqVO, StoreEvaluateDO.class);
        storeEvaluateMapper.updateById(updateObj);
    }

    @Override
    public void deleteStoreEvaluate(Long id) {
        // 校验存在
        validateStoreEvaluateExists(id);
        // 删除
        storeEvaluateMapper.deleteById(id);
    }

    private void validateStoreEvaluateExists(Long id) {
        if (storeEvaluateMapper.selectById(id) == null) {
            throw exception(STORE_EVALUATE_NOT_EXISTS);
        }
    }

    @Override
    public StoreEvaluateDO getStoreEvaluate(Long id) {
        return storeEvaluateMapper.selectById(id);
    }

    @Override
    public PageResult<StoreEvaluateDO> getStoreEvaluatePage(StoreEvaluatePageReqVO pageReqVO) {
        return storeEvaluateMapper.selectPage(pageReqVO);
    }

    @Override
    public Boolean saveOrUpdate(AppStoreEvaluateSaveReqVO createReqVO) {
        StoreEvaluateDO storeEvaluateDO = storeEvaluateMapper.selectOne(Wrappers.<StoreEvaluateDO>lambdaQuery()
                .eq(StoreEvaluateDO::getUserId, createReqVO.getUserId())
                .eq(createReqVO.getStoreId() != null,StoreEvaluateDO::getStoreId,createReqVO.getStoreId())
                .last(MemberConstants.LIMIT_ONE));
        if(storeEvaluateDO == null){
            StoreEvaluateDO add = new StoreEvaluateDO();
            BeanUtil.copyProperties(createReqVO,add);
            return  storeEvaluateMapper.insert(add)>0;
        }else {
            BeanUtil.copyProperties(createReqVO,storeEvaluateDO);
            return  storeEvaluateMapper.updateById(storeEvaluateDO)>0;
        }
    }

    @Override
    public StoreEvaluateDO selectByUserId(Long storeId) {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        if(loginUserId == null ){
            return new StoreEvaluateDO();
        }
        StoreEvaluateDO storeEvaluateDO = storeEvaluateMapper.selectOne(Wrappers.<StoreEvaluateDO>lambdaQuery()
                .eq(StoreEvaluateDO::getUserId, loginUserId)
                .eq(storeId != null,StoreEvaluateDO::getStoreId,storeId)
                .last(MemberConstants.LIMIT_ONE));
        return storeEvaluateDO;
    }

    @Override
    public StoreEvaluateVO getEvaluate(Long storeId) {
        StoreEvaluateVO storeEvaluateVO = new StoreEvaluateVO();
        LambdaQueryWrapper<StoreEvaluateDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(storeId != null,StoreEvaluateDO::getStoreId,storeId);
        Long good = storeEvaluateMapper.selectCount(queryWrapper
                .gt(StoreEvaluateDO::getEvaluate, MemberConstants.GOOD_EVALUATE)
               );
        Long total = storeEvaluateMapper.selectCount(queryWrapper);
        storeEvaluateVO.setNum(total);
        if(total == 0){
            storeEvaluateVO.setGood("0.00%");
            storeEvaluateVO.setBad("0.00%");
        }else{
            BigDecimal goodPercent = new BigDecimal(good).divide(new BigDecimal(total), 4, BigDecimal.ROUND_HALF_UP);
            BigDecimal badPercent = BigDecimal.ONE.subtract(goodPercent);
            storeEvaluateVO.setGood(goodPercent.multiply(new BigDecimal("100")).setScale(2,BigDecimal.ROUND_HALF_UP).toString()+"%");
            storeEvaluateVO.setBad(badPercent.multiply(new BigDecimal("100")).setScale(2,BigDecimal.ROUND_HALF_UP).toString()+"%");
        }
        return storeEvaluateVO;
    }
}