package com.ssyf.module.robot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssyf.common.security.domain.ClientInfo;
import com.ssyf.common.security.helper.ClientContextHelper;
import com.ssyf.common.web.apicode.ApiCodeUser;
import com.ssyf.common.web.error.ServiceRuntimeException;
import com.ssyf.module.robot.domain.entity.RRobotConsumptionRecord;
import com.ssyf.module.robot.domain.query.RRobotConsumptionRecordQuery;
import com.ssyf.module.robot.service.RRobotConsumptionRecordService;
import com.ssyf.module.robot.mapper.RRobotConsumptionRecordMapper;
import com.ssyf.plugs.mysql.helper.MybatisPlusHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
* @author ELSA
* @description 针对表【r_robot_consumption_record(机器人消费记录表)】的数据库操作Service实现
* @createDate 2025-12-18 10:00:17
*/
@Service
public class RRobotConsumptionRecordServiceImpl extends ServiceImpl<RRobotConsumptionRecordMapper, RRobotConsumptionRecord>
    implements RRobotConsumptionRecordService{

    @Override
    public RRobotConsumptionRecord addOne(RRobotConsumptionRecordQuery query) {
        if(StrUtil.isBlank(query.getRobotUuid())){
            ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode() , "机器人账号不能为空");
        }
        if(StrUtil.isBlank(query.getRobotAccount())){
            ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode() , "机器人登录账号不能为空");
        }
        if(query.getConsumptionAmount() == null){
            ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode() , "消费金额不能为空");
        }

        RRobotConsumptionRecord consumptionRecord = BeanUtil.toBean(query ,RRobotConsumptionRecord.class);
        consumptionRecord.setUuid(IdUtil.simpleUUID());
        consumptionRecord.setCreateTime(LocalDateTime.now());
        consumptionRecord.setUpdateTime(LocalDateTime.now());

        if(ClientContextHelper.isLogin()){
            ClientInfo clientInfo = ClientContextHelper.getClientInfo();
            consumptionRecord.setCreator(clientInfo.getNickname());
            consumptionRecord.setCreatorUuid(clientInfo.getId().toString());
        }else{
            consumptionRecord.setCreator("系统");
            consumptionRecord.setCreatorUuid("system");
        }

        this.save(consumptionRecord);
        return consumptionRecord;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeByUid(String uid) {
        checkedExistAndGet(uid);
        this.remove(createBaseWrapper(null).eq(RRobotConsumptionRecord::getUuid, uid));
    }

    @Override
    public void removeBatchByUids(List<String> uids) {
        this.remove(createBaseWrapper(null).in(RRobotConsumptionRecord::getUuid, uids));
    }

    @Override
    public void updateByUid(String uid, RRobotConsumptionRecordQuery query) {
        this.checkedExistAndGet(uid);
        //不能更新uuid，和id
        query.setUuid(null);
        RRobotConsumptionRecord update = BeanUtil.toBean(query ,RRobotConsumptionRecord.class);
        update.setUpdateTime(LocalDateTime.now());
        LambdaQueryWrapper<RRobotConsumptionRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RRobotConsumptionRecord::getUuid, uid);
        this.update(update , wrapper);
    }

    @Override
    public RRobotConsumptionRecord getOneByUid(String uid) {
        return this.getOne(createBaseWrapper(null).eq(RRobotConsumptionRecord::getUuid, uid));
    }

    @Override
    public PageInfo<RRobotConsumptionRecord> getPage(RRobotConsumptionRecordQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        return PageInfo.of(this.list(createBaseWrapper(query)));
    }

    @Override
    public List<RRobotConsumptionRecord> getList(RRobotConsumptionRecordQuery query) {
        return this.list(createBaseWrapper(query));
    }

    @Override
    public RRobotConsumptionRecord checkedExistAndGet(String uid) {
        RRobotConsumptionRecord old = this.getOne(createBaseWrapper(null).eq(RRobotConsumptionRecord::getUuid, uid));
        if (old == null) {
            ServiceRuntimeException.throw0(ApiCodeUser.PARAMETER_ERROR.getCode(), "消费记录不存在");
        }
        return old;
    }

    @Override
    public Integer countBy(RRobotConsumptionRecordQuery query) {
        return this.count(createBaseWrapper(query));
    }

    @Override
    public Integer countDistinctAnchors(String robotUuid, LocalDateTime startTime, LocalDateTime endTime) {
        // 使用 QueryWrapper 进行 count(distinct anchor_id) 查询
        QueryWrapper<RRobotConsumptionRecord> wrapper = new QueryWrapper<>();
        wrapper.select("count(distinct anchor_id) as total")
                .eq("robot_uuid", robotUuid)
                .ge(startTime != null, "create_time", startTime)
                .le(endTime != null, "create_time", endTime);

        // 注意：getMap返回的是 {total=数量}createTime
        Map<String, Object> map = this.getMap(wrapper);
        if (map != null && map.get("total") != null) {
            return Integer.parseInt(map.get("total").toString());
        }
        return 0;
    }

    @Override
    public Integer countGiftsToAnchor(String robotUuid, String anchorId, LocalDateTime startTime, LocalDateTime endTime) {
        LambdaQueryWrapper<RRobotConsumptionRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RRobotConsumptionRecord::getRobotUuid, robotUuid)
                .eq(RRobotConsumptionRecord::getAnchorId, anchorId)
                .ge(startTime != null, RRobotConsumptionRecord::getCreateTime, startTime)
                .le(endTime != null, RRobotConsumptionRecord::getCreateTime, endTime);
        return this.count(wrapper);
    }

    private LambdaQueryWrapper<RRobotConsumptionRecord> createBaseWrapper(RRobotConsumptionRecordQuery query) {
        LambdaQueryWrapper<RRobotConsumptionRecord> wrapper = new LambdaQueryWrapper<>();
        if (query == null) {
            return wrapper;
        }
        wrapper.eq(StrUtil.isNotBlank(query.getRobotGroupUuid()) , RRobotConsumptionRecord::getRobotGroupUuid, query.getRobotGroupUuid());
        wrapper.eq(StrUtil.isNotBlank(query.getRobotGroupName()) , RRobotConsumptionRecord::getRobotGroupName , query.getRobotGroupName());

        wrapper.like(StrUtil.isNotBlank(query.getRobotNickName()) , RRobotConsumptionRecord::getRobotNickName, query.getRobotNickName());
        wrapper.like(StrUtil.isNotBlank(query.getGiftName()), RRobotConsumptionRecord::getGiftName, query.getGiftName());
        wrapper.like(StrUtil.isNotBlank(query.getGiftId()), RRobotConsumptionRecord::getGiftId, query.getGiftId());
        wrapper.like(query.getGiftQuantity() != null, RRobotConsumptionRecord::getGiftQuantity, query.getGiftQuantity());
        wrapper.like(query.getGiftTotalPrice() != null, RRobotConsumptionRecord::getGiftTotalPrice, query.getGiftTotalPrice());
        wrapper.like(StrUtil.isNotBlank(query.getAnchorId()), RRobotConsumptionRecord::getAnchorId, query.getAnchorId());
        wrapper.like(StrUtil.isNotBlank(query.getAnchorName()), RRobotConsumptionRecord::getAnchorName, query.getAnchorName());
        wrapper.like(StrUtil.isNotBlank(query.getRoomId()), RRobotConsumptionRecord::getRoomId, query.getRoomId());
        wrapper.like(StrUtil.isNotBlank(query.getRoomName()), RRobotConsumptionRecord::getRoomName, query.getRoomName());
        wrapper.like(StrUtil.isNotBlank(query.getAnchorAvatar()), RRobotConsumptionRecord::getAnchorAvatar, query.getAnchorAvatar());

        wrapper.like(StrUtil.isNotBlank(query.getUuid()), RRobotConsumptionRecord::getUuid, query.getUuid());
        wrapper.like(StrUtil.isNotBlank(query.getRobotUuid()), RRobotConsumptionRecord::getRobotUuid, query.getRobotUuid());
        wrapper.like(StrUtil.isNotBlank(query.getRobotAccount()), RRobotConsumptionRecord::getRobotAccount, query.getRobotAccount());
        wrapper.eq(query.getConsumptionAmount() != null, RRobotConsumptionRecord::getConsumptionAmount, query.getConsumptionAmount());
        wrapper.ge(query.getConsumptionTimeStart() != null, RRobotConsumptionRecord::getConsumptionTime, query.getConsumptionTimeStart());
        wrapper.le(query.getConsumptionTimeEnd() != null, RRobotConsumptionRecord::getConsumptionTime, query.getConsumptionTimeEnd());
        wrapper.like(StrUtil.isNotBlank(query.getConsumptionMethod()), RRobotConsumptionRecord::getConsumptionMethod, query.getConsumptionMethod());
        wrapper.like(StrUtil.isNotBlank(query.getConsumptionInfo()), RRobotConsumptionRecord::getConsumptionInfo, query.getConsumptionInfo());
        wrapper.like(StrUtil.isNotBlank(query.getNotes()), RRobotConsumptionRecord::getNotes, query.getNotes());
        wrapper.like(StrUtil.isNotBlank(query.getSourceId()), RRobotConsumptionRecord::getSourceId, query.getSourceId());
        wrapper.ge(query.getCreateTimeStart() != null, RRobotConsumptionRecord::getCreateTime, query.getCreateTimeStart());
        wrapper.le(query.getCreateTimeEnd() != null, RRobotConsumptionRecord::getCreateTime, query.getCreateTimeEnd());
        wrapper.like(StrUtil.isNotBlank(query.getCreator()), RRobotConsumptionRecord::getCreator, query.getCreator());
        wrapper.ge(query.getUpdateTimeStart() != null, RRobotConsumptionRecord::getUpdateTime, query.getUpdateTimeStart());
        wrapper.le(query.getUpdateTimeEnd() != null, RRobotConsumptionRecord::getUpdateTime, query.getUpdateTimeEnd());
        
        // 示例排序逻辑
        if (CollectionUtil.isNotEmpty(query.getSorts())) {
            MybatisPlusHelper.orderAndIgnoreError(RRobotConsumptionRecord.class, wrapper, query.getSorts());
        } else {
            wrapper.orderByDesc(RRobotConsumptionRecord::getCreateTime);
        }
        return wrapper;
    }
}




