package zmo.technology.lite.controllers;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import com.alibaba.fastjson.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import zmo.technology.lite.core.ZeroController;
import zmo.technology.lite.core.ZeroEnum;
import zmo.technology.lite.core.ZeroException;
import zmo.technology.lite.core.ZeroQuery;
import zmo.technology.lite.core.ZeroQueryOperation;
import zmo.technology.lite.core.ZeroRequest;
import zmo.technology.lite.core.ZeroRequestGuider;
import zmo.technology.lite.processors.ZeroEnumProcessor;

@Controller
@RequestMapping(ZeroEnumController.ENUMS_PREFIX)
public class ZeroEnumController extends ZeroController {

    public static final String ENUMS_PREFIX = "enums";

    public ZeroEnumController() {
        super(ENUMS_PREFIX);
    }

    @Autowired
    private DataSource dataSource;

    @Override
    protected String handlerNameConstructor(ZeroRequestGuider guider) throws ZeroException {
        if (guider.getPaths().size() < 1)
            throw new ZeroException(404, "no handlers");
        return guider.getPaths().get(0);
    }

    @RequestMapping(GENERAL_HANDLER_PATH)
    public void general(HttpServletRequest request, HttpServletResponse response) throws Exception {
        proxyHandler(dataSource, request, response);
    }

    protected static final String EXPANDS_LEVEL = "level";
    protected static final String EXPANDS_PARENT = "parent";

    public void add(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<ZeroEnum> request = ZeroRequest.build(ZeroEnum.class, guider.getRawData());
        ZeroEnumProcessor processor = ZeroEnumProcessor.build(guider);
        for (ZeroEnum enums : request.getQuerys())
            if (request.getExpands().containsKey(EXPANDS_PARENT))
                processor.addEnum(request.getExpands().getString(EXPANDS_PARENT), enums);
            else
                processor.addEnum(enums);
        guider.write(success());
    }

    public void rm(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<ZeroEnum> request = ZeroRequest.build(ZeroEnum.class, guider.getRawData());
        ZeroEnumProcessor processor = ZeroEnumProcessor.build(guider);
        for (ZeroEnum enums : request.getQuerys())
            processor.rmEnum(enums);
        guider.write(success());
    }

    public void up(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<ZeroEnum> request = ZeroRequest.build(ZeroEnum.class, guider.getRawData());
        ZeroEnumProcessor processor = ZeroEnumProcessor.build(guider);
        for (ZeroEnum enums : request.getQuerys())
            processor.upEnum(enums);
        guider.write(success());
    }

    public void fetch(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<ZeroQuery<ZeroEnum>> request = ZeroRequest.build(guider.getRawData(),
                ZeroEnum.class);

        ZeroQueryOperation<ZeroEnum> operation = ZeroQueryOperation.build(ZeroEnum.class, guider);

        if (request.hasOption(""))
            operation.openConnect(request.getQuerys().get(0).setTableName("curacao_spring_enums"));
        else
            operation.openConnect(request.getQuerys().get(0).setTableName("curacao_spring_root_enum_view"));

        List<ZeroEnum> datas = new ArrayList<>();
        JSONObject expands = new JSONObject();
        ZeroEnumProcessor processor = ZeroEnumProcessor.build(guider);

        operation.exec(() -> {
            ZeroEnum enums = operation.getCurrent();
            if (request.hasExpand(EXPANDS_LEVEL))
                processor.fetchEnumOptions(enums, request.getExpands().getIntValue(EXPANDS_LEVEL));
            datas.add(enums);
        }).eachExpands((key, value) -> expands.put(key, value));
        guider.write(success(datas, expands));
    }
}
