package com.kidozh.discuzhub.utilities;

import android.util.Log;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.kidozh.discuzhub.entities.FavoriteThread;
import com.kidozh.discuzhub.entities.Smiley;
import com.kidozh.discuzhub.entities.User;
import com.kidozh.discuzhub.results.AddCheckResult;
import com.kidozh.discuzhub.results.DisplayThreadsResult;
import com.kidozh.discuzhub.results.FavoriteThreadResult;
import com.kidozh.discuzhub.results.SecureInfoResult;
import com.kidozh.discuzhub.results.PostParameterResult;
import com.kidozh.discuzhub.results.UserFriendResult;
import com.kidozh.discuzhub.results.UserNoteListResult;
import com.kidozh.discuzhub.results.UserProfileResult;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class bbsParseUtils {
    private static String TAG = bbsParseUtils.class.getSimpleName();

    public static AddCheckResult parseCheckInfoResult(String s) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(s, AddCheckResult.class);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public static UserProfileResult parseUserProfileResult(String s){
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            return mapper.readValue(s, UserProfileResult.class);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Boolean isPostThreadSuccessful(String s) {
        try {
            JSONObject jsonObject = new JSONObject(s);
            JSONObject message = jsonObject.getJSONObject("Message");
            return message.getString("messageval").equals("post_newthread_succeed");
        } catch (Exception e) {
            return false;
        }
    }

    public static Boolean isPostReplySuccessful(String s) {
        try {
            JSONObject jsonObject = new JSONObject(s);
            JSONObject message = jsonObject.getJSONObject("Message");
            return message.getString("messageval").equals("post_reply_succeed");
        } catch (Exception e) {
            return false;
        }
    }

    public static String parsePostThreadInfo(String s) {
        try {
            JSONObject jsonObject = new JSONObject(s);
            JSONObject message = jsonObject.getJSONObject("Message");
            return message.getString("messagestr");
        } catch (Exception e) {
            return null;
        }
    }

    public static class publicMessage {
        public int id, authorId;
        public Date publishAt;
        public String message;

        public publicMessage(int id, int authorId, Date publishAt, String message) {
            this.id = id;
            this.authorId = authorId;
            this.publishAt = publishAt;
            this.message = message;
        }
    }

    public static List<publicMessage> parsePublicMessage(String s) {
        try {
            List<publicMessage> publicMessageList = new ArrayList<>();
            JSONObject jsonObject = new JSONObject(s);
            JSONObject variables = jsonObject.getJSONObject("Variables");
            JSONArray pmList = variables.getJSONArray("list");
            for (int i = 0; i < pmList.length(); i++) {
                JSONObject pm = (JSONObject) pmList.get(i);
                int id = Integer.parseInt(pm.getString("id"));
                int authorId = Integer.parseInt(pm.getString("authorid"));
                String message = pm.getString("message");
                String publishAtStringTimestamp = pm.getString("dateline");
                Date publishAt = new Timestamp(Long.parseLong(publishAtStringTimestamp) * 1000);
                publicMessageList.add(new publicMessage(id, authorId, publishAt, message));
            }
            return publicMessageList;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static class privateMessage implements Serializable {
        public int plid;
        public Boolean isNew;
        public String subject;
        public int toUid;
        public int pmid;
        public int msgFromId;
        public String msgFrom;
        public String message;
        public String toUsername;
        public String vdateLine;

        public privateMessage(int plid, Boolean isNew, String subject, int toUid, int pmid, int msgFromId, String msgFrom, String message, String toUsername, String vdateLine) {
            this.plid = plid;
            this.isNew = isNew;
            this.subject = subject;
            this.toUid = toUid;
            this.pmid = pmid;
            this.msgFromId = msgFromId;
            this.msgFrom = msgFrom;
            this.message = message;
            this.toUsername = toUsername;
            this.vdateLine = vdateLine;
        }
    }

    public static List<privateMessage> parsePrivateMessage(String s) {
        try {
            List<privateMessage> privateMessageList = new ArrayList<>();
            JSONObject jsonObject = new JSONObject(s);
            JSONObject variables = jsonObject.getJSONObject("Variables");
            JSONArray pmList = variables.getJSONArray("list");
            for (int i = 0; i < pmList.length(); i++) {
                JSONObject pm = (JSONObject) pmList.get(i);
                privateMessage privateMessageInstance = new privateMessage(
                        Integer.parseInt(pm.getString("plid")),
                        !pm.getString("isnew").equals("0"),
                        pm.getString("subject"),
                        Integer.parseInt(pm.getString("touid")),
                        Integer.parseInt(pm.getString("pmid")),
                        Integer.parseInt(pm.optString("msgfromid", "0")),
                        pm.optString("msgfrom", ""),
                        pm.optString("message", ""),
                        pm.getString("tousername"),
                        pm.getString("vdateline")
                );
                privateMessageList.add(privateMessageInstance);

            }
            return privateMessageList;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static class privateDetailMessage implements Serializable {
        public int plid;
        public String subject;
        public int pmid;
        public String message;
        public int touid, msgFromId;
        public String msgFrom;
        public String vDateline;
        public Boolean isMyself;


        public privateDetailMessage(int plid, String subject, int pmid, String message, int touid, int msgFromId, String msgFrom, String vDateline, Boolean isMyself) {
            this.plid = plid;
            this.subject = subject;
            this.pmid = pmid;
            this.message = message;
            this.touid = touid;
            this.msgFromId = msgFromId;
            this.msgFrom = msgFrom;
            this.vDateline = vDateline;
            this.isMyself = isMyself;
        }
    }

    public static List<privateDetailMessage> parsePrivateDetailMessage(String s, int recvId) {
        try {
            List<privateDetailMessage> privateDetailMessageList = new ArrayList<>();
            JSONObject jsonObject = new JSONObject(s);
            JSONObject variables = jsonObject.getJSONObject("Variables");
            JSONArray pmList = variables.getJSONArray("list");
            for (int i = 0; i < pmList.length(); i++) {
                JSONObject pm = (JSONObject) pmList.get(i);
                privateDetailMessage privateDetailMessage = new privateDetailMessage(
                        Integer.parseInt(pm.getString("plid")),
                        pm.getString("subject"),
                        Integer.parseInt(pm.getString("pmid")),
                        pm.optString("message", ""),
                        Integer.parseInt(pm.getString("touid")),
                        Integer.parseInt(pm.getString("msgfromid")),
                        pm.getString("msgfrom"),
                        pm.getString("vdateline"),
                        true
                );

                if (privateDetailMessage.msgFromId == recvId) {
                    privateDetailMessage.isMyself = true;
                } else {
                    privateDetailMessage.isMyself = false;
                }
                if (privateDetailMessage.message.length() != 0) {
                    privateDetailMessageList.add(privateDetailMessage);
                }


            }
            return privateDetailMessageList;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }




    public static UserFriendResult parseUserFriendsResult(String s) {
        try {

            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(s, UserFriendResult.class);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static class noticeNumInfo {
        public int push, pm, prompt, mypost;

        public noticeNumInfo(String push, String pm, String prompt, String mypost) {
            this.push = Integer.parseInt(push);
            this.pm = Integer.parseInt(pm);
            this.prompt = Integer.parseInt(prompt);
            this.mypost = Integer.parseInt(mypost);
        }

        public int getAllNoticeInfo() {
            return push + pm + prompt + mypost;
        }
    }

    public static noticeNumInfo parseNoticeInfo(String s) {
        try {
            JSONObject jsonObject = new JSONObject(s);
            JSONObject variables = jsonObject.getJSONObject("Variables");
            JSONObject notice = variables.getJSONObject("notice");
            String newpush = notice.getString("newpush");
            String newpm = notice.getString("newpm");
            String newprompt = notice.getString("newprompt");
            String newmypost = notice.getString("newmypost");
            return new noticeNumInfo(newpush, newpm, newprompt, newmypost);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static class returnMessage {
        @JsonProperty("messageval")
        public String value;
        @JsonProperty("messagestr")
        public String string;
    }

    public static returnMessage parseReturnMessage(String s) {
        try {
            ObjectMapper mapper = new ObjectMapper();

            JSONObject jsonObject = new JSONObject(s);
            JSONObject messageObj = jsonObject.getJSONObject("Message");
            return mapper.readValue(messageObj.toString(), returnMessage.class);


        } catch (Exception e) {
            // e.printStackTrace();
            return null;
        }
    }

    public static class OneZeroDeserializer extends JsonDeserializer<Boolean> {

        @Override
        public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            JsonToken currentToken = p.getCurrentToken();
            if (currentToken.equals(JsonToken.VALUE_STRING)) {
                String text = p.getText();
                if (text.equals("0") || text.equals("")) {
                    return Boolean.FALSE;
                } else {
                    return Boolean.TRUE;
                }

            } else if (currentToken.equals(JsonToken.VALUE_TRUE)) {
                return Boolean.TRUE;
            } else if (currentToken.equals(JsonToken.VALUE_FALSE)) {
                return Boolean.FALSE;
            } else if (currentToken.equals(JsonToken.VALUE_NULL)) {
                return Boolean.FALSE;
            }
            return Boolean.TRUE;
        }
    }



    public static PostParameterResult parseThreadPostParameter(String s) {
        try {

            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(s, PostParameterResult.class);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static SecureInfoResult parseSecureInfoResult(String s) {
        try {

            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(s, SecureInfoResult.class);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static FavoriteThreadResult getFavoriteThreadResult(String s) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(s, FavoriteThreadResult.class);


        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
