package cn.iocoder.yudao.module.tkdata.service.employeebigbrother;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.tkdata.controller.admin.employeebigbrother.vo.EmployeeBigBrotherPageReqVO;
import cn.iocoder.yudao.module.tkdata.controller.admin.employeebigbrother.vo.EmployeeBigBrotherSaveReqVO;
import cn.iocoder.yudao.module.tkdata.controller.admin.employeehosts.vo.CompletedRateVO;
import cn.iocoder.yudao.module.tkdata.dal.dataobject.bigbrother.BigBrotherDO;
import cn.iocoder.yudao.module.tkdata.dal.dataobject.employeebigbrother.EmployeeBigBrotherDO;
import cn.iocoder.yudao.module.tkdata.dal.dataobject.employeehosts.EmployeeHostsDO;
import cn.iocoder.yudao.module.tkdata.dal.mysql.bigbrother.BigBrotherMapper;
import cn.iocoder.yudao.module.tkdata.dal.mysql.employeebigbrother.EmployeeBigBrotherMapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.generator.IFill;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;


import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.yudao.module.tkdata.enums.ErrorCodeConstants.EMPLOYEE_BIG_BROTHER_NOT_EXISTS;

/**
 * 大哥数据员工业务 Service 实现类
 *
 * @author ziin
 */
@Service
@Validated
public class EmployeeBigBrotherServiceImpl implements EmployeeBigBrotherService {

    @Resource
    private EmployeeBigBrotherMapper employeeBigBrotherMapper;

    @Resource
    private BigBrotherMapper bigBrotherMapper;

    @Override
    public Integer createEmployeeBigBrother(EmployeeBigBrotherSaveReqVO createReqVO) {
        // 插入
        EmployeeBigBrotherDO employeeBigBrother = BeanUtils.toBean(createReqVO, EmployeeBigBrotherDO.class);
        employeeBigBrotherMapper.insert(employeeBigBrother);
        // 返回
        return employeeBigBrother.getId();
    }

    @Override
    public void updateEmployeeBigBrother(EmployeeBigBrotherSaveReqVO updateReqVO) {
        // 校验存在
        validateEmployeeBigBrotherExists(updateReqVO.getId());
        // 更新
        Long tenantId = TenantContextHolder.getTenantId();
        EmployeeBigBrotherDO updateObj = BeanUtils.toBean(updateReqVO, EmployeeBigBrotherDO.class);
        LambdaUpdateWrapper<EmployeeBigBrotherDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(EmployeeBigBrotherDO::getOperationStatus, updateReqVO.getOperationStatus());
        updateWrapper.eq(EmployeeBigBrotherDO::getUserId, updateReqVO.getUserId());
        updateWrapper.eq(EmployeeBigBrotherDO::getDisplayId,updateObj.getDisplayId());
        updateWrapper.eq(EmployeeBigBrotherDO::getTenantId, tenantId);
        employeeBigBrotherMapper.update(updateObj,updateWrapper);
    }

    @Override
    public void deleteEmployeeBigBrother(Integer id) {
        // 校验存在
        validateEmployeeBigBrotherExists(id);
        // 删除
        employeeBigBrotherMapper.deleteById(id);
    }

    @Override
        public void deleteEmployeeBigBrotherListByIds(List<Integer> ids) {
        // 校验存在
        validateEmployeeBigBrotherExists(ids);
        // 删除
        employeeBigBrotherMapper.deleteByIds(ids);
        }

    private void validateEmployeeBigBrotherExists(List<Integer> ids) {
        List<EmployeeBigBrotherDO> list = employeeBigBrotherMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(EMPLOYEE_BIG_BROTHER_NOT_EXISTS);
        }
    }

    private void validateEmployeeBigBrotherExists(Integer id) {
        if (employeeBigBrotherMapper.selectById(id) == null) {
            throw exception(EMPLOYEE_BIG_BROTHER_NOT_EXISTS);
        }
    }

    @Override
    public EmployeeBigBrotherDO getEmployeeBigBrother(Integer id) {
        return employeeBigBrotherMapper.selectById(id);
    }

    @Override
    public PageResult<EmployeeBigBrotherDO> getEmployeeBigBrotherPage(EmployeeBigBrotherPageReqVO pageReqVO) {
        pageReqVO.setTenantId(TenantContextHolder.getTenantId());
        IPage<EmployeeBigBrotherDO> iPage = new Page<>(pageReqVO.getPageNo(),pageReqVO.getPageSize());
        IPage<EmployeeBigBrotherDO> bigBrotherDOIPage = employeeBigBrotherMapper.selectPage(iPage, pageReqVO);
        return new  PageResult<>(bigBrotherDOIPage.getRecords(),bigBrotherDOIPage.getTotal());
    }

    @Override
    public Boolean allocationEmployeeBigBrother(List<EmployeeBigBrotherSaveReqVO> createReqVO) {

        ArrayList<EmployeeBigBrotherDO> employeeBigBrotherDOS = new ArrayList<>();
        ArrayList<BigBrotherDO> bigBrotherDOS = new ArrayList<>();
        for (EmployeeBigBrotherSaveReqVO employeeBigBrotherSaveReqVO : createReqVO) {
            BigBrotherDO bigBrotherDO = new BigBrotherDO();
            bigBrotherDO.setId(employeeBigBrotherSaveReqVO.getId());
            bigBrotherDO.setUserId(employeeBigBrotherSaveReqVO.getUserId());
            bigBrotherDO.setIsAssigned(1);
            bigBrotherDOS.add(bigBrotherDO);
            EmployeeBigBrotherDO employeeBigBrotherDO = BeanUtils.toBean(employeeBigBrotherSaveReqVO, EmployeeBigBrotherDO.class);
            employeeBigBrotherDO.setOperationStatus(0);
            employeeBigBrotherDO.setId(null);
            employeeBigBrotherDOS.add(employeeBigBrotherDO);
        }
        employeeBigBrotherMapper.insertBatch(employeeBigBrotherDOS);
        return bigBrotherMapper.updateBatch(bigBrotherDOS);

    }

    @Override
    public PageResult<EmployeeBigBrotherDO> getEmployeeBigBrotherPageWithSelf(EmployeeBigBrotherPageReqVO pageReqVO) {
        pageReqVO.setTenantId(TenantContextHolder.getTenantId());
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        if (loginUser!= null){
            pageReqVO.setUserId(loginUser.getId());
            IPage<EmployeeBigBrotherDO> iPage = new Page<>(pageReqVO.getPageNo(),pageReqVO.getPageSize());
            IPage<EmployeeBigBrotherDO> bigBrotherDOIPage = employeeBigBrotherMapper.selectPagewithSelf(iPage, pageReqVO);
            return new  PageResult<>(bigBrotherDOIPage.getRecords(),bigBrotherDOIPage.getTotal());
        }else{
            return null;
        }
    }

    @Override
    public void batchUpdateEmployeeBigBrother(List<EmployeeBigBrotherSaveReqVO> updateReqVO) {
        ArrayList<EmployeeBigBrotherDO> employeeBigBrotherDOS = new ArrayList<>();
        for (EmployeeBigBrotherSaveReqVO employeeBigBrotherSaveReqVO : updateReqVO) {
            employeeBigBrotherDOS.add(BeanUtils.toBean(employeeBigBrotherSaveReqVO, EmployeeBigBrotherDO.class));
        }
        employeeBigBrotherMapper.updateBatch(employeeBigBrotherDOS);
    }

    @Override
    public List<CompletedRateVO> getEmployeeBrotherCompleteBarChart(List<Long> userIdList, Integer days) {

        List<CompletedRateVO> dbList = employeeBigBrotherMapper.selectEmployeeBrotherCompleteBarChart(userIdList,days);


        try {
            // 2. 转 Map，key 是 userId
            Map<Long, CompletedRateVO> dbMap = dbList.stream()
                    .collect(Collectors.toMap(
                            CompletedRateVO::getUserId,
                            Function.identity(),
                            (oldVal, newVal) -> newVal)); // 重复时保留新的
            // 3. 组装结果
            return userIdList.stream()
                    .map(userId -> dbMap.getOrDefault(userId, new CompletedRateVO(userId, 0))) // 缺数据补0
                    .collect(Collectors.toList());
        } catch (Exception e) {
            ArrayList<CompletedRateVO> nullData = new ArrayList<>();
            for (Long userId : userIdList) {
                nullData.add(new CompletedRateVO(userId, 0));
            }
            return nullData;
        }

    }

    @Override
    public CompletedRateVO getEmployeeHostsCompleteWithSelf(Long loginUserId) {
        return employeeBigBrotherMapper.selectEmployeeBrotherWithOperationStatus(loginUserId);
    }

}