package com.eshore.gringotts.web.domain.service;

import cn.hutool.core.util.StrUtil;
import com.eshore.gringotts.web.domain.base.service.CheckingService;
import com.eshore.gringotts.web.domain.base.service.SimpleServiceSupport;
import com.eshore.gringotts.web.domain.entity.CheckOrder;
import com.eshore.gringotts.web.domain.entity.User;
import com.eshore.gringotts.web.domain.entity.Ware;
import com.eshore.gringotts.web.domain.repository.WareRepository;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.factory.Maps;
import org.eclipse.collections.api.list.ImmutableList;
import org.eclipse.collections.api.map.ImmutableMap;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Service;

/**
 * @author lanyuanxiaoyao
 * @date 2024-12-13
 */
@Slf4j
@Service("com.eshore.gringotts.web.domain.service.WareService")
public class WareService extends SimpleServiceSupport<Ware> implements CheckingService {
    private final WareRepository wareRepository;
    private final CheckOrderService checkOrderService;
    private final ObjectMapper mapper;

    public WareService(WareRepository repository, UserService userService, CheckOrderService checkOrderService, Jackson2ObjectMapperBuilder builder) {
        super(repository, userService);
        this.wareRepository = repository;
        this.checkOrderService = checkOrderService;
        this.mapper = builder.build();
    }

    public ImmutableList<Ware> listPublic() {
        return Lists.immutable.ofAll(
                wareRepository.findAll((root, query, builder) -> builder.equal(root.get("state"), Ware.State.NORMAL))
        );
    }

    @Transactional(rollbackOn = Throwable.class)
    @Override
    public void onChecked(CheckOrder order, CheckOrder.Operation operation, ImmutableMap<String, Object> parameters) {
        if (StrUtil.equals(order.getKeyword(), "ware_check")) {
            Long wareId = (Long) parameters.get("wareId");
            Ware ware = detailOrThrow(wareId);
            switch (operation) {
                case APPLY:
                    ware.setState(Ware.State.NORMAL);
                    order.setState(CheckOrder.State.OVER);
                    break;
                case REJECT:
                    ware.setState(Ware.State.DRAFT);
                    order.setState(CheckOrder.State.OVER);
                    break;
            }
            save(ware);
            checkOrderService.save(order);
        }
    }

    @Transactional(rollbackOn = Throwable.class)
    public void submit(Long id) throws JsonProcessingException {
        Ware ware = detailOrThrow(id);
        ware.setState(Ware.State.CHECKING);
        Long orderId = checkOrderService.save(new CheckOrder(
                "ware_check",
                StrUtil.format("数据资源「{}」的上架申请", ware.getName()),
                CheckOrder.Type.MARKET,
                mapper.writeValueAsString(Maps.immutable.of("wareId", ware.getId())),
                "com.eshore.gringotts.web.domain.service.WareService",
                User.Role.CHECKER
        ));
        CheckOrder order = checkOrderService.detailOrThrow(orderId);
        ware.setOrder(order);
        save(ware);
    }

    @Transactional(rollbackOn = Throwable.class)
    public void retract(Long id) {
        Ware ware = detailOrThrow(id);
        ware.setState(Ware.State.DRAFT);
        save(ware);

        CheckOrder order = ware.getOrder();
        order.setState(CheckOrder.State.RETRACT);
        checkOrderService.save(order);
    }
}
