package com.chinaweal.aiccs.aiccs.market.controller;


import com.chinaweal.aiccs.aiccs.abnormal.entity.EBaseinfo;
import com.chinaweal.aiccs.aiccs.abnormal.service.EBaseinfoService;
import com.chinaweal.aiccs.aiccs.market.ai.AreaSliceClaimAI;
import com.chinaweal.aiccs.aiccs.market.entity.AreaSlice;
import com.chinaweal.aiccs.aiccs.market.entity.dto.AssignEntity;
import com.chinaweal.aiccs.aiccs.market.service.AreaSliceService;
import com.chinaweal.aiccs.aiccs.market.service.InitService;
import com.chinaweal.aiccs.common.threadLocalManage.DisableEntListManage;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.servlet.ServletContextEvent;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.*;

/**
 * @author ymc
 * @date 2022年04月25日 14:29
 */

@Api(tags = "市场所监管初始化相关接口")
@ApiSort(2)
@RestController
@RequestMapping("/market/init")
@Slf4j(topic = "claim")
public class InitController {

    // 线程工厂，用于为线程池中的每条线程命名
    private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("assignAI-%d").build();

    // 创建线程池，使用有界阻塞队列防止内存溢出
    private static ExecutorService statsThreadPool = new ThreadPoolExecutor(5, 8,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(300), namedThreadFactory);

//    @PreDestroy
//    public void contextDestroyed(ServletContextEvent sce) {
//        statsThreadPool.shutdown();
//        DisableEntListManage.timer.cancel();
//    }

    @Resource
    private InitService initService;
    @Resource
    private EBaseinfoService eBaseinfoService;
    @Resource
    private AreaSliceService areaSliceService;
    @Resource
    private AreaSliceClaimAI areaSliceClaimAI;

    @ApiOperation(value = "1.市场所主体补认领接口 ", position = 1)
    @ApiOperationSupport(order = 1)
    @GetMapping("/repairAssignOwner")
    public RestResult<?> repairAssignOwner() {

        log.info("==========市场所主体补认领开始==========");
        Set<String> notAreaSet = new HashSet<>();
        List<EBaseinfo> eBaseinfos = eBaseinfoService.lambdaQuery().eq(EBaseinfo::getSareacodeTemp, "").eq(EBaseinfo::getRegstate, "1").orderByAsc(EBaseinfo::getPripid).last("limit 10000").list();
        while (CollectionUtils.isNotEmpty(eBaseinfos)) {
            String orgCode = null;
            String errPriPid = null;
            try {
                for (EBaseinfo each : eBaseinfos) {
                    // 2.根据监管、登记机关字段判断区域
                    orgCode = each.getSuporg();
                    errPriPid = each.getPripid();

                    // 过滤
                    if (StringUtils.isBlank(orgCode) || orgCode.length() == 6)
                        continue;

                    // 特殊处理
                    if ("44011006".equals(orgCode)) orgCode = "44011001";

                    // 区、所公共片区都只有一条数据，有多那就证明数据不正常，捕获一下顺便清晰一波数据
                    AreaSlice areaSlice = null;
                    areaSlice = areaSliceService.lambdaQuery().eq(AreaSlice::getOrgNumber, orgCode).eq(AreaSlice::getState, "1").in(AreaSlice::getSliceType, "0", "1").one();

                    if (areaSlice == null) {
                        notAreaSet.add(orgCode);
                        log.error("无法找到对应片区, pripid: {}, orgCode: {}。", each.getPripid(), orgCode);
                        continue;
                    }

                    initService.repairAssignOwner(areaSlice.getSliceId(), each.getPripid());

                }
                String pripid = eBaseinfos.get(eBaseinfos.size() - 1).getPripid();
                eBaseinfos = eBaseinfoService.lambdaQuery().isNull(EBaseinfo::getSareacodeTemp).eq(EBaseinfo::getRegstate, "1").gt(EBaseinfo::getPripid, pripid).orderByAsc(EBaseinfo::getPripid).last("limit 10000").list();
                log.info("遍历查询：pripid：{}, 数量：{} ", pripid, eBaseinfos.size());

            } catch (MyBatisSystemException e) {
                log.error("获取片区出错，orgCode: {}, 原因： {}", orgCode, e.getMessage());
            } catch (Exception e) {
                log.error("系统出错, pripid: {}, orgCode: {}。原因：", errPriPid, orgCode, e);
            }
        }
        log.info("没有片区数据集合：{}", String.join(",", notAreaSet));
        log.info("==========市场所主体补认领结束==========");

        return RestResult.ok();

    }

    @ApiOperation(value = "2.智能自动认领(手动触发) ", position = 2)
    @ApiOperationSupport(order = 1)
    @GetMapping("/autoClaimAI")
    public RestResult<?> autoClaimAI() {

        statsThreadPool.submit(() -> {
            log.info("==========市场所主体认领开始==========");

            String lastSql = "limit 10000";
            List<EBaseinfo> records = eBaseinfoService.lambdaQuery().isNull(EBaseinfo::getSareacodeTemp).eq(EBaseinfo::getRegstate, "1")
                    .orderByAsc(EBaseinfo::getPripid).last(lastSql).list();

            while (CollectionUtils.isNotEmpty(records)) {
                for (EBaseinfo each : records) {

                    AssignEntity entity = new AssignEntity()
                            .setAddress(StringUtils.isNotBlank(each.getDom()) ? each.getDom() : each.getAddress())
                            .setPripid(each.getPripid())
                            .setEntName(each.getEntname())
                            .setEntType(each.getEnttype())
                            .setLerep(each.getLerep())
                            .setRegNo(each.getRegno())
                            .setRegOrg(each.getRegorg())
                            .setRegulatory(each.getSuporg())
                            .setUniscid(each.getUniscid());

//                    if (StringUtils.isBlank(entity.getAddress())) {
//                        log.error("缺失地址，pripid: {}", entity.getPripid());
//                        continue;
//                    }

                    try {
                        areaSliceClaimAI.claimInScope(entity, null);
                    } catch (Exception e) {
                        if ("配额不足".equals(e.getMessage())) {
                            log.error("高德地图配额不足,退出智能自动认领!", e);
                            break;
                        } else {
                            log.error("系统出错, pripid: {}。原因：", each.getPripid(), e);
                        }
                    }

                }
                records = eBaseinfoService.lambdaQuery().isNull(EBaseinfo::getSareacodeTemp).eq(EBaseinfo::getRegstate, "1")
                        .gt(EBaseinfo::getPripid, records.get(records.size() - 1).getPripid())
                        .orderByAsc(EBaseinfo::getPripid).last(lastSql).list();
            }

            log.info("==========市场所主体认领结束==========");

        });

        return RestResult.ok();

    }

}
