package com.ningdatech.kqapi.scheduler.task;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import com.ningdatech.cache.model.cache.CacheKey;
import com.ningdatech.cache.repository.CachePlusOps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.ningdatech.kqapi.common.util.NdDateUtils;
import com.ningdatech.kqapi.irs.manage.IrsManage;
import com.ningdatech.kqapi.zzsfw.model.entity.DscSxAdsShareItemQltQlsxCommonIDVKq;
import com.ningdatech.kqapi.zzsfw.service.IDscSxAdsShareItemQltQlsxCommonIDVKqService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author CMM
 * 事项同步定时任务
 * @since 2024/08/21 09:53
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class ItemSynTask {

    @Value("${hostname}")
    public String HOST;

    @Value("${task.switch.is-open}")
    private boolean flag;

    private final IDscSxAdsShareItemQltQlsxCommonIDVKqService kqService;
    private final IrsManage irsManage;
    private final CachePlusOps cachePlusOps;

    String ITEM_BASIC_INFO_KEY = "kq:task:item:item_basic_info_list_update_date";

    /**
     * 每天凌晨5点同步数据
     */
    @Scheduled(cron = "0 0 5 * * ?")
    public void synData() throws UnknownHostException {
        // 线上环境运行
        if (flag && HOST.equals(InetAddress.getLocalHost().getHostName())) {
            log.info("事项数据 ===================== 同步开始");
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            // 每天凌晨5点循环拉取较前一天新更新的数据
            // 根据事项表中最后更新日期 循环更新至前一天的事项数据
            // 默认一页返回
            int pageNum = 1;
            // irs接口最大返回数据量1000条
            int pageSize = 1000;

            List<DscSxAdsShareItemQltQlsxCommonIDVKq> records = Lists.newArrayList();

            // 从缓存中取上次同步数据中最新的更新日期
            CacheKey key = new CacheKey(ITEM_BASIC_INFO_KEY);
            String start = cachePlusOps.get(key);
            // 如果缓存中不存在 从表中查询
            if (StringUtils.isBlank(start)) {
                start = kqService.getNewestUpdateDate();
            }
            String end = NdDateUtils.format(LocalDateTime.now().minusDays(1), NdDateUtils.DEFAULT_DATE_FORMAT);
            LocalDate startDate = LocalDate.parse(start).plusDays(1);
            LocalDate endDate = LocalDate.parse(end);
            for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
                boolean flag = true;
                while (flag) {
                    String startDateStr = NdDateUtils.format(date, NdDateUtils.DEFAULT_DATE_FORMAT);
                    String endDateStr = NdDateUtils.format(date.plusDays(1), NdDateUtils.DEFAULT_DATE_FORMAT);
                    Object listObject = irsManage.itemBasicInfoList(startDateStr, endDateStr, pageSize, pageNum);
                    // 如果数据正常返回
                    if (listObject instanceof JSONArray) {
                        JSONArray listJsonArray = (JSONArray) listObject;
                        log.info("事项列表数量为：{}", listJsonArray.size());
                        getSaveRecords(listJsonArray, records);
                        // 如果listJsonArray数据量等于1000 需要继续拉取数据
                        if (listJsonArray.size() == pageSize) {
                            pageNum++;
                        } else {
                            flag = false;
                        }
                    } else {
                        log.error("事项列表数据异常：{}", listObject.toString());
                        return;
                    }
                }
            }
            log.info("{} - {} 数据列表数量为：{}", startDate, endDate, records.size());
            kqService.saveBatch(records);
            log.info("事项同步成功，更新时间：{}", endDate);
            // 更新缓存中的更新时间
            // 获取此次保存记录中的最新更新时间
            records.sort((o1, o2) -> o2.getUpdateDate().compareTo(o1.getUpdateDate()));
            LocalDateTime updateDate = records.get(0).getUpdateDate();
            String updateDateStr = NdDateUtils.format(updateDate, NdDateUtils.DEFAULT_DATE_FORMAT);
            cachePlusOps.set(key, updateDateStr);
            stopWatch.stop();
            log.info("事项数据 ===================== 同步总共耗时 :{} s", stopWatch.getTotalTimeSeconds());
        }
    }

    private void getSaveRecords(JSONArray listJsonArray, List<DscSxAdsShareItemQltQlsxCommonIDVKq> records) {
        if (CollUtil.isNotEmpty(listJsonArray)) {
            List<DscSxAdsShareItemQltQlsxCommonIDVKq> dataList = Lists.newArrayList();
            for (Object item : listJsonArray) {
                JSONObject itemJsonObject = (JSONObject) item;
                DscSxAdsShareItemQltQlsxCommonIDVKq itemData = null;
                // 先将列表中返回的非敏感信息进行赋值
                itemData = JSON.parseObject(itemJsonObject.toJSONString(), DscSxAdsShareItemQltQlsxCommonIDVKq.class);
                String rowGuid = itemJsonObject.getString("rowguid" );
                if (StringUtils.isNotBlank(rowGuid)) {
                    Object detailObject = irsManage.itemBasicInfoDetail(rowGuid);
                    if (detailObject instanceof JSONArray){
                        JSONArray detailJsonArray = (JSONArray) detailObject;
                        List<DscSxAdsShareItemQltQlsxCommonIDVKq> idvKqList = detailJsonArray.toJavaList(DscSxAdsShareItemQltQlsxCommonIDVKq.class);
                        if (CollUtil.isNotEmpty(idvKqList)) {
                            // 如果列表不为空，则取最新的一条数据
                            idvKqList.sort((o1, o2) -> o2.getUpdateDate().compareTo(o1.getUpdateDate()));
                            DscSxAdsShareItemQltQlsxCommonIDVKq detailItemData = idvKqList.get(0);
                            // 将敏感数据进行赋值
                            CopyOptions copyOptions = CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true);
                            BeanUtil.copyProperties(detailItemData, itemData,copyOptions);
                        }
                    }
                }
                if (Objects.nonNull(itemData)) {
                    dataList.add(itemData);
                }
            }
            // 保存数据
            if (CollUtil.isNotEmpty(dataList)) {
                records.addAll(dataList);
            }
        }
    }
}
