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

import cn.hutool.core.util.StrUtil;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.framework.util.ThreadPool;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.pdu.site.SitePdu;
import com.mortals.xhx.feign.site.ISiteFeign;
import com.mortals.xhx.module.access.dao.AccessDao;
import com.mortals.xhx.module.access.model.AccessEntity;
import com.mortals.xhx.module.access.model.AccessQuery;
import com.mortals.xhx.module.access.model.AccessSystemEntity;
import com.mortals.xhx.module.access.model.AccessSystemQuery;
import com.mortals.xhx.module.access.service.AccessService;
import com.mortals.xhx.module.access.service.AccessSystemService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

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

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;

/**
 * AccessService
 * 区域接入 service实现
 *
 * @author zxfei
 * @date 2024-07-02
 */
@Service("accessService")
@Slf4j
public class AccessServiceImpl extends AbstractCRUDServiceImpl<AccessDao, AccessEntity, Long> implements AccessService {
    @Autowired
    private AccessSystemService accessSystemService;
    @Autowired
    private ISiteFeign siteFeign;
    @Autowired
    private AccessService accessService;
    @Autowired
    private ICacheService cacheService;

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

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

    private void fillSubData(List<AccessEntity> list) {
        List<Long> idList = list.stream().map(i -> i.getId()).collect(Collectors.toList());
        AccessSystemQuery accessSystemQuery = new AccessSystemQuery();
        accessSystemQuery.setAccessIdList(idList);
        Map<Long, List<AccessSystemEntity>> accessSystemListMap = accessSystemService.find(accessSystemQuery).stream().collect(Collectors.groupingBy(AccessSystemEntity::getAccessId));
        list.forEach(item -> item.setAccessSystemList(accessSystemListMap.get(item.getId())));
    }

    @Override
    protected void saveAfter(AccessEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getAccessSystemList())) {
            entity.getAccessSystemList().stream().peek(item -> {
                item.setAccessId(entity.getId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
            }).count();
            accessSystemService.save(entity.getAccessSystemList());

            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    List<SitePdu> statSiteList = accessService.getStatSiteList( new AccessQuery());
                    int total = statSiteList.size();
                    cacheService.set(RedisKey.KEY_SITE_STAT_COUNT_CHCHE, total);
                }
            };
            ThreadPool.getInstance().execute(runnable);
        }
        super.saveAfter(entity, context);
    }

    @Override
    protected void updateAfter(AccessEntity entity, Context context) throws AppException {
        if (!ObjectUtils.isEmpty(entity.getAccessSystemList())) {
            Long[] accessSystemIds = accessSystemService.find(new AccessSystemQuery().accessId(entity.getId())).stream().map(AccessSystemEntity::getId).toArray(Long[]::new);
            accessSystemService.remove(accessSystemIds, context);
            entity.getAccessSystemList().stream().peek(item -> {
                item.setAccessId(entity.getId());
                item.setCreateUserId(this.getContextUserId(context));
                item.setCreateTime(new Date());
                item.setUpdateUserId(this.getContextUserId(context));
                item.setUpdateTime(new Date());
            }).count();
            accessSystemService.save(entity.getAccessSystemList());

            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    List<SitePdu> statSiteList = accessService.getStatSiteList( new AccessQuery());
                    int total = statSiteList.size();
                    cacheService.set(RedisKey.KEY_SITE_STAT_COUNT_CHCHE, total);
                }
            };
            ThreadPool.getInstance().execute(runnable);
        }
        super.updateAfter(entity, context);
    }

    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        List<AccessSystemEntity> accessSystemlist = accessSystemService.find(new AccessSystemQuery().accessIdList(Arrays.asList(ids)));
        accessSystemService.removeList(accessSystemlist, context);
        super.removeAfter(ids, context, result);
    }

    @Override
    public List<SitePdu> getStatSiteList(AccessQuery accessQuery) {
        List<AccessEntity> accessEntities = this.find(accessQuery);
        accessEntities = accessEntities.stream().filter(item -> {
            List<AccessSystemEntity> accessSystemList = item.getAccessSystemList();
            //判断排队机或者评价系统是否开通
            if (ObjectUtils.isEmpty(accessSystemList)) return false;
            List<AccessSystemEntity> collect = accessSystemList.stream().filter(f -> f.getEnabled() == YesNoEnum.YES.getValue()).collect(Collectors.toList());
            if (ObjectUtils.isEmpty(collect)) {
                return false;
            }
            return true;
        }).collect(Collectors.toList());

        List<SitePdu> sitePduList = new ArrayList<>();
        for (AccessEntity accessEntity : accessEntities) {
            if (ObjectUtils.isEmpty(accessEntity.getSiteId())) continue;
            if (accessEntity.getSiteId() == 1L) {
                SitePdu site = new SitePdu();
                site.setId(accessEntity.getSiteId());
                site.setSiteName(accessEntity.getSiteName());
                site.setSiteCode(accessEntity.getSiteCode());
                site.setAreaCode(accessEntity.getAreaCode());
                sitePduList.add(site);
                continue;
            }
            SitePdu sitePdu = new SitePdu();
            sitePdu.setId(accessEntity.getSiteId());
            Rest<List<SitePdu>> sitesRest = siteFeign.getFlatSitesBySiteId(sitePdu);
            if (YesNoEnum.YES.getValue() == sitesRest.getCode()) {
                sitePduList.addAll(sitesRest.getData());
            }
        }

        if (!ObjectUtils.isEmpty(sitePduList)) {
            sitePduList = sitePduList.stream().collect(
                    collectingAndThen(
                            toCollection(() -> new TreeSet<>(Comparator.comparing(SitePdu::getId))), ArrayList::new));
        }
        return sitePduList;
    }


    public static void main(String[] args) {
        String a = StrUtil.prependIfMissing("a123", "a");
        System.out.println(a);
    }
}