#!/usr/bin/env bash

_rofi () {
    rofi -dmenu -i -no-levenshtein-sort -width 1000 "$@"
}

# display settings
display_type=1
max_str_width=80

# keybindings
switch_view="Alt+Tab"
new_bookmark="Alt+n"
actions="Alt+a"
edit="Alt+e"
delete="Alt+d"

# colors
help_color="#334433"

# source global config
if [[ -f /etc/buku_run.config ]]
then
  source /etc/buku_run.config
fi

# source local config:
if [[ -z $XDG_CONFIG_DIR ]]
then
  if [[ -f $HOME/.config/buku_run/config ]]
  then
    source $HOME/.config/buku_run/config
  else
    echo "User config file \'~/.config/buku_run/config\' not found. using global config"
  fi
else
  if [[ -f "${XDG_CONFIG_DIR}/buku_run/config" ]]
  then
    source "${XDG_CONFIG_DIR}/buku_run/config"
  else
    echo "User config file \'~/.config/buku_run/config\' not found. using global config"
  fi
fi


main () {
    HELP="Welcome to Buku. Use <span color='${help_color}'>${new_bookmark}</span> to add a new Bookmark
Use <span color='${help_color}'>${switch_view}</span> to switch View. <span color='${help_color}'>${actions}</span> for actions"
    if [[ $mode == "bookmarks" ]]; then
        content=$(parseBuku)
        menu=$(echo "${content}" | _rofi -p '> ' -filter "${filter}" -mesg "${HELP}" -kb-custom-1 "${new_bookmark}" -kb-custom-2 "${switch_view}" -kb-custom-3 "${actions}" -kb-custom-4 "${edit}" -kb-custom-5 "${delete}")
    elif [[ $mode == "tags" ]]; then
        menu=$(buku --np --st | awk '{$NF=""; print $0}' | cut -d ' ' -f2-  | _rofi -p '> ' -mesg "${HELP}" -kb-custom-1 "${new_bookmark}" -kb-custom-2 "${switch_view}" -kb-custom-3 "${actions}" -kb-custom-4 "${edit}" -kb-custom-5 "${delete}")
    fi
    val=$?
    if [[ $val -eq 1 ]]; then
        exit
    elif [[ $val -eq 12 ]]; then
        optionsMenu
    elif [[ $val -eq 10 ]]; then
        addMark
    elif [[ $val -eq 14 ]]; then
        deleteMenu
    elif [[ $val -eq 13 ]]; then
        editMenu
    elif [[ $val -eq 11 ]]; then
        if [[ $mode == "bookmarks" ]]; then
            export mode="tags"
            mode=tags main
        elif [[ $mode == "tags" ]]; then
            export mode="bookmarks"
            mode=bookmarks main
        fi
    elif [[ $val -eq 0 ]]; then
        if [[ $mode == "bookmarks" ]]; then
            id=$(getId "$content" "$menu")
            for bm in ${id}; do
                buku -o "${bm}"
            done
        elif [[ $mode == "tags" ]]; then
            filter="${menu}" mode="bookmarks" main
        fi
    fi
}

optionsMenu () {
    if [[ $mode == "bookmarks" ]]; then
        askmenu=$(echo -e "< Return\n---\n1. Edit\n2. Delete" | _rofi -p '> ' -mesg "Choose Action for bookmark")
        val=$?
        if [[ $val -eq 1 ]]; then
            exit
        elif [[ $val -eq 0 ]]; then
            if [[ $askmenu == "< Return" ]]; then
                export mode=bookmarks
                main
            elif [[ $askmenu == "1. Edit" ]]; then
                editMenu
            elif [[ $askmenu == "2. Delete" ]]; then
                deleteMenu
            fi
        fi
    elif [[ $mode == "tags" ]]; then
        askmenu=$(echo -e "< Return\n---\n1. Replace Tag\n2. Delete Tag" | _rofi -p '> ' -mesg "Choose Action for tag \"${menu}\"")
        val=$?
        if [[ $val -eq 1 ]]; then
            exit
        elif [[ $val -eq 0 ]]; then
            if [[ $askmenu == "< Return" ]]; then
                export mode=tags
                main
            elif [[ $askmenu == "1. Replace Tag" ]]; then
                newtag=$(echo | _rofi -p '> ' -mesg "Enter new tag name for tag \"${menu}\"")
                val=$?
                if [[ $val -eq 1 ]]; then
                    exit
                elif [[ $val -eq 0 ]]; then
                    if [[ $newtag == "" ]]; then
                        mode=tags main
                    else
                        buku -r "${menu}" "${newtag}"
                        mode=tags main
                    fi
                fi
            elif [[ $askmenu == "2. Delete Tag" ]]; then
                delask=$(echo -e "1. Yes\n2. No" | _rofi -p '> ' -mesg "Really delete tag?")
                val=$?
                if [[ $val -eq 1 ]]; then
                    exit
                elif [[ $val -eq 0 ]]; then
                    if [[ $delask == "1. Yes" ]]; then
                        buku -r "${menu}"
                        mode=tags main
                    elif [[ $delask == "2. No" ]]; then
                        mode=tags main
                    fi
                fi
            fi
        fi
    fi
}

deleteMenu () {
    id=$(getId "$content" "$menu")
    delask=$(echo -e "1. Yes\n2. No" | _rofi -p '> ' -mesg "Really delete bookmark?")
    val=$?
    if [[ $val -eq 1 ]]; then
        exit
    elif [[ $val -eq 0 ]]; then
        if [[ $delask == "1. Yes" ]]; then
            buku -d ${id} --tacit
            mode=bookmarks main
        elif [[ $delask == "2. No" ]]; then
            optionsMenu
        fi
    fi
}

editMenu () {
    id=$(getId "$content" "$menu")
    title="$(getTitleFromId $id)"
    bookmark="$(getUrlFromId $id)"
    tags="$(getTagsFromId $id)"
    content=$(echo -e "1. title: $title\n2. url: $bookmark\n3. tags: $tags")
    editmenu=$(echo -e "< Return\n---\n${content}" | _rofi -p '> ')
    val=$?
    if [[ $val -eq 1 ]]; then
        exit
    elif [[ $val -eq 0 ]]; then
        if [[ $editmenu == "< Return" ]]; then
            main
        elif [[ $editmenu == "tags: NOTAG" ]]; then
            addTags --update
        elif [[ $editmenu =~ tags:* ]]; then
            tags="${tags}" editTags
        elif [[ $editmenu =~ url:* ]]; then
            editBookmark
        elif [[ $editmenu =~ title:* ]]; then
            editTitle
        fi
    fi
}

editTags () {
    edittagsmenu=$(echo | _rofi -filter "${tags}" -p '> ' -mesg "Edit Tags and hit Enter")
    val=$?
    if [[ $val -eq 1 ]]; then
        exit
    elif [[ $val -eq 0 ]]; then
        buku -u ${id} --tag "${edittagsmenu}"
    fi
    mode=bookmarks main
}

editBookmark () {
    bmarkmenu=$(echo "" | _rofi -p "> " -filter "${bookmark}" -mesg "Edit Bookmark and hit Enter")
    val=$?
    if [[ $val -eq 1 ]]; then
        exit
    elif [[ $val -eq 0 ]]; then
        if [[ $bmarkmenu == "http"* ]]; then
            buku -u "${id}" --url "${bmarkmenu}"
        else
            echo "" | rofi -e "Not a valid URI, Make sure URLs start with http"
            editBookmark
        fi
    fi
    mode=bookmarks main
}

editTitle () {
  titlemenu=$(echo "" | _rofi -p "> " -filter "${title}" -mesg "Edit Title and hit Enter")
  val=$?
  if [[ $val -eq 1 ]]; then
    exit
  elif [[ $val -eq 0 ]]; then
    buku -u "${id}" --title "${titlemenu}"
  fi
  mode=bookmarks main
}

addMark () {
    inserturl=$(echo -e "$(xclip -o)" | _rofi -p '> ' -mesg "Use URL below or type manually")
    val=$?
    if [[ $val -eq 1 ]]; then
        exit
    elif [[ $val -eq 0 ]]; then
        addTags
    fi
}

addTags () {
    inserttags=$(buku --np --st | awk '{$NF=""; print $0}' | cut -d ' ' -f2- | _rofi -p '> ' -mesg "Add some tags. Separate tags with ', '")
    val=$?
    if [[ $val -eq 1 ]]; then
        exit
    elif [[ $val -eq 0 ]]; then
        if [[ $(echo "${inserttags}" | wc -l) -gt 1 ]]; then
            taglist=$(echo "${inserttags}" | tr '\n' ',')
            tags=()
            for tag in $taglist; do
                tags+=("$tag")
            done
        else
            tags=${inserttags}
        fi
        if [[ $1 == "--update" ]]; then
            buku -u "${id}" --tag ${tags}
        else
            buku -a ${inserturl} ${tags}
        fi
    fi
}

parseBuku () {
  echo "$(buku --nc -p | gawk -v max="$max_str_width" -v type="$display_type" '
BEGIN {
  RS=""
  FS="\n"
}
{
  if ($3 == "")
    $3 = " # NOTAG"
  id = gensub(/([0-9]+)\.(.*)/, "\\1", "g", $1)
  url = substr(gensub(/\s+> (.*)/, "\\1", "g", $2),0,max)
  tags = gensub(/\s+# (.*)/, "\\1", "g", $3)
  title = substr(gensub(/[0-9]+\.\s*(.*)/, "\\1", "g", $1),0,max)

  if (type == 1)
    print id "\t" url "\t" tags
  else
    print id "\t" title "\t" tags
    if (type == 3)
      print " \t" url "\t "
  print ""
}
' | column -t -s $'\t')"
}

getId () {
  id=$(echo "${2%% *}")
  if [ -z "$id" ]; then
    prev=""
    IFS=$'\n'
    for line in $1; do
      if [ "$2" = "$line" ]; then
        id=$(echo "${prev%% *}")
        break
      else
        prev="$line"
      fi
    done
  fi
  echo $id
}

getTitleFromId () {
  echo "$(buku --nc -p $1 | gawk '
  BEGIN {
    RS=""
    FS="\n"
  }
  {
    print gensub(/[0-9]+\.\s*(.*)/, "\\1", "g", $1)
  }
  ')"
}

getUrlFromId () {
  echo "$(buku --nc -p $1 | gawk '
  BEGIN {
    RS=""
    FS="\n"
  }
  {
    print gensub(/\s+> (.*)/, "\\1", "g", $2)
  }
  ')"
}

getTagsFromId () {
  echo "$(buku --nc -p $1 | gawk '
  BEGIN {
    RS=""
    FS="\n"
  }
  {
    print gensub(/\s+# (.*)/, "\\1", "g", $3)
  }
  ')"
}

mode=bookmarks main
