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.service.tasker.WebSocketServerTasker;
import com.ecep.contract.ui.Tasker;
import com.fasterxml.jackson.databind.JsonNode;

/**
 * 全量同步库存
 */
public class InventoryAllSyncTask extends Tasker<Object> implements WebSocketServerTasker {
    private InventoryCtx inventoryCtx;

    public InventoryService getInventoryService() {
        return getCachedBean(InventoryService.class);
    }

    @Override
    public void init(JsonNode argsNode) {

    }

    @Override
    protected Object execute(MessageHolder holder) throws Exception {
        updateProgress(0, 1000);

        inventoryCtx = new InventoryCtx(this);
        inventoryCtx.initializeRepository(holder);

        InventoryService service = getInventoryService();
        Pageable pageRequest = PageRequest.ofSize(200);
        AtomicInteger counter = new AtomicInteger(0);
        Specification<Inventory> spec = null;
        long total = service.count(spec);
        holder.info("共需同步 " + total + " 条库存数据");

        while (true) {
            if (isCancelled()) {
                holder.warn("库存同步任务已取消");
                break;
            }

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

            for (Inventory inventory : page) {
                if (isCancelled()) {
                    holder.warn("库存同步任务已取消");
                    break;
                }

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

                syncInventory(inventory, subHolder);

                int progress = (int) ((counter.incrementAndGet() * 1000L) / total);
                updateProgress(progress, 1000);
            }
            if (!page.hasNext()) {
                break;
            }
            pageRequest = page.nextPageable();
        }

        updateProgress(1000, 1000);
        holder.info("库存同步任务完成！");
        return null;
    }

    private void syncInventory(Inventory inventory, MessageHolder holder) {
        holder.info("正在同步库存数据：" + inventory.getCode() + " - " + inventory.getName());
        try {
            if (inventoryCtx.syncInventoryDetailByCode(inventory, inventory.getCode(), holder)) {
                inventoryCtx.getInventoryService().save(inventory);
                holder.info("库存数据同步成功：" + inventory.getCode());
            }
        } catch (Exception e) {
            holder.error("库存同步失败：" + inventory.getCode() + " - " + e.getMessage());
        }
    }

}
