package elements.messages;

import elements.exceptions.*;
import org.json.JSONObject;

import java.time.ZoneId;
import java.util.Date;

/**
 * Created by Guillermo Serrahima on 10/8/16.
 */
public abstract class Message {
    protected Long cid;         //chat id
    protected Integer mid;      //message id
    protected Integer uid;      //user id
    protected String chatType;  //chat type
    protected String fullName;  //author name
    protected String userName;  //username
    protected String chatName;  //chat name
    protected String text;      //the actual message
    protected Date timestamp;
    protected String consoleLog;

    public Message(JSONObject message) {
        cid = message.getJSONObject("chat").getLong("id");
        mid = message.getInt("message_id");
        chatType = message.getJSONObject("chat").getString("type");

        if (message.has("text"))
            text = message.getString("text");
        else text = null;

        consoleLog = message.toString();

        timestamp = new Date(new Long(message.getInt("date"))*1000);
    }

    public long getCid() {
        return cid;
    }

    public int getMid() {
        return mid;
    }

    public abstract boolean hasAuthor();

    public abstract int getUid() throws NoAuthorMessageException;

    public abstract String getAuthor() throws NoAuthorMessageException;

    protected boolean hasUsername() {
        return userName != null;
    }

    public abstract String getUsername() throws NoUsernameMessageException, NoAuthorMessageException;

    public boolean hasText() {
        return text != null;
    }

    public String getText() throws NoTextMessageException {
        if(!hasText()) throw new NoTextMessageException();
        return text;
    }

    public static Message getMessage(JSONObject message) throws MessageException {
        String type = message.getJSONObject("chat").getString("type");

        if(type.equals("group"))
            return new GroupMessage(message);
        if(type.equals("supergroup"))
            return new SupergroupMessage(message);
        if(type.equals("channel"))
            return new ChannelMessage(message);
        if(!type.equals("private"))
            throw new MessageException("Unidentified message.");

        return new PrivateMessage(message);
    }

    public abstract boolean isBasicGroup();

    public abstract boolean isSupergroup();

    public abstract boolean isChannel();

    public abstract boolean isPrivate();

    protected boolean hasChatName() {
        return chatName != null;
    }

    public abstract String getChatName();

    public boolean isGroup() {
        return isBasicGroup() || isSupergroup();
    }

    @Override
    public String toString() {
        return consoleLog;
    }

    public String getTimestamp() {
        return String.valueOf(timestamp);
    }

    public String getDate() {
        return String.valueOf(timestamp.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
    }
}
