package com.rv.im.db.dao;

import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;

import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.stmt.QueryBuilder;
import com.rv.im.ImSetting;
import com.rv.im.db.SQLiteHelper;
import com.rv.im.db.table.ChatMessage;
import com.rv.im.enums.MessageStatusEnum;
import com.rv.im.log.LogUtil;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class MessageDao {

    private static final String TAG = MessageDao.class.getSimpleName();
    public Dao<ChatMessage, Integer> dao;

    private OrmLiteSqliteOpenHelper mHelper;
    private Context mContext;

    public MessageDao(Context context) {
        try {
            this.mContext = context;
            mHelper = SQLiteHelper.getInstance(context);
            dao = DaoManager.createDao(SQLiteHelper.getInstance(context).getConnectionSource(), ChatMessage.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        OpenHelperManager.releaseHelper();
    }


    public int getPages(String userId) {
        String sql_page = "select count(*) from tb_message where fromUserId=? or toUserId=?";
        Cursor cursor;
        cursor = mHelper.getReadableDatabase().rawQuery(sql_page, new String[]{userId, userId});
        cursor.moveToLast();
        return cursor.getInt(0);
    }

    /*******
     * 插入消息
     * @param message
     */
    public void addMessage(ChatMessage message) {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return;
        }
        if (message == null) {
            LogUtil.e(TAG, "message is null");
            return;
        }
        Log.d(TAG, message.toString());
        if (isExit(message)) {
            updateMessage(message);
            return;
        }
        try {
            int result = dao.create(message);
            LogUtil.d(TAG, "插入结果 " + result);
        } catch (SQLException e) {
            e.printStackTrace();
            LogUtil.d(TAG, "插入失败 " + e.getMessage());
        }
    }

    /*****
     * 更新消息
     * @param message
     */
    public void updateMessage(ChatMessage message) {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return;
        }
        if (message == null) {
            LogUtil.e(TAG, "message is null");
            return;
        }
        try {
            dao.update(message);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /*****
     * 删除消息
     * @param message
     */
    public void deleteMessage(ChatMessage message) {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return;
        }
        if (message == null) {
            LogUtil.e(TAG, "message is null");
            return;
        }
        try {
            dao.delete(message);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /*******
     * 判断是否存在该消息
     * @param message
     * @return
     */
    public boolean isExit(ChatMessage message) {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return false;
        }
        if (message == null) {
            LogUtil.e(TAG, "message is null");
            return false;
        }
        try {
            List<ChatMessage> lists = dao.queryForEq("packId", message.getPackId());
            return lists == null ? false : lists.size() == 0 ? false : true;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    /******
     * 根据对方的消息id 获取所有聊天
     * @param targetId
     * @return
     */
    public List<ChatMessage> getAllChatMessageByConversation(String targetId) {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return null;
        }
        if (TextUtils.isEmpty(targetId)) {
            LogUtil.e(TAG, "message is null");
            return null;
        }
        List<ChatMessage> chatMessages = null;
        try {
            chatMessages = dao.queryBuilder().orderBy("timeSend", true)
                    .where()
                    .eq("fromUserId", targetId)
                    .or()
                    .eq("toUserId", targetId)
                    .query();
            if (chatMessages != null) {
                Collections.sort(chatMessages, (o1, o2) -> (int) (o1.getTimeSend() - o2.getTimeSend()));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return chatMessages;
    }


    public void setMsgSuccess(String receiptId) {
        try {
            List<ChatMessage> chatMessages = dao.queryBuilder().orderBy("timeSend", false).where().eq("packId", receiptId).query();
            if (chatMessages != null && chatMessages.size() > 0) {
                ChatMessage message = chatMessages.get(0);
                message.setMessageStatus(MessageStatusEnum.SUCCESS);
                updateMessage(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void setUpProgress(String packId, int progress) {
        try {
            List<ChatMessage> chatMessages = dao.queryBuilder().orderBy("timeSend", false).where().eq("packId", packId).query();
            if (chatMessages != null && chatMessages.size() > 0) {
                ChatMessage message = chatMessages.get(0);
                message.setUploadSchedule(progress);
                updateMessage(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void setUpFailure(String packId) {
        try {
            List<ChatMessage> chatMessages = dao.queryBuilder().orderBy("timeSend", false).where().eq("packId", packId).query();
            if (chatMessages != null && chatMessages.size() > 0) {
                ChatMessage message = chatMessages.get(0);
                message.setUpLoadStatus(3);
                updateMessage(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void setSendFailure(String packId) {
        try {
            List<ChatMessage> chatMessages = dao.queryBuilder().orderBy("timeSend", false).where().eq("packId", packId).query();
            if (chatMessages != null && chatMessages.size() > 0) {
                ChatMessage message = chatMessages.get(0);
                message.setMessageStatus(MessageStatusEnum.FAIL);
                updateMessage(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void setUpSuccess(String packId, String url) {

        try {
            List<ChatMessage> chatMessages = dao.queryBuilder().orderBy("timeSend", false).where().eq("packId", packId).query();
            if (chatMessages != null && chatMessages.size() > 0) {
                ChatMessage message = chatMessages.get(0);
                message.setUpLoadStatus(2);
                message.setContent(url);
                updateMessage(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public ChatMessage getLastMsgByUserId(String userId) {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return null;
        }
        if (TextUtils.isEmpty(userId)) {
            LogUtil.e(TAG, "userId is null");
            return null;
        }
        List<ChatMessage> chatMessages = null;
        try {
            chatMessages = dao.queryBuilder().orderBy("timeSend", false).where().
                    eq("fromUserId", userId)
                    .or()
                    .eq("toUserId", userId)
                    .query();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        if (chatMessages != null && chatMessages.size() > 0) {
            return chatMessages.get(0);
        }
        return null;
    }

    public int getUnReadMessage(String userId) {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return 0;
        }
        if (TextUtils.isEmpty(userId)) {
            LogUtil.e(TAG, "userId is null");
            return 0;
        }
        List<ChatMessage> chatMessages = null;
        try {
            chatMessages = dao.queryBuilder().where()
                    .eq("fromUserId", userId)
                    .and()
                    .eq("isRead", false)
                    .query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return chatMessages != null ? chatMessages.size() : 0;
    }


    /***********
     * 获取所有未读的消息
     * @return
     */
    public int getUnReadMessage() {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return 0;
        }
        List<ChatMessage> chatMessages = null;
        try {
            chatMessages = dao.queryBuilder().where()
                    .eq("isRead", false)
                    .and()
                    .eq("toUserId", ImSetting.getUserId())
                    .query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return chatMessages != null ? chatMessages.size() : 0;
    }

    public void setMessageRead(String userId) {
        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return;
        }
        if (TextUtils.isEmpty(userId)) {
            LogUtil.e(TAG, "userId is null");
            return;
        }
        List<ChatMessage> chatMessages;
        try {
            chatMessages = dao.queryBuilder().orderBy("timeSend", false).where()
                    .eq("fromUserId", userId)
                    .or()
                    .eq("toUserId", userId)
                    .and()
                    .eq("isRead", false)
                    .query();
            if (chatMessages != null && chatMessages.size() > 0) {
                for (ChatMessage message : chatMessages) {
                    message.setRead(true);
                    updateMessage(message);
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void setVoicePlay(String packId) {

        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return;
        }
        if (TextUtils.isEmpty(packId)) {
            LogUtil.e(TAG, "packId is null");
            return;
        }
        List<ChatMessage> chatMessages;
        try {
            chatMessages = dao.queryBuilder().orderBy("timeSend", false).where()
                    .eq("packId", packId)
                    .query();
            if (chatMessages != null && chatMessages.size() > 0) {
                ChatMessage message = chatMessages.get(0);
                message.setVoiceStatus(1);
                updateMessage(message);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public List<ChatMessage> loadMoreMessage(String userId, long time) {

        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return null;
        }
        if (TextUtils.isEmpty(userId)) {
            LogUtil.e(TAG, "userId is null");
            return null;
        }
        QueryBuilder<ChatMessage, Integer> builder = dao.queryBuilder();
        List<ChatMessage> chatMessages = null;
        try {
            // builder.where().gt("_id", mMinId);
            builder.where().eq("fromUserId", userId)
                    .or()
                    .eq("toUserId", userId);
            builder.where().lt("timeSend", time);
            builder.orderBy("timeSend", false);
            builder.limit(20L);
            builder.offset(0L);
            chatMessages = dao.query(builder.prepare());
            if (chatMessages != null) {
                Collections.sort(chatMessages, (o1, o2) -> (int) (o1.getTimeSend() - o2.getTimeSend()));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return chatMessages;
    }

    public List<ChatMessage> getFirstPageMessage(String userId) {

        if (dao == null) {
            LogUtil.e(TAG, "dao is null");
            return null;
        }
        if (TextUtils.isEmpty(userId)) {
            LogUtil.e(TAG, "message is null");
            return null;
        }
        List<ChatMessage> chatMessages = null;
        try {
            chatMessages = dao.queryBuilder().orderBy("timeSend", false)
                    .limit(20L)
                    .where()
                    .eq("fromUserId", userId)
                    .or()
                    .eq("toUserId", userId)
                    .query();
            if (chatMessages != null) {
                Collections.sort(chatMessages, (o1, o2) -> (int) (o1.getTimeSend() - o2.getTimeSend()));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return chatMessages;
    }
}
