package seedu.tache.logic.commands;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import seedu.tache.commons.exceptions.IllegalValueException;
import seedu.tache.logic.commands.exceptions.CommandException;
import seedu.tache.model.tag.Tag;
import seedu.tache.model.tag.UniqueTagList;
import seedu.tache.model.task.DateTime;
import seedu.tache.model.task.Name;
import seedu.tache.model.task.Task;
import seedu.tache.model.task.Task.RecurInterval;
import seedu.tache.model.task.UniqueTaskList;
import seedu.tache.model.task.UniqueTaskList.TaskNotFoundException;

/**
 * Adds a task to the task manager.
 */
public class AddCommand extends Command implements Undoable {

    public static final String COMMAND_WORD = "add";

    public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a task to the task manager. "
            + "Parameters: NAME [;START DATE & TIME] [;END DATE & TIME] [;TAG...]\n"
            + "Example: " + COMMAND_WORD
            + " Orientation week camp; 25/7/16 0800; 28/7/2016 0900; HighPriority; Events";

    public static final String MESSAGE_SUCCESS = "New task added: %1$s";
    public static final String MESSAGE_DUPLICATE_TASK = "This task already exists in the task manager";
    public static final String MESSAGE_TASK_NOT_FOUND = "%1$s no longer exists in the task manager";

    private final Task toAdd;
    private boolean commandSuccess;

    /**
     * Creates an AddCommand using raw name and tags value.
     *
     * @throws IllegalValueException if any of the raw values are invalid
     */
    public AddCommand(String name, Set<String> tags)
            throws IllegalValueException {
        final Set<Tag> tagSet = new HashSet<>();
        for (String tagName : tags) {
            tagSet.add(new Tag(tagName));
        }
        this.toAdd = new Task(
                new Name(name),
                new UniqueTagList(tagSet)
        );
        commandSuccess = false;
    }

    //@@author A0150120H
    /**
     * Creates an AddCommand using raw name, start date & time, end date & time, and tags values.
     *
     * @throws IllegalValueException if any of the raw values are invalid
     */
    public AddCommand(String nameStr, String startDateStr, String startTimeStr, Optional<String> endDateStr,
            Optional<String> endTimeStr, Set<String> tagsStr) throws IllegalValueException {
        final Set<Tag> tagSet = new HashSet<>();
        for (String tagName : tagsStr) {
            tagSet.add(new Tag(tagName));
        }
        Name name = new Name(nameStr);
        Optional<DateTime> startDateTime = Optional.of(new DateTime(startDateStr + startTimeStr));
        Optional<DateTime> endDateTime = Optional.empty();
        String endDate = "";
        String endTime = "";
        if (endDateStr.isPresent()) {
            endDate = endDateStr.get();
        }
        if (endTimeStr.isPresent()) {
            endTime = endTimeStr.get();
        }
        if (!(endDate.equals("") && endTime.equals(""))) {
            endDateTime = Optional.of(new DateTime(endDate + endTime));
        }
        UniqueTagList tagList = new UniqueTagList(tagSet);
        this.toAdd = new Task(name, startDateTime, endDateTime, tagList, true, true, false, RecurInterval.NONE);
        commandSuccess = false;
    }

    @Override
    public CommandResult execute() throws CommandException {
        assert model != null;
        try {
            model.addTask(toAdd);
            commandSuccess = true;
            undoHistory.push(this);
            return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd));
        } catch (UniqueTaskList.DuplicateTaskException e) {
            throw new CommandException(MESSAGE_DUPLICATE_TASK);
        }

    }

    @Override
    public boolean isUndoable() {
        return commandSuccess;
    }

    @Override
    public String undo() throws CommandException {
        try {
            model.deleteTask(toAdd);
            return String.format(MESSAGE_SUCCESS, toAdd);
        } catch (TaskNotFoundException e) {
            throw new CommandException(String.format(MESSAGE_TASK_NOT_FOUND, toAdd));
        }
    }
}


@@ -1415,555 +1415,8 @@
 s;%0A%0A
-    /**%0A     * Creates an AddCommand using raw name and tags value.%0A     *%0A     * @throws IllegalValueException if any of the raw values are invalid%0A     */%0A    public AddCommand(String name, Set%3CString%3E tags)%0A            throws IllegalValueException %7B%0A        final Set%3CTag%3E tagSet = new HashSet%3C%3E();%0A        for (String tagName : tags) %7B%0A            tagSet.add(new Tag(tagName));%0A        %7D%0A        this.toAdd = new Task(%0A                new Name(name),%0A                new UniqueTagList(tagSet)%0A        );%0A        commandSuccess = false;%0A    %7D%0A%0A
     
@@ -1665,30 +1665,40 @@
 ng nameStr, 
+Optional%3C
 String
+%3E
  startDateSt
@@ -1699,25 +1699,8 @@
 Date
-Str, String start
 Time
@@ -1728,16 +1728,20 @@
  endDate
+Time
 Str,%0A   
@@ -1752,37 +1752,8 @@
     
- Optional%3CString%3E endTimeStr,
  Set
@@ -1982,16 +1982,17 @@
 meStr);%0A
+%0A
         
@@ -2039,52 +2039,14 @@
 nal.
-of(new DateTime(startDateStr + startTimeStr)
+empty(
 );%0A 
@@ -2115,209 +2115,106 @@
     
-String endDate = %22%22;%0A        String endTime = %22%22;%0A        if (endDateStr.isPresent()) %7B%0A            endDate = endDateStr.get();%0A        %7D%0A        if (endTimeStr.isPresent()) %7B%0A            endTime = end
+if (startDateTimeStr.isPresent()) %7B%0A            startDateTime = Optional.of(new DateTime(startDate
 Time
@@ -2222,16 +2222,18 @@
 tr.get()
+))
 ;%0A      
@@ -2251,18 +2251,16 @@
  if 
-(!
 (endDate
 .equ
@@ -2259,41 +2259,26 @@
 Date
-.equals(%22%22) && endTime.equals(%22%22)
+TimeStr.isPresent(
 )) %7B
@@ -2340,18 +2340,21 @@
 Date
- + endTime
+TimeStr.get()
 ));%0A
@@ -2355,32 +2355,33 @@
 ()));%0A        %7D%0A
+%0A
         UniqueTa

Update AddCommand to match new Task implementation