package com.ecep.contract.ds.other.controller;

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.InventoryCtx;
import com.ecep.contract.ds.other.service.InventoryService;
import com.ecep.contract.model.Inventory;
import com.ecep.contract.ui.Tasker;

public class InventorySyncTask extends Tasker<Object> {
    private InventoryCtx inventoryCtx;

    @Override
    protected Object execute(MessageHolder holder) throws Exception {
        inventoryCtx = new InventoryCtx();
        inventoryCtx.initializeRepository(holder);

        InventoryService service = inventoryCtx.getInventoryService();
        Pageable pageRequest = PageRequest.ofSize(200);
        AtomicInteger counter = new AtomicInteger(0);
        Specification<Inventory> spec = null;
        long total = service.count(spec);
        while (true) {
            if (isCancelled()) {
                break;
            }

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

            for (Inventory inventory : page) {
                if (isCancelled()) {
                    break;
                }

                String prefix = counter.get() + " / " + total + "> #" + inventory.getId() + "> ";
                MessageHolder subHolder = holder.sub(prefix);
                syncInventory(inventory, subHolder);

                updateProgress(counter.incrementAndGet(), total);
            }
            if (!page.hasNext()) {
                break;
            }
            pageRequest = page.nextPageable();
        }
        updateProgress(1, 1);
        return super.call();
    }

    private void syncInventory(Inventory inventory, MessageHolder holder) {
        if (inventoryCtx.syncInventoryDetailByCode(inventory, inventory.getCode(), holder)) {
            inventoryCtx.getInventoryService().save(inventory);
        }
    }
}
