package easydo.technology.core.controllers;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

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

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

import com.alibaba.fastjson.JSONObject;

import easydo.technology.core.EasydoCore.EasydoEnterprise;
import easydo.technology.core.EasydoCore.EasydoMenu;
import easydo.technology.core.ZeroCoreSpringController;
import easydo.technology.core.processors.EasydoCoreProcessor;
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;

// @Controller
// @RequestMapping(EasydoEnterpriseController.ENTERPRISE_PREFIX)
public class EasydoEnterpriseController extends ZeroCoreSpringController {

    public static final String ENTERPRISE_PREFIX = "enterprise";

    public EasydoEnterpriseController() {
        super(ENTERPRISE_PREFIX);
    }

    @Autowired
    private DataSource dataSource;

    @Override
    protected String handlerNameConstructor(ZeroRequestGuider guider) throws Exception {
        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);
    }

    public void add(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<EasydoEnterprise> request = ZeroRequest.build(EasydoEnterprise.class, guider.getRawData());
        EasydoCoreProcessor processor = EasydoCoreProcessor.build(guider);
        for (EasydoEnterprise enterprise : request.getQuerys())
            processor.addEnterprise(enterprise);
        guider.write(success());
    }

    public void up(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<EasydoEnterprise> request = ZeroRequest.build(EasydoEnterprise.class, guider.getRawData());
        EasydoCoreProcessor processor = EasydoCoreProcessor.build(guider);
        for (EasydoEnterprise enterprise : request.getQuerys())
            processor.upEnterprise(enterprise);
        guider.write(success());
    }

    public void rm(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<EasydoEnterprise> request = ZeroRequest.build(EasydoEnterprise.class, guider.getRawData());
        EasydoCoreProcessor processor = EasydoCoreProcessor.build(guider);
        for (EasydoEnterprise enterprise : request.getQuerys())
            processor.rmEnterprise(enterprise);
        guider.write(success());
    }

    public void addsubep(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<EasydoEnterprise> request = ZeroRequest.build(EasydoEnterprise.class, guider.getRawData());
        EasydoCoreProcessor processor = EasydoCoreProcessor.build(guider);
        for (EasydoEnterprise enterprise : request.getQuerys()) {
            for (EasydoEnterprise subenterprise : enterprise.getChilds()) {
                if (subenterprise.getId() == null)
                    processor.addEnterprise(subenterprise);
                processor.addEnterpriseRelevancy(enterprise.uuIDString(), subenterprise.uuIDString());
            }
        }
        guider.write(success());
    }

    public void rmsubep(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<EasydoEnterprise> request = ZeroRequest.build(EasydoEnterprise.class, guider.getRawData());
        EasydoCoreProcessor processor = EasydoCoreProcessor.build(guider);
        for (EasydoEnterprise enterprise : request.getQuerys()) {
            for (EasydoEnterprise subenterprise : enterprise.getChilds()) {
                processor.rmEnterpriseRelevancy(enterprise.uuIDString(), subenterprise.uuIDString());
            }
        }
        guider.write(success());
    }

    public void addepmenus(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<EasydoEnterprise> request = ZeroRequest.build(EasydoEnterprise.class, guider.getRawData());
        EasydoCoreProcessor processor = EasydoCoreProcessor.build(guider);
        for (EasydoEnterprise enterprise : request.getQuerys()) {
            for (EasydoMenu menu : enterprise.getMenus()) {
                processor.addEnterpriseMenus(enterprise.uuIDString(), menu.uuIDString());
            }
        }
        guider.write(success());
    }

    public void rmepmenus(ZeroRequestGuider guider) throws Exception {
        ZeroRequest<EasydoEnterprise> request = ZeroRequest.build(EasydoEnterprise.class, guider.getRawData());
        EasydoCoreProcessor processor = EasydoCoreProcessor.build(guider);
        for (EasydoEnterprise enterprise : request.getQuerys()) {
            for (EasydoMenu menu : enterprise.getMenus()) {
                processor.rmEnterpriseMenus(enterprise.uuIDString(), menu.uuIDString());
            }
        }
        guider.write(success());
    }

    protected static final String OPTION_ROOT = "root";
    protected static final String OPTION_RECURSION = "recursion";

    protected static final String OPTION_MENUS = "menus";
    protected static final String OPTION_PROJECTS = "projects";

    private void recursionEnterprises(EasydoCoreProcessor processor, EasydoEnterprise enterprise) throws SQLException {
        processor.fetchSubEnterprises(enterprise);
        for (EasydoEnterprise subenterprise : enterprise.getChilds())
            recursionEnterprises(processor, subenterprise);
    }

    public void fetch(ZeroRequestGuider guider) throws Exception {

        ZeroRequest<ZeroQuery<EasydoEnterprise>> request = ZeroRequest.build(guider.getRawData(),
                EasydoEnterprise.class);

        ZeroQueryOperation<EasydoEnterprise> operation = ZeroQueryOperation.build(EasydoEnterprise.class, guider);
        operation.openConnect(request.getQuerys().get(0).setTableName("easydo_enterprise_view"));
        if (request.hasOption(OPTION_ROOT))
            operation.appendCondition(() -> "ENTERPRISE_ID IS NULL");

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

        operation.exec(() -> {
            EasydoEnterprise data = operation.getCurrent();
            if (request.hasOption(OPTION_RECURSION))
                recursionEnterprises(processor, data);
            if (request.hasOption(OPTION_PROJECTS))
                processor.fetchEnterpriseProjects(data);
            if (request.hasOption(OPTION_MENUS))
                processor.fetchEnterpriseMenus(data);
            datas.add(data);
        }).eachExpands((key, value) -> expands.put(key, value));
        guider.write(success(datas, expands));
    }
}
