package com.changhu.service.impl;

import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.changhu.common.exception.MessageException;
import com.changhu.common.pojo.vo.SelectNodeVo;
import com.changhu.mapper.OpenApiMapper;
import com.changhu.pojo.dto.DataViewDTO;
import com.changhu.pojo.dto.EnterprisesUnitDetailDTO;
import com.changhu.pojo.dto.SecurityUnitUseStatisticsDTO;
import com.changhu.pojo.dto.SecurityUserRosterDTO;
import com.changhu.pojo.entity.EnterprisesUnit;
import com.changhu.pojo.entity.PoliceUnit;
import com.changhu.pojo.entity.SecurityUnit;
import com.changhu.pojo.entity.SecurityUser;
import com.changhu.pojo.params.EnterprisesUnitOrServiceProjectType;
import com.changhu.service.OpenApiService;
import com.changhu.service.ServiceProjectService;
import com.changhu.support.mybatisplus.pojo.entity.BaseEntity;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @author 20252
 * @createTime 2024/10/9 下午5:29
 * @desc OpenApiServiceImpl...
 */
@Service
public class OpenApiServiceImpl implements OpenApiService {

    @Autowired
    private ServiceProjectService serviceProjectService;

    @Autowired
    private OpenApiMapper openApiMapper;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Override
    public List<SelectNodeVo<Long>> getEnterprisesUnit(String code, Integer level) {
        return openApiMapper.getEnterprisesUnit(code, level);
    }

    @Override
    public EnterprisesUnitDetailDTO enterprisesUnitDetailById(Long enterprisesUnitId) {
        return Db.lambdaQuery(EnterprisesUnit.class)
                .eq(BaseEntity::getSnowFlakeId, enterprisesUnitId)
                .oneOpt()
                .map(item -> EnterprisesUnitDetailDTO.builder()
                        .snowFlakeId(item.getSnowFlakeId())
                        .name(item.getName())
                        .type(item.getType())
                        .address(item.getAddress())
                        .contactPersonInfo(item.getContactPersonInfo())
                        .remark(item.getRemark())
                        .serviceProjectList(openApiMapper.getServiceProjectByEnterprisesUnitId(item.getSnowFlakeId()))
                        .createTime(item.getCreateTime())
                        .build())
                .orElseThrow(() -> new MessageException("企事业单位不存在"));
    }

    @SneakyThrows
    @Override
    public DataViewDTO dataView() {
        DataViewDTO dataViewDTO = new DataViewDTO();
        CountDownLatch countDownLatch = new CountDownLatch(5);
        threadPoolTaskExecutor.execute(() -> {
            try {
                dataViewDTO.setPoliceUnitCount(Db.lambdaQuery(PoliceUnit.class).count().intValue());
            } finally {
                countDownLatch.countDown();
            }
        });

        threadPoolTaskExecutor.execute(() -> {
            try {
                dataViewDTO.setSecurityUnitCount(Db.lambdaQuery(SecurityUnit.class).count().intValue());
            } finally {
                countDownLatch.countDown();
            }
        });
        threadPoolTaskExecutor.execute(() -> {
            try {
                dataViewDTO.setEnterprisesUnitCount(Db.lambdaQuery(EnterprisesUnit.class).count().intValue());
            } finally {
                countDownLatch.countDown();
            }
        });
        threadPoolTaskExecutor.execute(() -> {
            try {
                dataViewDTO.setSecurityUserTotal(Db.lambdaQuery(SecurityUser.class).count().intValue());
            } finally {
                countDownLatch.countDown();
            }
        });
        threadPoolTaskExecutor.execute(() -> {
            try {
                dataViewDTO.setNoCardSecurityUserCount(Db.lambdaQuery(SecurityUser.class)
                        .isNull(SecurityUser::getSecurityNumber)
                        .or()
                        .eq(SecurityUser::getSecurityNumber, "")
                        .count().intValue());
            } finally {
                countDownLatch.countDown();
            }
        });

        countDownLatch.await();
        return dataViewDTO;
    }

    @Override
    public List<SecurityUnitUseStatisticsDTO> securityUnitUseStatistics(String code, Integer level) {
        return openApiMapper.securityUnitUseStatistics(code, level);
    }

    @Override
    public List<SecurityUserRosterDTO> securityUserRoster(Long id, EnterprisesUnitOrServiceProjectType type) {
        return openApiMapper.securityUserRoster(id, type);
    }

    @Override
    public List<SecurityUserRosterDTO> unitSecurityUserRoster(String code, Integer level) {
        return openApiMapper.unitSecurityUserRoster(code, level);

    }
}
