package seedu.todo.controllers;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.joestelmach.natty.*;

import seedu.todo.commons.exceptions.UnmatchedQuotesException;
import seedu.todo.models.Event;
import seedu.todo.models.Task;
import seedu.todo.models.TodoListDB;
import seedu.todo.ui.UiManager;
import seedu.todo.ui.views.IndexView;

public class AddController implements Controller {
    
    private static String NAME = "Add";
    private static String DESCRIPTION = "Adds a task / event to the to-do list.";
    private static String COMMAND_SYNTAX = "add <task> by <deadline> || add <event> at <time>";
    
    private static CommandDefinition commandDefinition =
            new CommandDefinition(NAME, DESCRIPTION, COMMAND_SYNTAX); 

    public static CommandDefinition getCommandDefinition() {
        return commandDefinition;
    }

    @Override
    public float inputConfidence(String input) {
        // TODO
        return (input.startsWith("add")) ? 1 : 0;
    }
    
    private static Map<String, String[]> getTokenDefinitions() {
        Map<String, String[]> tokenDefinitions = new HashMap<String, String[]>();
        tokenDefinitions.put("default", new String[] {"add"});
        tokenDefinitions.put("eventType", new String[] { "event", "task" });
        tokenDefinitions.put("time", new String[] { "at", "by", "before", "time" });
        tokenDefinitions.put("timeFrom", new String[] { "from" });
        tokenDefinitions.put("timeTo", new String[] { "to" });
        return tokenDefinitions;
    }

    @Override
    public void process(String input) {
        
        Map<String, String[]> parsedResult;
        try {
            parsedResult = Tokenizer.tokenize(getTokenDefinitions(), input);            
        } catch (UnmatchedQuotesException e) {
            System.out.println("Unmatched quote!");
            return;
        }
        
        
        // Create and persist task / event.
        TodoListDB db = TodoListDB.getInstance();
        if (isTask) {
            Task newTask = db.createTask();
            newTask.setName(name);
            newTask.setDueDate(dateFrom);
        } else {
            Event newEvent = db.createEvent();
            newEvent.setName(name);
            newEvent.setStartDate(dateFrom);
            newEvent.setEndDate(dateTo);
        }
        db.save();
        
        // Re-render
        IndexView view = UiManager.loadView(IndexView.class);
        view.tasks = db.getAllTasks();
        view.events = db.getAllEvents();
        view.render();
    }
    
    private LocalDateTime parseNatural(String natural) {
        Parser parser = new Parser();
        List<DateGroup> groups = parser.parse(natural);
        Date date = null;
        try {
            date = groups.get(0).getDates().get(0);
        } catch (IndexOutOfBoundsException e) {
            System.out.println("Error!"); // TODO
            return null;
        }
        LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
        return ldt;
    }
    
}

@@ -1977,32 +1977,1558 @@
      %7D%0A        %0A
+        // Task or event?%0A        boolean isTask = true;%0A        if (parsedResult.get(%22eventType%22) != null && parsedResult.get(%22eventType%22)%5B0%5D.equals(%22event%22))%0A            isTask = false;%0A        %0A        // Name - Disambiguate if null.%0A        String name = null;%0A        if (parsedResult.get(%22default%22) != null && parsedResult.get(%22default%22)%5B1%5D != null)%0A            name = parsedResult.get(%22default%22)%5B1%5D;%0A        if (parsedResult.get(%22eventType%22) != null && parsedResult.get(%22eventType%22)%5B1%5D != null)%0A            name = parsedResult.get(%22eventType%22)%5B1%5D;%0A        if (name == null) %7B%0A            renderDisambiguation(parsedResult);%0A            return;%0A        %7D%0A        %0A        // Time - Disambiguate if %22to%22 without %22from%22 OR %22task%22 and two timings.%0A        String naturalFrom = null;%0A        String naturalTo = null;%0A        setTime: %7B%0A            if (parsedResult.get(%22time%22) != null && parsedResult.get(%22time%22)%5B1%5D != null) %7B%0A                naturalFrom = parsedResult.get(%22time%22)%5B1%5D;%0A                break setTime;%0A            %7D%0A            if (parsedResult.get(%22timeFrom%22) != null && parsedResult.get(%22timeFrom%22)%5B1%5D != null)%0A                naturalFrom = parsedResult.get(%22timeFrom%22)%5B1%5D;%0A            if (parsedResult.get(%22timeTo%22) != null && parsedResult.get(%22timeTo%22)%5B1%5D != null)%0A                naturalFrom = parsedResult.get(%22timeTo%22)%5B1%5D;%0A        %7D%0A        if ((naturalFrom == null && naturalTo != null) %7C%7C (isTask && naturalTo != null)) %7B%0A            renderDisambiguation(parsedResult);%0A            return;%0A        %7D%0A
         %0A       

Set variables from parsedResult.