package com.ecep.contract.ds.contract.tasker;

import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import com.ecep.contract.MessageHolder;
import com.ecep.contract.cloud.u8.ctx.ContractCtx;
import com.ecep.contract.ds.contract.service.ContractService;
import com.ecep.contract.model.Contract;
import com.ecep.contract.model.ContractGroup;
import com.ecep.contract.ui.Tasker;

import lombok.Setter;

/**
 * 对所有合同的文件进行重置
 */
public class ContractFilesRebuildAllTasker extends Tasker<Object> {
    @Setter
    private ContractService contractService;

    private ContractCtx contractCtx;

    @Setter
    private ContractGroup group;

    ContractCtx getContractCtx() {
        if (contractCtx == null) {
            contractCtx = new ContractCtx();
            contractCtx.setContractService(getContractService());
        }
        return contractCtx;
    }

    public ContractFilesRebuildAllTasker() {
        updateTitle("合同文件重置");
    }

    @Override
    protected Object execute(MessageHolder holder) {
        Pageable pageRequest = PageRequest.ofSize(200);
        AtomicInteger counter = new AtomicInteger(0);
        updateTitle("遍历所有合同，对每个可以合同的文件进行“重置”操作");

        Specification<Contract> spec = null;
        if (group != null) {
            holder.info("= 按合同分组 " + group.getTitle() + " 刷选 =");
            spec = (root, query, cb) -> {
                return cb.equal(root.get("group"), group);
            };
        }
        long total = getContractService().count(spec);
        while (true) {
            if (isCancelled()) {
                break;
            }

            Page<Contract> page = getContractService().findAll(spec, pageRequest);
            if (page.isEmpty()) {
                break;
            }

            for (Contract contract : page) {
                if (isCancelled()) {
                    break;
                }
                MessageHolder subHolder = holder.sub(
                        counter.get() + " / " + total + "> " + contract.getCode() + " #" + contract.getId() + "> ");
                getContractCtx().syncContractFiles(contract, subHolder);
                updateProgress(counter.incrementAndGet(), total);
            }
            if (!page.hasNext()) {
                break;
            }
            pageRequest = page.nextPageable();
        }
        return null;
    }

    private ContractService getContractService() {
        if (contractService == null) {
            contractService = getBean(ContractService.class);
        }
        return contractService;
    }
}
