package com.gingersoft.gsa.cloud.function;

import android.app.Activity;
import android.text.TextUtils;
import android.view.View;

import androidx.fragment.app.Fragment;

import com.gingersoft.gsa.cloud.base.utils.ReflectionUtils;
import com.gingersoft.gsa.cloud.database.bean.Function;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import butterknife.BindView;

/**
 * @author : bin
 * @create date: 2020-11-23
 * @update date: 2020-11-23
 * @description:
 */
public class XFunctionManager implements XFunctionAction {

    private static XFunctionManager sXFunctionManager = null;

    /**
     * 所有功能數據
     */
    private HashMap<String, Function> mFunctionMap = new HashMap<>();

    private XFunctionManager() {
    }

    public static XFunctionManager newInstance() {
        if (sXFunctionManager == null) {
            sXFunctionManager = new XFunctionManager();
        }
        return sXFunctionManager;
    }


    @Override
    public void inJectFunctionAnnoations(Object rootView, Class<?> functionModules) {

        Map<String, FModule[]> FModuleValues = new HashMap<>();
        Map<String, FModule> FModuleValue = new HashMap<>();

        Field[] functionFields = functionModules.getDeclaredFields();
        for (int i = 0; i < functionFields.length; i++) {
            Field field = functionFields[i];
            field.setAccessible(true);
            Annotation[] annotations = field.getAnnotations();
            if (annotations == null) {
                continue;
            }
            for (Annotation annotation : annotations) {
                String value = null;
                if (annotation instanceof XFunctionItems) {
                    XFunctionItems functionItems = (XFunctionItems) annotation;
                    value = functionItems.value();
                    try {
                        String name = field.getName();
                        FModule[] fModule = (FModule[]) field.get(name);
                        if (!FModuleValues.containsValue(fModule)) {
                            FModuleValues.put(value, fModule);
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else if (annotation instanceof XFunctionItem) {
                    XFunctionItem functionItem = (XFunctionItem) annotation;
                    value = functionItem.value();
                    try {
                        String name = field.getName();
                        FModule fModule = (FModule) field.get(name);
                        if (!FModuleValue.containsValue(fModule)) {
                            FModuleValue.put(value, fModule);
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        Field[] viewFields = rootView.getClass().getDeclaredFields();
        for (int i = 0; i < viewFields.length; i++) {
            Field field = viewFields[i];
            field.setAccessible(true);
            Annotation[] annotations = field.getAnnotations();
            if (annotations == null) {
                continue;
            }
            for (Annotation annotation : annotations) {
                if (annotation instanceof XFunctionViews) {
                    XFunctionViews functionViews = (XFunctionViews) annotation;
                    String value = functionViews.value();
                    if (FModuleValues.containsKey(value)) {
                        //功能組 拿到對應的key去匹配
                        List<Function> functions = getFunctionItems(value, FModuleValues.get(value));
                        try {
                            String name = field.getName();
                            //設置功能組數據源
                            ReflectionUtils.setField(rootView.getClass(), name, field.get(name), functions);
                        } catch (NoSuchFieldException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                } else if (annotation instanceof XFunctionView) {
                    XFunctionView functionView = (XFunctionView) annotation;
                    String value = functionView.value();
                    int viewResId =  functionView.viewId();
                    if (viewResId == 0) {
                        //控制單個功能 顯示隱藏需要viewId配合
                        continue;
                    }
                    View view;
                    if (rootView instanceof Fragment) {
                        view = ((Fragment) rootView).getActivity().findViewById(viewResId);
                    } else {
                        view = ((Activity) rootView).findViewById(viewResId);
                    }
                    if (view == null) {
                        continue;
                    }
                    if (FModuleValue.containsKey(value)) {
                        //已配置此功能 顯示view
//                        Function function = getFunctionItem(value, FModuleValue.get(value));
                        view.setVisibility(View.VISIBLE);
                    } else {
                        //未配置此功能,隱藏當前view
                        view.setVisibility(View.GONE);
                    }
                }
            }
        }
    }

    @Override
    public List<Function> getFunctionItems(String targetResKey, FModule[] fModules) {
        List<Function> functionList = new ArrayList<>();
        if (mFunctionMap.size() == 0) {
            return functionList;
        }
        Iterator entries = mFunctionMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry entry = (Map.Entry) entries.next();
            String resUrl = (String) entry.getKey();
            //獲取具體的功能組，如table/bottom/init下的table/bottom組
            String[] keyRes = resUrl.split("/");
            if (keyRes.length > 1) {
                resUrl = resUrl.substring(0, keyRes[keyRes.length - 1].length());
                if (resUrl.startsWith(targetResKey)) {
                    /**
                     * 匹配功能組成功{@link XFunctionItems}
                     */
                    Function item = (Function) entry.getValue();
                    functionList.add(item);
                }
            }
        }
        for (int i = 0; i < functionList.size(); i++) {
            Function function = functionList.get(i);
            for (int j = 0; j < fModules.length; j++) {
                FModule module = fModules[j];
                if (function.getResUrl().equals(module.getKeyRes())) {
                    function.setIcRes(module.getOpenIconRes());
                }
            }
        }
        return functionList;
    }

    @Override
    public Function getFunctionItem(String targetResKey, FModule fModules) {
        if (mFunctionMap.size() == 0) {
            return null;
        }
        Iterator entries = mFunctionMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry entry = (Map.Entry) entries.next();
            String resUrl = (String) entry.getKey();
            if (targetResKey.equals(resUrl)) {
                /**
                 * 匹配單個功能成功{@link XFunctionItem}
                 */
                Function function = (Function) entry.getValue();
                if (function.getResUrl().equals(fModules.getKeyRes())) {
                    function.setIcRes(fModules.getOpenIconRes());
                }
                return function;
            }
        }
        return null;
    }

    @Override
    public List<Function> getFunctionsByResModule(List<Function> functionList) {
        return null;
    }

    @Override
    public void updateFunctions(List<Function> functions) {
        if (functions == null) {
            return;
        }
        if (mFunctionMap.size() > 0) {
            mFunctionMap.clear();
        }
        for (Function function : functions) {
            mFunctionMap.put(function.getResUrl(), function);
        }
    }

}
