package com.efounder.chat.item.manager;

import android.content.Context;
import android.view.ViewGroup;

import com.efounder.chat.R;
import com.efounder.chat.item.AnimationItem;
import com.efounder.chat.item.CallingCardMessageItem;
import com.efounder.chat.item.ChatTipsMessageItem;
import com.efounder.chat.item.CommandMessageItem;
import com.efounder.chat.item.CommonLikeOrCommentMessageItem;
import com.efounder.chat.item.CommonMessageItem;
import com.efounder.chat.item.FileMessageItem;
import com.efounder.chat.item.FormMessageItem;
import com.efounder.chat.item.FormMessageItemNative;
import com.efounder.chat.item.GXTaskMessageItem;
import com.efounder.chat.item.GotoApplicationMessageItem;
import com.efounder.chat.item.ImageMessageItem;
import com.efounder.chat.item.LocationMapItem;
import com.efounder.chat.item.MeetingMessageItem;
import com.efounder.chat.item.NotificationItem;
import com.efounder.chat.item.PayCardItem;
import com.efounder.chat.item.PublicNumberMessageItem;
import com.efounder.chat.item.ReCallMessageItem;
import com.efounder.chat.item.RecognitionMessageItem;
import com.efounder.chat.item.RedPackageItem;
import com.efounder.chat.item.ShareMessageItem;
import com.efounder.chat.item.TGTaskFormMessageItem;
import com.efounder.chat.item.TangZuMessageItem;
import com.efounder.chat.item.TransferItem;
import com.efounder.chat.item.VideoMessageItem;
import com.efounder.chat.item.VoiceItem;
import com.efounder.chat.item.VoiceRecognitionItem;
import com.efounder.chat.item.ZoneMessageItem;
import com.efounder.chat.struct.MessageChildTypeConstant;
import com.efounder.message.struct.IMStruct002;
import com.efounder.pansoft.chat.messageview.item.JFTextMessageItem;
import com.efounder.pansoft.chat.messageview.item.SecretFileMessageItem;
import com.efounder.pansoft.chat.messageview.item.SecretLetterMessageItem;
import com.efounder.pansoft.chat.messageview.item.SecretPictureMessageItem;
import com.efounder.pansoft.chat.messageview.item.TextFormatMessageItem;
import com.efounder.util.AppContext;
import com.utilcode.util.LogUtils;
import com.utilcode.util.ReflectUtils;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class JFMessageItemManager {
    public JFMessageItemManager() {
    }

    private static Map<String, ArrayList<IMessageItem>> messageItemPool = new HashMap<String, ArrayList<IMessageItem>>();

    public static IMessageItem getMessageItem(Context context, IMStruct002 message) {
        IMessageItem item = null;
        //TODO 根据message的type switch类型  如果不是new出来的 调prepareForReuse方法  返回前改成inUse
        //1.从池中获取未使用的Item，如果为null，new一个，并加入池中
        short messageChildType = message.getMessageChildType();
        if (message.isRecall()) {
            //如果消息已经撤回(真实消息类型不会改变，我们只是把它当成撤回消息处理)
            messageChildType = MessageChildTypeConstant.subtype_recallMessage;
        }
        //复用池的key
        String poolKey = messageChildType + "";
        if (messageChildType == MessageChildTypeConstant.subtype_custom_with_avatar
                || messageChildType == MessageChildTypeConstant.subtype_custom_without_avatar) {
            poolKey = getItemViewClass(message);
        }

        item = getUnuseItem(poolKey, message);
        if (item == null) {
            //创建item
            item = createItem(context, messageChildType, message, poolKey);
            //加入池中
            addItemPool(poolKey, item);
        }
        //2.调prepareForReuse方法
        item.prepareForReuse();
        //3.返回前改成inUse
        item.setIsInUse(true);
        return item;
    }

    /**
     * 创建消息item
     *
     * @param context
     * @param messageChildType 消息类型
     * @param message
     * @param poolKey          自定义消息的viewclass
     * @return
     */
    private static IMessageItem createItem(Context context, int messageChildType, IMStruct002 message, String poolKey) {
        IMessageItem item = null;
        switch (messageChildType) {
            case MessageChildTypeConstant.subtype_text://文本
                item = new JFTextMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_mZoneNotification://空间通知
                item = new ZoneMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_officalAccount://公众号 item
                item = new PublicNumberMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_callingCard://名片
                item = new CallingCardMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_payCard://支付
                item = new PayCardItem(context);
                break;
            case MessageChildTypeConstant.subtype_task://应用跳转
                item = new GotoApplicationMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_smallVideo:
                item = new VideoMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_form:
                item = new FormMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_form_native:
                item = new FormMessageItemNative(context);
                break;
//			case MessageChildTypeConstant.subtype_image:
//				item = new ImageMessageItem(context);
//				break;
            case MessageChildTypeConstant.subtype_voice:
                item = new VoiceItem(context);
                break;
            case MessageChildTypeConstant.subtype_location:
                item = new LocationMapItem(context);
                break;
            case MessageChildTypeConstant.subtype_feiyongbaoxiao:
                item = new FeiyongBaoxiaoCardItem(context);
                break;
            case MessageChildTypeConstant.subtype_oa:
                item = new OACardItem(context);
                break;
            case MessageChildTypeConstant.subtype_command:
                item = new CommandMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_recallMessage://撤回
                item = new ReCallMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_officalweb://网页
                item = new WebMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_zy_task://网页
                item = new TGTaskFormMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_xj_item1://新疆carditem1
                try {
                    item = ReflectUtils.reflect("com.efounder.messageItem.CardMessageItem").newInstance(context).get();
//                    ClassLoader loader = Thread.currentThread().getContextClassLoader();
//                    Class<?> clazz = loader.loadClass("com.efounder.messageItem.CardMessageItem");
//                    //获取有参构造器，根据参数类型。
//                    Constructor<?> cons1 = clazz.getDeclaredConstructor(Context.class);
//                    //实例化
//                    item = (IMessageItem) cons1.newInstance(context);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case MessageChildTypeConstant.subtype_common:// 通用
                item = new CommonMessageItem(context);
//              item = new GXTaskMessageItem(context);
//				item = new TangZuMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_file:// 文件
                // item = new ImageMessageItem(context,datas);
                item = new FileMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_TangZuItem:// 糖足item
                //item = new NativePageItem(context);
                item = new TangZuMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_meeting://会议消息item
                item = new MeetingMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_recognition://人脸识别消息item
                item = new RecognitionMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_gxtask://共享任务消息item
                item = new GXTaskMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_image:// 图片
                item = new ImageMessageItem(context, null);
                break;
            case MessageChildTypeConstant.subtype_anim:// 动画
                item = new AnimationItem(context);
                break;
            case MessageChildTypeConstant.subtype_transfer:// 转账
                item = new TransferItem(context);
                break;
            case MessageChildTypeConstant.subtype_secret_text://密信
                item = new SecretLetterMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_secret_image://密图
                item = new SecretPictureMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_secret_file://密件
                item = new SecretFileMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_notification://通告item
                item = new NotificationItem(context);
                break;
//            case MessageChildTypeConstant.subtype_share_goods://分享商品
//                item= new ShareGoodsItem(context);
//                break;
            case MessageChildTypeConstant.subtype_share_web://分享
                item = new ShareMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_red_package://红包
                item = new RedPackageItem(context);
                break;
            case MessageChildTypeConstant.subtype_speechRecognize://语音识别
                item = new VoiceRecognitionItem(context);
                break;
            case MessageChildTypeConstant.subtype_chat_tips://提示消息（类似加群通知等）
                item = new ChatTipsMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_format_text://json格式的文本消息
                item = new TextFormatMessageItem(context);
                break;
            case MessageChildTypeConstant.subtype_subtype_general_common_message:// 通用评论消息item
                item = new CommonLikeOrCommentMessageItem(context);
                break;

            case MessageChildTypeConstant.subtype_custom_with_avatar:// 自定义有头像
            case MessageChildTypeConstant.subtype_custom_without_avatar:// 自定义无头像（应用号）
                String viewClass = poolKey;
                // getItemViewClass(message);
                try {
                    item = ReflectUtils.reflect(viewClass).newInstance(context).get();
                } catch (ReflectUtils.ReflectException e) {
                    LogUtils.e(viewClass + "不存在");
                    item = new JFTextMessageItem(context);
                }
                break;
            default:
                // TODO: 17-8-13  其他消息类型先显示文本，防止程序崩溃
//                item = new JFTextMessageItem(context);
                item = getOtherItemByReflect(context, messageChildType);
                break;
        }
        return item;
    }


    //通过反射获取其他消息
    private static IMessageItem getOtherItemByReflect(Context context, int messageChildType) {
        IMessageItem item = new JFTextMessageItem(context);
        try {
            String[] messageTypeArray = AppContext.getInstance().getResources().getStringArray(R.array.reflect_chat_message_type);
            String[] messageTypeClassArray = AppContext.getInstance().getResources().getStringArray(R.array.reflect_chat_message_type_class);
            if (messageTypeArray.length != messageTypeClassArray.length) {
                return item;
            }
            int position = Arrays.asList(messageTypeArray).indexOf(messageChildType + "");
            if (position < 0) {
                return item;
            }
            //反射配置的相应类
            String className = messageTypeClassArray[position];
            item = ReflectUtils.reflect(className).newInstance(context).get();
            return item;
        } catch (Exception e) {
            e.printStackTrace();
            return item;
        }

    }

    /**
     * item添加到复用池
     *
     * @param key
     * @param item
     */
    private static void addItemPool(String key, IMessageItem item) {
        ArrayList<IMessageItem> itemList = messageItemPool.get(key);
        if (itemList == null) {
            itemList = new ArrayList<IMessageItem>();
            messageItemPool.put(key, itemList);
        }
        itemList.add(item);
    }

    /**
     * 复用池中获取未使用的item
     *
     * @param key         消息类型
     * @param imStruct002 消息体
     * @return
     */
    private static IMessageItem getUnuseItem(String key, IMStruct002 imStruct002) {
        IMessageItem item = null;
        ArrayList<IMessageItem> itemList = messageItemPool.get(key);
        if (itemList == null) {
            return null;
        }

        IMessageItem temp = null;
        for (int i = 0; i < itemList.size(); i++) {
            temp = itemList.get(i);
            if (!temp.getIsInUse()) {
                item = temp;
                //从父控件中删除
                //  Log.i("yqs", "-----从池中获取一个未使用的item:" + item + "，item类型：" + key + "item的hashcode" + item.hashCode());
                ViewGroup parentView = (ViewGroup) (item.messageView().getParent());
                if (parentView != null) {
                    parentView.removeView(item.messageView());
                }
                break;
            }
        }
        return item;
    }

    /**
     * 释放资源
     */
    public static void release() {
        messageItemPool.clear();
    }

    /**
     * 从消息中获取自定义view的类名
     *
     * @param imStruct002
     * @return
     */
    private static String getItemViewClass(IMStruct002 imStruct002) {
        String message = imStruct002.getMessage();
        JSONObject messageObject = null;
        try {
            messageObject = new JSONObject(message);
            //androidView iOSView 必填字段
            String viewClass = messageObject.optString("androidView");
            return viewClass;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}