package com.eshore.gringotts.web.domain.base.controller;

import cn.hutool.core.util.ObjectUtil;
import com.eshore.gringotts.web.configuration.amis.AmisResponse;
import com.eshore.gringotts.web.domain.base.controller.query.Query;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity;
import com.eshore.gringotts.web.domain.base.service.SimpleServiceSupport;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * @author lanyuanxiaoyao
 * @date 2024-11-26
 */
@Slf4j
public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> implements SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> {
    protected static final String SAVE = "/save";
    protected static final String LIST = "/list";
    protected static final String DETAIL = "/detail/{id}";
    protected static final String REMOVE = "/remove/{id}";

    private final SimpleServiceSupport<ENTITY> service;

    public SimpleControllerSupport(SimpleServiceSupport<ENTITY> service) {
        this.service = service;
    }

    @PostMapping(SAVE)
    @Override
    public AmisResponse<Long> save(@RequestBody SAVE_ITEM item) throws Exception {
        return AmisResponse.responseSuccess(service.save(fromSaveItem(item)));
    }

    @GetMapping(LIST)
    @Override
    public AmisResponse<ImmutableList<LIST_ITEM>> list() throws Exception {
        return AmisResponse.responseSuccess(service.list().collect(entity -> {
            try {
                return toListItem(entity);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }));
    }

    @PostMapping(LIST)
    @Override
    public AmisResponse<ImmutableList<LIST_ITEM>> list(@RequestBody Query query) throws Exception {
        if (ObjectUtil.isNull(query)) {
            return AmisResponse.responseSuccess(Lists.immutable.empty());
        }
        return AmisResponse.responseSuccess(service.list(query).collect(entity -> {
            try {
                return toListItem(entity);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }));
    }

    @GetMapping(DETAIL)
    @Override
    public AmisResponse<DETAIL_ITEM> detail(@PathVariable Long id) throws Exception {
        return AmisResponse.responseSuccess(toDetailItem(service.detailOrThrow(id)));
    }

    @GetMapping(REMOVE)
    @Override
    public AmisResponse<Object> remove(@PathVariable Long id) {
        service.remove(id);
        return AmisResponse.responseSuccess();
    }

    protected abstract ENTITY fromSaveItem(SAVE_ITEM item) throws Exception;

    protected abstract LIST_ITEM toListItem(ENTITY entity) throws Exception;

    protected abstract DETAIL_ITEM toDetailItem(ENTITY entity) throws Exception;
}
