package com.gree.mall.miniapp.schedule;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.gree.mall.miniapp.bean.material.parts.SalesCustomerPartsBean;
import com.gree.mall.miniapp.constant.Constant;
import com.gree.mall.miniapp.enums.IsEnum;
import com.gree.mall.miniapp.logic.material.parts.OldRefundManageLogic;
import com.gree.mall.miniapp.plus.entity.WebsitPartsOldRefundManage;
import com.gree.mall.miniapp.plus.entity.WorkerSalesCustomerInfo;
import com.gree.mall.miniapp.plus.service.WebsitPartsOldRefundManageService;
import com.gree.mall.miniapp.plus.service.WorkerSalesCustomerInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

@Component
@Slf4j
@ConditionalOnProperty(name = "schedule.enable", havingValue = "true", matchIfMissing = true)
public class WorkerOldPartsHandlerSchedule {

    @Resource
    WorkerSalesCustomerInfoService workerSalesCustomerInfoService;
    @Resource
    OldRefundManageLogic oldRefundManageLogic;
    @Resource
    RedisLockRegistry redisLockRegistry;
    @Resource
    WebsitPartsOldRefundManageService websitPartsOldRefundManageService;

    //上一次执行完后5秒再扫表
    @Scheduled(initialDelay = 5000, fixedDelay = 5000)
    private void infoTask() {
        final DateTime curDate = DateUtil.date();
        List<WorkerSalesCustomerInfo> infoList = workerSalesCustomerInfoService.lambdaQuery()
                .eq(WorkerSalesCustomerInfo::getIsExec, IsEnum.N.getValue())
                .isNull(WorkerSalesCustomerInfo::getExecTime)
                .between(WorkerSalesCustomerInfo::getCreateTime, DateUtil.offsetDay(curDate, -2), curDate)
                .orderByAsc(WorkerSalesCustomerInfo::getCreateTime)
                .list();

        if (CollectionUtil.isNotEmpty(infoList)) {
            for (WorkerSalesCustomerInfo info : infoList) {
                Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER + info.getId());
                try {
                    if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                        final SalesCustomerPartsBean bean = JSONUtil.toBean(info.getSalesCustomerJson(), SalesCustomerPartsBean.class);
                        final String applyNo = oldRefundManageLogic.add(bean);
                        if (StringUtils.isNotBlank(applyNo)) {
                            info.setIsExec(true)
                                    .setExecTime(DateUtil.date())
                                    .updateById();
                        }
                    }
                } catch (Exception e) {
                    log.error("旧件返还处理师傅配件库存出错: " + info.getId(), e);
                } finally {
                    obtain.unlock();
                }
            }
        }
    }


    //上一次执行完后5秒再扫表
    @Scheduled(initialDelay = 5000, fixedDelay = 5000)
    private void oldRefundTask() {
        List<WebsitPartsOldRefundManage> manageList = websitPartsOldRefundManageService.lambdaQuery()
                .select(WebsitPartsOldRefundManage::getApplyNo)
                .isNull(WebsitPartsOldRefundManage::getSettlementState)
                .orderByAsc(WebsitPartsOldRefundManage::getCreateTime)
                .list();

        if (CollectionUtil.isNotEmpty(manageList)) {
            for (WebsitPartsOldRefundManage manage : manageList) {
                Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER + manage.getApplyNo());
                try {
                    if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                        oldRefundManageLogic.websitSalesHandle(manage.getApplyNo());
                    }
                } catch (Exception e) {
                    log.error("旧件返还处理配件销售单出错: " + manage.getApplyNo(), e);
                } finally {
                    obtain.unlock();
                }
            }
        }
    }

}
