#!/bin/bash

ACCESS_TOKEN_FILE="$HOME/.local/share/ticktask/token"
CONFIG_FILE="$HOME/.config/ticktask/config.sh"
FOLDER_ERROR_TASKS="$HOME/.local/share/ticktask/error_tasks/"

if [ -z "$1" ]; then
    echo "Usage: $0 your task title"

    exit 1
fi

# escape \ and " symbols
task_title=$(echo "$@" | sed 's/\\/\\\\/g; s/"/\\"/g')

if [ ! -f $CONFIG_FILE ]; then
    echo "Please create config file: $CONFIG_FILE"

    exit 1
fi

source $CONFIG_FILE

if [ -f $ACCESS_TOKEN_FILE ]; then
    access_token=$(<$ACCESS_TOKEN_FILE)
else
    # authorization
    echo "No access_token cached. Receiving new one"

    REDIRECT_URL="http://127.0.0.1"
    URL_LEN=$(echo "$REDIRECT_URL" | wc -c)

    # docs says "comma separated", but comma not work. So we use space there
    SCOPE="tasks:write%20tasks:read"

    auth_url="https://ticktick.com/oauth/authorize?scope=$SCOPE&client_id=$CLIENT_ID&state=state&redirect_uri=$REDIRECT_URL&response_type=code"

    echo "Opening browser"
    user_auth_url=$(curl -ILsS -w "%{url_effective}\n" "$auth_url" | tail -n1)
    xdg-open $user_auth_url 2> /dev/null

    read -ep "Paste url you've been redirected: " url_with_code
    code=$(echo -n $url_with_code | tail -c +$(($URL_LEN + 7)) | head -c 6)
    echo "Code: $code"

    payload_get_acces_token="grant_type=authorization_code&code=$code&redirect_uri=$REDIRECT_URL"
    resp_get_access_token=$(curl -s --header "Content-Type: application/x-www-form-urlencoded" \
        -u $CLIENT_ID:$CLIENT_SECRET \
        --request POST \
        --data "$payload_get_acces_token" \
        https://ticktick.com/oauth/token)

    if [[ $resp_get_access_token =~ (access_token\":\")([^\"]*) ]]; then
        access_token=${BASH_REMATCH[2]}
        echo "access_token received. You can find it in $ACCESS_TOKEN_FILE"

        mkdir -p $(dirname $ACCESS_TOKEN_FILE)
        echo -n "$access_token" > $ACCESS_TOKEN_FILE
    else
        echo "Bad response for getting access_token: $resp_get_access_token"

        exit 2
    fi
fi

# getting task description
if [ $(declare -F cmd_get_description) ]; then
    # escape \ and " and newline symbols
    desc=$(cmd_get_description | sed 's/\\/\\\\/g; s/"/\\"/g' \
        | awk '{printf "%s\\n", $0}')
    field_content=', "content": "'$desc'"'
fi

# parse date
if [[ $task_title =~ (^| )\*(today|tomorrow)( |$).* ]]; then
    title_date=${BASH_REMATCH[2]}
    # date must be 1 day ago than real
    title_date=$(date --date="$title_date 1 day ago" -Iseconds)
    field_duedate=', "dueDate": "'$title_date'"'

    # remove date entries from title text
    task_title="$(echo "$task_title" | sed -E 's/(^| )\*today( |$)/ /g; s/(^| )\*tomorrow( |$)/ /g; s/(^ | $)//g')"
fi
# parse tags
if [[ $task_title =~ (^| )#([a-zA-Z0-9_]+)( |$) ]]; then
    tags=$(echo "$task_title" | grep -Eo "(^| )#\w+" | tr -d "\n")

    # HACK. desc is not actual description (for real description use field
    # 'content'). This field is not even displayed (at least in web version),
    # but ticktick parses tags from this field
    field_desc=', "desc": "'$tags'"'

    # remove tags from title text
    task_title="$(echo "$task_title" | sed -E 's/(^| )(#\w+( |$))+/ /g; s/(^ | $)//g')"
fi

json_task='{ "title": "'$task_title'"'$field_content$field_duedate$field_desc' }'

# finally send request to create task
resp_create_task=$(curl -s \
    --fail-with-body \
    --header "Content-Type: application/json" \
    --header "Authorization: Bearer $access_token" \
    --request POST \
    --data "$json_task" \
    https://api.ticktick.com/open/v1/task)
if (( $? != 0 )); then
    echo "Error on creating task. Server response:"
    echo "$resp_create_task"

    mkdir -p $FOLDER_ERROR_TASKS
    error_task_file=$(date +%s)
    echo "$@" > $FOLDER_ERROR_TASKS/$error_task_file
    echo "Task saved to $FOLDER_ERROR_TASKS"

    exit 2
fi