#compdef todo.sh

_todo() {
    local curcontext="$curcontext" state state_descr line
    typeset -A opt_args
    local -a args commands subcmds

    local _todo_sh=${_todo_sh:-${words[1]}}
    local -r MOVE_COMMAND_PATTERN='(move|mv)'
    local -r OPTS=('-@' '-@@' '-+' '-++' '-d' '-f' '-h' '-p' '-P' '-PP' '-a' '-n' '-t' '-v' '-vv' '-V' '-x')
    local -r COMMANDS=(
        'add:a new task'
        'a:add alias'
        'addto:add to file'
        'addm:add multiple'
        'append:app:app:append to task'
        'archive:move done tasks to archive'
        'command:run addon'
        'del:rm:delete task'
        'depri:dp:remove priority'
        'do:mark as done'
        'help:show help'
        'list:ls:list tasks'
        'listaddons:show installed addons'
        'listall:lsa:list all tasks'
        'listcon:lsc:list contexts'
        'listfile:lf:list files'
        'listpri:lsp:list by priority'
        'listproj:lsprj:list projects'
        'move:mv:move task between files'
        'prepend:insert text at beginning'
        'pri:p:set priority'
        'replace:modify task'
        'report:generate report'
        'shorthelp:brief help'
    )

    _arguments -C \
        "1: :->cmds" \
        "*:: :->args"

    case $state in
        cmds)
            local addons=($(eval TODOTXT_VERBOSE=0 "$_todo_sh" command listaddons 2>/dev/null))
            args=($COMMANDS $addons $OPTS)
            _describe 'todo.sh command' args
            ;;
        args)
            cur="${words[CURRENT]}"
            prev="${words[CURRENT-1]}"

            case "$prev" in
                command)
                    _describe 'subcommand' COMMANDS
                    ;;
                help)
                    local addons=($(eval TODOTXT_VERBOSE=0 "$_todo_sh" command listaddons 2>/dev/null))
                    args=($COMMANDS $addons)
                    _describe 'help topic' args
                    ;;
                addto|listfile|lf|move|mv)
                    local files=($(eval TODOTXT_VERBOSE=0 "$_todo_sh" command listfile 2>/dev/null))
                    _describe 'file' files
                    ;;
                *)
                    case "$cur" in
						due:*)
							_values 'due date' $(seq 0 30 | xargs -I{} date -d "+{} days" +%Y-%m-%d)
							;;
						*@today*|*@now*)
							_wanted dates expl 'date' compadd -S '' -- $(date +%Y-%m-%d)
							;;
                        +*)
                            local projects=($(eval TODOTXT_VERBOSE=0 "$_todo_sh" command listproj 2>/dev/null))
                            [[ ${#projects} -eq 0 ]] && projects=($(eval TODOTXT_VERBOSE=0 TODOTXT_SOURCEVAR=\$DONE_FILE "$_todo_sh" command listproj 2>/dev/null))
                            _describe 'project' projects -p '+'
                            ;;
                        @*)
                            local contexts=($(eval TODOTXT_VERBOSE=0 "$_todo_sh" command listcon 2>/dev/null))
                            [[ ${#contexts} -eq 0 ]] && contexts=($(eval TODOTXT_VERBOSE=0 TODOTXT_SOURCEVAR=\$DONE_FILE "$_todo_sh" command listcon 2>/dev/null))
                            _describe 'context' contexts -p '@'
                            ;;
                        [0-9]##)
                            local task=($(eval TODOTXT_VERBOSE=0 "$_todo_sh" \
                                '-@ -+ -p -x command ls "^ *${cur} "' 2>/dev/null | \
                                sed -e 's/^ *[0-9]\{1,\} //' \
                                    -e 's/^\((.) \)\{0,1\}[0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} /\1/' \
                                    -e 's/^\([xX] \)\([0-9]\{2,4\}-[0-9]\{2\}-[0-9]\{2\} \)\{1,2\}/\1/' \
                                    -e 's/[[:space:]]*$//' -e '1q'))
                            _message -r "Task ${cur}: ${task}"
                            ;;
                        *)
                            if [[ ${words[1]} == $~MOVE_COMMAND_PATTERN ]] && (( CURRENT == 3 )); then
                                local files=($(eval TODOTXT_VERBOSE=0 "$_todo_sh" command listfile 2>/dev/null))
                                _describe 'destination file' files
                            else
                                _files
                            fi
                            ;;
					esac
                    ;;
            esac
            ;;
    esac
}

_todo "$@"
