package com.mortals.xhx.module.ent.service.impl;

import com.mortals.framework.model.OrderCol;
import com.mortals.framework.model.PageInfo;
import com.mortals.xhx.base.system.menu.model.MenuEntity;
import com.mortals.xhx.base.system.menu.model.MenuQuery;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.module.ent.model.EntLifeCycleQuery;
import org.springframework.beans.BeanUtils;

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

import org.springframework.stereotype.Service;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.xhx.module.ent.dao.EntLifeCycleDao;
import com.mortals.xhx.module.ent.model.EntLifeCycleEntity;
import com.mortals.xhx.module.ent.service.EntLifeCycleService;
import org.springframework.beans.factory.annotation.Autowired;
import com.mortals.xhx.module.ent.model.EntLifeMatterEntity;
import com.mortals.xhx.module.ent.model.EntLifeMatterQuery;
import com.mortals.xhx.module.ent.service.EntLifeMatterService;
import org.springframework.util.ObjectUtils;

import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

/**
 * EntLifeCycleService
 * 企业生命周期 service实现
 *
 * @author zxfei
 * @date 2025-03-15
 */
@Service("entLifeCycleService")
@Slf4j
public class EntLifeCycleServiceImpl extends AbstractCRUDServiceImpl<EntLifeCycleDao, EntLifeCycleEntity, Long> implements EntLifeCycleService {
    @Autowired
    private EntLifeMatterService entLifeMatterService;

    @Override
    protected void saveBefore(EntLifeCycleEntity entity, Context context) throws AppException {
        super.saveBefore(entity, context);
        if(ObjectUtils.isEmpty(entity.getSort())){
            //求出最大的排序值 +1
            Integer maxSort = this.find(new EntLifeCycleQuery()).stream().map(EntLifeCycleEntity::getSort).max(Integer::max).orElseGet(() -> 0);
            entity.setSort(maxSort + 1);
        }

    }

    @Override
    protected void findAfter(EntLifeCycleEntity params, PageInfo pageInfo, Context context, List<EntLifeCycleEntity> list) throws AppException {
        fillSubData(list);
        super.findAfter(params, pageInfo, context, list);
    }

    @Override
    protected void findAfter(EntLifeCycleEntity params, Context context, List<EntLifeCycleEntity> list) throws AppException {
        fillSubData(list);
        super.findAfter(params, context, list);
    }

    private void fillSubData(List<EntLifeCycleEntity> list) {
        List<Long> idList = list.stream().map(i -> i.getId()).collect(Collectors.toList());
        if (ObjectUtils.isEmpty(idList)) return;
        Map<Long, List<EntLifeMatterEntity>> entLifeMatterListMap = entLifeMatterService
                .find(new EntLifeMatterQuery().lifeCycleIdList(idList)).parallelStream()
                .collect(Collectors.groupingBy(EntLifeMatterEntity::getLifeCycleId));
        list.forEach(item -> item.setEntLifeMatterList(entLifeMatterListMap.get(item.getId())));
    }


    @Override
    protected void saveAfter(EntLifeCycleEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getEntLifeMatterList())) {
            entity.getEntLifeMatterList().stream().peek(item -> {
                item.setLifeCycleId(entity.getId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
            }).count();
            entLifeMatterService.save(entity.getEntLifeMatterList());
        }
        super.saveAfter(entity, context);
    }

    @Override
    protected void updateAfter(EntLifeCycleEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getEntLifeMatterList())) {
            Long[] entLifeMatterIds = entLifeMatterService.find(new EntLifeMatterQuery().lifeCycleId(entity.getId())).stream().map(EntLifeMatterEntity::getId).toArray(Long[]::new);
            entLifeMatterService.remove(entLifeMatterIds, context);
            entity.getEntLifeMatterList().stream().peek(item -> {
                item.setLifeCycleId(entity.getId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
                item.setUpdateUserId(this.getContextUserId(context));
                item.setUpdateTime(new Date());
            }).count();
            entLifeMatterService.save(entity.getEntLifeMatterList());
        }
        super.updateAfter(entity, context);
    }

    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        List<EntLifeMatterEntity> entLifeMatterlist = entLifeMatterService.find(new EntLifeMatterQuery().lifeCycleIdList(Arrays.asList(ids)));
        entLifeMatterService.removeList(entLifeMatterlist, context);
        super.removeAfter(ids, context, result);
    }


    @Override
    public void upOrDown(Long id, Integer type) {
        EntLifeCycleQuery query = new EntLifeCycleQuery();
        query.setOrderColList(Arrays.asList(new OrderCol("sort")));
        query.setOrderKind(OrderCol.ASCENDING);

        List<EntLifeCycleEntity> list = this.find(query);
        EntLifeCycleEntity preEntity = null;
        EntLifeCycleEntity curEntity = null;
        if (type == YesNoEnum.NO.getValue()) {
            //up
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).getId().equals(id) && i > 0) {
                    curEntity = list.get(i);
                    preEntity = list.get(i - 1);
                    break;
                }
            }

        } else {
            //down
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i).getId().equals(id) && i + 1 < list.size()) {
                    curEntity = list.get(i);
                    preEntity = list.get(i + 1);
                    break;
                }
            }
        }

        if (preEntity != null && curEntity != null) {
            //交换
            int temp = preEntity.getSort();
            preEntity.setSort(curEntity.getSort());
            curEntity.setSort(temp);

            this.update(preEntity);
            this.update(curEntity);
        }

    }

}