package com.zt.plat.module.base.service.base;

import cn.hutool.core.collection.CollUtil;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.module.base.controller.admin.base.vo.CompanyRelativityPageReqVO;
import com.zt.plat.module.base.controller.admin.base.vo.CompanyRelativityRespVO;
import com.zt.plat.module.base.controller.admin.base.vo.CompanyRelativitySaveReqVO;
import com.zt.plat.module.base.dal.dataobject.base.CompanyRelaDeptDO;
import com.zt.plat.module.base.dal.dataobject.base.CompanyRelativityDO;
import com.zt.plat.module.base.dal.mysql.base.CompanyRelativityMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.module.base.enums.ErrorCodeConstants.COMPANY_RELATIVITY_NOT_EXISTS;

/**
 * 公司关系 Service 实现类
 *
 * @author 后台管理
 */
@Service
@Validated
public class CompanyRelativityServiceImpl implements CompanyRelativityService {

    @Resource
    private CompanyRelativityMapper companyRelativityMapper;

    @Override
    public CompanyRelativityRespVO createCompanyRelativity(CompanyRelativitySaveReqVO createReqVO) {
        // 插入
        CompanyRelativityDO companyRelativity = BeanUtils.toBean(createReqVO, CompanyRelativityDO.class);
        companyRelativityMapper.insert(companyRelativity);
        // 返回
        return BeanUtils.toBean(companyRelativity, CompanyRelativityRespVO.class);
    }

    @Override
    public void updateCompanyRelativity(CompanyRelativitySaveReqVO updateReqVO) {
        // 校验存在
        validateCompanyRelativityExists(updateReqVO.getId());
        // 更新
        CompanyRelativityDO updateObj = BeanUtils.toBean(updateReqVO, CompanyRelativityDO.class);
        companyRelativityMapper.updateById(updateObj);
    }

    @Override
    public void deleteCompanyRelativity(Long id) {
        // 校验存在
        validateCompanyRelativityExists(id);
        // 删除
        companyRelativityMapper.deleteById(id);
    }

    @Override
    public void deleteCompanyRelativityListByIds(List<Long> ids) {
        // 校验存在
        validateCompanyRelativityExists(ids);
        // 删除
        companyRelativityMapper.removeByIds(ids);
    }

    private void validateCompanyRelativityExists(List<Long> ids) {
        List<CompanyRelativityDO> list = companyRelativityMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(COMPANY_RELATIVITY_NOT_EXISTS);
        }
    }

    private void validateCompanyRelativityExists(Long id) {
        if (companyRelativityMapper.selectById(id) == null) {
            throw exception(COMPANY_RELATIVITY_NOT_EXISTS);
        }
    }

    @Override
    public CompanyRelativityDO getCompanyRelativity(Long id) {
        return companyRelativityMapper.selectById(id);
    }

    @Override
    public PageResult<CompanyRelaDeptDO> getCompanyRelativityPage(CompanyRelativityPageReqVO pageReqVO) {
        // 获取分页数据
        List<CompanyRelaDeptDO> list = companyRelativityMapper.getPageByReq(pageReqVO);
        if (list == null) {
            list = CollUtil.newArrayList();
        }
        
        // 构建树形结构
//        List<CompanyRelaDeptDO> treeList = buildTree(list);
        
        // 分页处理
        int pageNo = pageReqVO.getPageNo();
        int pageSize = pageReqVO.getPageSize();
        int total = list.size();
        
        // 计算分页起始和结束位置
        int fromIndex = (pageNo - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);
        
        // 如果起始位置超出范围，则返回空列表
        if (fromIndex >= total) {
            return new PageResult<>(new ArrayList<>(), (long) total);
        }
        
        // 截取当前页数据
        List<CompanyRelaDeptDO> pageList = list.subList(fromIndex, toIndex);

        return new PageResult<>(pageList, (long) total);
    }

    @Override
    public List<CompanyRelativityRespVO> createOrUpdataCompanyList(List<CompanyRelativitySaveReqVO> createReqVOS) {
        if (CollUtil.isEmpty(createReqVOS)) {
            return null;
        }
        
        List<CompanyRelativityDO> insertList = new ArrayList<>();
        List<CompanyRelativityDO> updateList = new ArrayList<>();
        
        // 分离需要插入和更新的数据
        for (CompanyRelativitySaveReqVO createReqVO : createReqVOS) {
            if (createReqVO.getId() == null) {
                // 插入
                CompanyRelativityDO companyRelativity = BeanUtils.toBean(createReqVO, CompanyRelativityDO.class);
                insertList.add(companyRelativity);
            } else {
                // 校验存在
                validateCompanyRelativityExists(createReqVO.getId());
                // 更新
                CompanyRelativityDO updateObj = BeanUtils.toBean(createReqVO, CompanyRelativityDO.class);
                updateList.add(updateObj);
            }
        }
        
        // 批量插入
        if (CollUtil.isNotEmpty(insertList)) {
            companyRelativityMapper.insertBatch(insertList);
        }
        
        // 批量更新
        if (CollUtil.isNotEmpty(updateList)) {
            companyRelativityMapper.updateBatch(updateList);
        }

        return BeanUtils.toBean(createReqVOS, CompanyRelativityRespVO.class);
    }

    private List<CompanyRelaDeptDO> buildTree(List<CompanyRelaDeptDO> list) {
        // 创建一个map用于存储所有节点，key为id，value为节点对象
        Map<Long, CompanyRelaDeptDO> nodeMap = new HashMap<>();
        for (CompanyRelaDeptDO node : list) {
            nodeMap.put(node.getId(), node);
        }

        // 创建结果列表
        List<CompanyRelaDeptDO> result = new ArrayList<>();

        // 遍历所有节点，建立父子关系
        for (CompanyRelaDeptDO node : list) {
            Long parentId = node.getParentId();
            if (parentId == null || parentId == 0) {
                // 如果没有父节点或者父节点为0，则为根节点
                result.add(node);
            } else {
                // 如果有父节点，则将其添加到父节点的子节点列表中
                CompanyRelaDeptDO parent = nodeMap.get(parentId);
                if (parent != null) {
                    if (parent.getChildrens() == null) {
                        parent.setChildrens(new ArrayList<>());
                    }
                    parent.getChildrens().add(node);
                }
            }
        }

        return result;
    }

}