package com.brframework.commoncms.core.option;

import com.brframework.commoncms.core.uri.RouteUri;
import com.brframework.commonweb.exception.HandleException;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.brframework.commoncms.annatotion.Panel;
import com.brframework.commoncms.annatotion.option.CmsOption;
import com.brframework.commoncms.core.Option;
import com.brframework.commoncms.core.UriProtocol;
import com.brframework.commoncms.core.uri.PanelUri;
import com.brframework.commoncms.core.uri.RequestUri;
import com.brframework.commoncms.utils.ColourUtil;
import com.brframework.commoncms.utils.ControllerUtil;
import lombok.Data;
import org.springframework.core.annotation.AnnotatedElementUtils;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * 操作
 *
 * @author xu
 * @date 2018/10/10 14:31
 * @see CmsOption
 */
@Data
public class DefOption implements Option {

    /**
     * 条件表达式
     */
    String condition;

    /**
     * 操作名称
     */
    String name;
    /**
     * 操作uri
     * {PROTOCOL}://{path}
     */
    String uri;

    /**
     * 根据Http请求方式设置按钮的颜色
     */
    String color;

    @Override
    public void create(Method method, CmsOption option) {
        name = option.name();
        condition = option.condition();

        String uriMappingMethod = option.uriMappingMethod();
        if (!Strings.isNullOrEmpty(uriMappingMethod)) {
            uri = handlerUriMappingMethod(method, uriMappingMethod, option);
        } else {
            String[] protocolUri = option.uri().split("://");
            if (protocolUri.length != 2) {
                throw new HandleException("非正确协议");
            }

            String protocol = protocolUri[0];
            String path = protocolUri[1];

            switch (protocol) {
                case UriProtocol.REQUEST:
                    path = handlerRequestPath(path, option.alert());
                    break;
                case UriProtocol.PANEL:
                    path = handlerPanelPath(path);
                    break;
                case UriProtocol.ROUTE:
                    path = handlerRoutePath(path);
                    break;
                default:
                    throw new HandleException("错误协议" + protocol);
            }

            uri = UriProtocol.builder()
                    .protocol(protocol)
                    .path(path)
                    .build().toString();
        }

        //最后看看@CmsOption有没有配置专门的颜色
        if (!Strings.isNullOrEmpty(option.color())) {
            setColor(option.color());
        }

    }

    /**
     * 处理界面跳转地址
     * PANEL://POST admin/access/v1/user/{id}/integral
     *
     * @param protocolPath 协议地址部分
     * @return
     */
    private String handlerPanelPath(String protocolPath) {
        //PANEL://POST admin/access/v1/user/{id}/integral
        String[] protocolPathNodes = protocolPath.split(" ");
        //http请求方法
        String requestMethod = protocolPathNodes[0];
        String url = null;

        for (int i = 1; i < protocolPathNodes.length; i++) {
            if (Strings.isNullOrEmpty(protocolPathNodes[i])) {
                continue;
            }

            switch (protocolPathNodes[i]) {
                default:
                    url = protocolPathNodes[i];
                    break;
            }
        }

        PanelUri panelUri = new PanelUri();
        panelUri.setMethod(requestMethod);
        panelUri.setUrl(url);


        //设置按钮的颜色
        setColor(ColourUtil.setColorByRequestMethod(requestMethod).color());

        return panelUri.toString();
    }


    /**
     * 处理request协议
     * question?id={id}
     *
     * @param protocolPath 协议地址部分
     * @return
     */
    private String handlerRoutePath(String protocolPath) {
//        POST -d forbidden=1 -alert 您确定解禁该用户吗 admin/access/v1/user/{id}/forbidden
        String[] protocolPathNodes = protocolPath.split(" ");


        RouteUri routeUri = new RouteUri();
        routeUri.setUrl(protocolPathNodes[0]);

        return routeUri.toString();
    }

    /**
     * 处理request协议
     * POST -d forbidden=1 -alert 您确定解禁该用户吗 admin/access/v1/user/{id}/forbidden
     *
     * @param protocolPath 协议地址部分
     * @param alert        提示信息
     * @return
     */
    private String handlerRequestPath(String protocolPath, String alert) {
//        POST -d forbidden=1 -alert 您确定解禁该用户吗 admin/access/v1/user/{id}/forbidden
        String[] protocolPathNodes = protocolPath.split(" ");
        //http请求方法
        String requestMethod = protocolPathNodes[0];
        Map<String, String> body = Maps.newHashMap();
        String url = null;
        for (int i = 1; i < protocolPathNodes.length; i++) {
            if (Strings.isNullOrEmpty(protocolPathNodes[i])) {
                continue;
            }
            switch (protocolPathNodes[i]) {
                case "-d":
                    //将表达式设置成body参数
                    String[] bodyParams = protocolPathNodes[i + 1].split(",");
                    for (String bodyParam : bodyParams) {
                        String[] _p = bodyParam.split("=");
                        body.put(_p[0], _p[1]);
                    }
                    break;
                case "-alert":
                    alert = protocolPathNodes[i + 1];
                    i++;
                    break;
                default:
                    url = protocolPathNodes[i];
                    break;
            }
        }

        RequestUri requestUri = new RequestUri();
        requestUri.setAlert(alert);
        requestUri.setBody(body);
        requestUri.setMethod(requestMethod);
        requestUri.setUrl(url);

        //设置按钮的颜色
        setColor(ColourUtil.setColorByRequestMethod(requestMethod).color());

        return requestUri.toString();
    }


    /**
     * 处理得到URL映射的方法
     *
     * @param method
     * @param uriMappingMethod
     * @return
     */
    public String handlerUriMappingMethod(Method method, String uriMappingMethod, CmsOption option) {

        Method[] declaredMethods = method.getDeclaringClass().getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            if (declaredMethod.getName().equals(uriMappingMethod)) {
                return ControllerUtil.parseMethodUriProtocol(
                        declaredMethod, option.alert()).toString();
            }
        }

        throw new HandleException("填写了错误的方法:" + uriMappingMethod);
    }
}
