package com.system.serivce.impl;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.system.api.KingDeeApi;
import com.system.api.KingDeeK3CloudApi;
import com.system.dao.InitConnectParamMapper;
import com.system.dao.SynchronizationRecordsMapper;
import com.system.kingdee.KingDeeSynchronizationApi;
import com.system.model.InitConnectParam;
import com.system.quartz.model.QuartzJob;
import com.system.quartz.service.IQuartzJobService;
import com.system.quartz.transfer.QuartzJobPauseInVo;
import com.system.quartz.transfer.QuartzJobResumeInVo;
import com.system.serivce.IKingDeeCommonSynService;
import com.system.serivce.ISynchronizationService;
import com.system.transfer.configure.InitConnectParamCheckInVo;
import com.system.transfer.configure.InitConnectParamCreateInVo;
import com.system.transfer.configure.InitConnectParamOutVo;
import com.system.transfer.kingdee.SynchronizationRecordsListOutVoRecords;
import com.system.transfer.response.RestResponse;
import com.system.utils.HttpUtil;
import com.system.utils.JsonUtil;
import com.system.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Inori
 */
@Service
public class SynchronizationServiceImpl implements ISynchronizationService {

    @Autowired
    private KingDeeApi kingDeeApi;

    @Autowired
    private IQuartzJobService quartzJobService;

    @Autowired
    private InitConnectParamMapper initConnectParamMapper;

    @Autowired
    private KingDeeSynchronizationApi kingDeeSynchronizationApi;

    @Autowired
    private IKingDeeCommonSynService kingDeeCommonSynService;

    @Autowired
    private SynchronizationRecordsMapper synchronizationRecordsMapper;

    private ExecutorService threadPool = new ThreadPoolExecutor(5, 5,
            0L,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1024),
            new ThreadFactoryBuilder().setNameFormat("syn-pool-%d").build(),
            new ThreadPoolExecutor.AbortPolicy());


    @Override
    public RestResponse startSynchronization() {
        QuartzJob quartzJob = quartzJobService.getBaseMapper().selectById("1");

        if (StringUtil.isNotNull(quartzJob)) {
            if (quartzJob.getStatus() == 0) {
                quartzJobService.quartzJobResume(new QuartzJobResumeInVo(quartzJob.getJobClassName()));
                return RestResponse.success();
            }
        } else {
            return RestResponse.fail("自动同步定时任务不存在！");
        }

        return RestResponse.fail("自动同步已经启动，请勿重复启动！");
    }

    @Override
    public RestResponse turnOffSynchronization() {
        QuartzJob quartzJob = quartzJobService.getBaseMapper().selectById("1");

        if (StringUtil.isNotNull(quartzJob)) {
            if (quartzJob.getStatus() == 1) {
                quartzJobService.quartzJobPause(new QuartzJobPauseInVo(quartzJob.getJobClassName()));
                return RestResponse.success();
            }
        } else {
            return RestResponse.fail("自动同步定时任务不存在！");
        }

        return RestResponse.fail("自动同步已经关闭，请勿重复关闭！");
    }

    @Override
    public QuartzJob synchronizationStatus() {
        return quartzJobService.getBaseMapper().selectById("1");
    }

    @Override
    public RestResponse manualSynchronization() {
        threadPool.execute(() -> {
            List<SynchronizationRecordsListOutVoRecords> recordsList = synchronizationRecordsMapper.getSynchronizationRecordsListByStatus(Stream.of(1, 2).collect(Collectors.toList()));

            for (SynchronizationRecordsListOutVoRecords records : recordsList) {
                if (!"LQKJ_IMSSync".equals(records.getSFormId())) {
                    kingDeeCommonSynService.synchronization(records.getId(), records.getSFormId(), records.getDataId(), records.getEntryId());
                }
            }
        });

        return RestResponse.success();
    }

    @Override
    public InitConnectParamOutVo initConnectParam() {
        return initConnectParamMapper.initConnectParam();
    }

    @Override
    public RestResponse initConnectParamCreate(InitConnectParamCreateInVo inVo) {
        QuartzJob quartzJob = quartzJobService.getBaseMapper().selectById("1");

        if (StringUtil.isNotNull(quartzJob)) {
            if (quartzJob.getStatus() == 1) {
                return RestResponse.fail("请先关闭同步再保存!");
            }
        } else {
            return RestResponse.fail("自动同步定时任务不存在！");
        }

        KingDeeK3CloudApi kingDeeK3CloudApi = new KingDeeK3CloudApi(inVo.getK3CloudUrl());
        Boolean flag;
        try {
            flag = kingDeeK3CloudApi.login(inVo.getDbid(), inVo.getUid(), inVo.getPwd(), inVo.getLang());
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }

        kingDeeApi.setFlag(flag);
        kingDeeApi.setKingDeeK3CloudApi(kingDeeK3CloudApi);
        kingDeeApi.setThirdPartyUrl(inVo.getThirdPartyUrl());

        if (!flag) {
            return RestResponse.fail("参数错误，金蝶登陆失败！");
        }

        InitConnectParam initConnectParam = new InitConnectParam();
        initConnectParam.setId(1);
        initConnectParam.setK3CloudUrl(inVo.getK3CloudUrl());
        initConnectParam.setDbid(inVo.getDbid());
        initConnectParam.setLang(inVo.getLang());
        initConnectParam.setUid(inVo.getUid());
        initConnectParam.setPwd(inVo.getPwd());
        initConnectParam.setThirdPartyUrl(inVo.getThirdPartyUrl());
        initConnectParam.setDuration(inVo.getDuration());
        initConnectParamMapper.initConnectParamCreateOrUpdate(initConnectParam);
        kingDeeApi.setInitConnectParam(initConnectParam);

        String cron = "0 */" + inVo.getDuration() + "  * * * ?";
        if (!cron.equals(quartzJob.getCronExpression())) {
            quartzJob.setCronExpression(cron);
            quartzJobService.getBaseMapper().updateById(quartzJob);

            quartzJobService.quartzJobResume(new QuartzJobResumeInVo(quartzJob.getJobClassName()));
        }

        HttpUtil.httpGet("http://semiconductor-plug-in-unit:9090/semiconductor/api/init/connect/param/refresh");
        return RestResponse.success();
    }

    @Override
    public RestResponse initConnectParamCheck(InitConnectParamCheckInVo inVo) {
        KingDeeK3CloudApi kingDeeK3CloudApi = kingDeeApi.getKingDeeK3CloudApi();
        boolean flag = false;
        try {
            Object[] data = new Object[]{inVo.getDbid(), inVo.getUid(), inVo.getPwd(), inVo.getLang()};
            String result = kingDeeK3CloudApi.execute("Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser", data, String.class);

            Map<String, Object> map = JsonUtil.toMap(result, String.class, Object.class);
            if (!CollectionUtils.isEmpty(map)) {
                flag = map.containsKey("LoginResultType") && Integer.parseInt(String.valueOf(map.get("LoginResultType"))) == 1;
            }
        } catch (Exception e) {
            flag = false;
        }

        if (flag) {
            return RestResponse.success("参数正确，金蝶云登陆成功");
        } else {
            return RestResponse.fail("参数错误，金蝶云登陆失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void synchronization() {
        List<Map<String, Object>> tempList = kingDeeSynchronizationApi.synchronization();

        if (!CollectionUtils.isEmpty(tempList)) {
            synchronizationRecordsMapper.synchronizationRecordsTempCreate(tempList);
        }

        List<Map<String, Object>> uList = new ArrayList<>();
        List<String> collect = tempList.stream()
                .filter(m -> !"LQKJ_IMSSync".equals(m.get("sFormId")))
                .map(m -> String.valueOf(m.get("fid")))
                .collect(Collectors.toList());
        collect.forEach(item -> {
            //将金蝶云的数据同步该成1
            Map<String, Object> result = new HashMap<>(3);
            result.put("FID", item);
            result.put("F_LQKJ_SyncCheck", "1");
            result.put("F_LQKJ_SyndDatetime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            uList.add(result);
        });
        if (!CollectionUtils.isEmpty(uList)) {
            //修改金蝶云是否同步
            kingDeeSynchronizationApi.batchAdd(uList);
        }

        List<Map<String, Object>> mapList = synchronizationRecordsMapper.synchronizationRecordsTempList();
        if (!CollectionUtils.isEmpty(mapList)) {
            synchronizationRecordsMapper.synchronizationRecordsCreate(mapList);

            List<Integer> idList = mapList.stream().map(m -> Integer.parseInt(m.get("id").toString())).collect(Collectors.toList());
            synchronizationRecordsMapper.synchronizationRecordsTempDelete(idList);
        }

        threadPool.execute(() -> {
            List<SynchronizationRecordsListOutVoRecords> recordsList = synchronizationRecordsMapper.getSynchronizationRecordsListByStatus(Stream.of(0).collect(Collectors.toList()));
            List<Integer> idList = recordsList.stream().map(SynchronizationRecordsListOutVoRecords::getId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(idList)) {
                synchronizationRecordsMapper.synchronizationRecordsUpdateByIdList(idList);
            }

            for (SynchronizationRecordsListOutVoRecords records : recordsList) {
                if (!"LQKJ_IMSSync".equals(records.getSFormId())) {
                    kingDeeCommonSynService.synchronization(records.getId(), records.getSFormId(), records.getDataId(), records.getEntryId());
                }
                if (Thread.currentThread().isInterrupted()) {
                    break;
                }
            }
        });
    }


}
