package seedu.dailyplanner.model.task;

import java.util.Objects;

import seedu.dailyplanner.commons.util.CollectionUtil;
import seedu.dailyplanner.commons.util.DateUtil;
import seedu.dailyplanner.commons.util.StringUtil;
import seedu.dailyplanner.model.tag.UniqueTagList;

/**
 * Represents a Person in the address book. Guarantees: details are present and
 * not null, field values are validated.
 */
public class Task implements ReadOnlyTask, Comparable<Task> {

	private String taskName;
	private DateTime start;
	private DateTime end;
	private boolean isComplete;
	private boolean isPinned;
	private UniqueTagList tags;

	/**
	 * Every field must be present and not null.
	 */
	public Task(String name, DateTime start, DateTime end, boolean isComplete, boolean isPinned, UniqueTagList tags) {
		assert !CollectionUtil.isAnyNull(name, start, end, isComplete, isPinned, tags);
		this.taskName = name;
		this.start = start;
		this.end = end;
		this.tags = new UniqueTagList(tags); // protect internal tags from
		// changes in the arg list
		this.isComplete = isComplete;
		this.isPinned = isPinned;
	}

	/**
	 * Copy constructor.
	 */
	public Task(ReadOnlyTask source) {
		this(source.getName(), source.getStart(), source.getEnd(), source.isComplete(), source.isPinned(),
				source.getTags());
	}

	@Override
	public void setName(String name) {
		this.taskName = name;
	}

	@Override
	public void setStart(DateTime startDate) {
		this.start = startDate;
	}

	@Override
	public void setEnd(DateTime endDate) {
		this.end = endDate;
	}

	@Override
	public void markAsComplete() {
		this.isComplete = true;
	}

	@Override
	public void markAsNotComplete() {
		this.isComplete = false;
	}

	public void pin() {
		this.isPinned = true;
	}

	public void unpin() {
		this.isPinned = false;
	}

	private String calculateDueStatus(DateTime end) {
		if (end.getTime().toString().equals("")) {
			return "";

		}
		DateTime nowAsDateTime = DateUtil.nowAsDateTime();
		// if end is strictly before the current date and time
		if (DateUtil.checkDatePrecedence(end, nowAsDateTime)) {
			return "OVERDUE";
		}
		// if end date is same as current date
		else if (end.getDate().equals(nowAsDateTime.getDate())) {
			// if end time is before or equal to current time
			if (end.getTime().compareTo(nowAsDateTime.getTime()) <= 0) {
				return "OVERDUE";
			} else {
				int endHour = DateUtil.convertTo24HrFormat(end.getTime());
				int nowHour = DateUtil.convertTo24HrFormat(nowAsDateTime.getTime());
				int overDueHours = endHour - nowHour;
				if (overDueHours <= 3) {
					return "DUE SOON";
				}
			}
		}
		return "";
	}

	@Override
	public String getName() {
		return taskName;
	}

	@Override
	public DateTime getStart() {
		return start;
	}

	@Override
	public DateTime getEnd() {
		return end;
	}

	@Override
	public String getCompletion() {
		return (isComplete) ? "COMPLETE" : "NOT COMPLETE";
	}

	@Override
	public String getDueStatus() {
		return calculateDueStatus(end);
	}

	@Override
	public boolean isComplete() {
		return isComplete;
	}

	@Override
	public void setCompletion(boolean completion) {
		isComplete = completion;
	}

	public boolean isPinned() {
		return isPinned;
	}

	@Override
	public UniqueTagList getTags() {
		return new UniqueTagList(tags);
	}

	/**
	 * Replaces this task's tags with the tags in the argument tag list.
	 */
	public void setTags(UniqueTagList replacement) {
		tags.setTags(replacement);
	}

	@Override
	public boolean equals(Object other) {
		return other == this // short circuit if same object
				|| (other instanceof ReadOnlyTask // instanceof handles nulls
						&& this.isSameStateAs((ReadOnlyTask) other));
	}

	@Override
	public int hashCode() {
		return Objects.hash(taskName, start, end, isComplete, isPinned, tags);
	}

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

	@Override
	public int compareTo(Task o) {
		if (!start.equals(o.start)) {
			return start.compareTo(o.start);
		} else if (!end.equals(o.end)) {
			return end.compareTo(o.end);
		} else
			return taskName.compareTo(o.taskName);
	}

}

@@ -1839,35 +1839,76 @@
  %7B%0A%09
-%09if (end.getTime().toString
+%0A%09%09// if there is no end date, return empty string%0A%09%09if (end.getDate
 ().e
@@ -1934,21 +1934,23 @@
 urn %22%22;%0A
-%0A
 %09%09%7D%0A
+%09%09%0A
 %09%09DateTi
@@ -1994,16 +1994,19 @@
 Time();%0A
+%09%09%0A
 %09%09// if 
@@ -2009,16 +2009,21 @@
  if end 
+date 
 is stric
@@ -2033,20 +2033,16 @@
  before 
-the 
 current 
@@ -2049,100 +2049,225 @@
 date
- and time%0A%09%09if (DateUtil.checkDatePrecedence(end, nowAsDateTime)) %7B%0A%09%09%09return %22OVERDUE%22;%0A%09%09%7D
+%0A%09%09if (end.getDate().compareTo(nowAsDateTime.getDate()) %3C 0 ) %7B%0A%09%09%09return %22OVERDUE%22;%0A%09%09%7D%0A%09%09%0A%09%09// if end date is today or later but there is no end time%0A%09%09if (end.getTime().toString().equals(%22%22)) %7B%0A%09%09%09return %22%22;%0A%09%09%7D%0A%09%09
 %0A%09%09/

Fix overdue bug