#!/usr/bin/env bash
# sdict — terminal dictionary lookup
# Inspired by BreadOnPenguins/scripts/define
# Backends: Oxford Dictionaries API (set OD_APP_ID + OD_APP_KEY)
#           sdcv with Oxford StarDict dict (offline, set SDICT_USE_SDCV=1)
#           dictionaryapi.dev (free fallback, no config needed)

set -euo pipefail

BOLD='\033[1m'
DIM='\033[2m'
ITALIC='\033[3m'
BLUE='\033[34m'
CYAN='\033[36m'
GREEN='\033[32m'
YELLOW='\033[33m'
RESET='\033[0m'

usage() {
    echo -e "${BOLD}sdict${RESET} — look up a word in the dictionary"
    echo ""
    echo -e "  ${BOLD}Usage:${RESET} sdict <word>"
    echo ""
    echo -e "  ${BOLD}Backends (checked in order):${RESET}"
    echo "    1. Oxford Dictionaries API  — set OD_APP_ID and OD_APP_KEY"
    echo "    2. sdcv (offline Oxford)    — set SDICT_USE_SDCV=1"
    echo "    3. dictionaryapi.dev        — free, no config needed"
    exit 0
}

die() { echo -e "\033[31merror:\033[0m $1" >&2; exit 1; }

[[ $# -lt 1 || "$1" == "-h" || "$1" == "--help" ]] && usage
word="$1"
[[ "$word" =~ [^a-zA-Z-] ]] && die "invalid word: $word"

# --- Backend 1: Oxford Dictionaries API ---
oxford_lookup() {
    local resp
    resp=$(curl -sf --connect-timeout 5 --max-time 10 \
        -H "app_id: $OD_APP_ID" \
        -H "app_key: $OD_APP_KEY" \
        "https://od-api-v2.oxforddictionaries.com/api/v2/entries/en-us/${word,,}") || return 1

    echo -e "${BOLD}${BLUE}${word}${RESET}"
    echo ""

    # phonetic
    local phonetic
    phonetic=$(echo "$resp" | jq -r '
        [.results[].lexicalEntries[].pronunciations[]? | select(.phoneticSpelling) | .phoneticSpelling] | first // empty
    ' 2>/dev/null)
    [[ -n "$phonetic" ]] && echo -e "  ${DIM}/$phonetic/${RESET}" && echo ""

    # etymology
    local etym
    etym=$(echo "$resp" | jq -r '
        [.results[].lexicalEntries[].entries[].etymologies[]?] | first // empty
    ' 2>/dev/null)
    [[ -n "$etym" ]] && echo -e "  ${DIM}Origin: $etym${RESET}" && echo ""

    # definitions by part of speech
    echo "$resp" | jq -r '
        .results[].lexicalEntries[] |
        .lexicalCategory.id as $pos |
        .entries[].senses[:3][] |
        "\($pos)|\(.definitions[0] // empty)|\(.examples[0].text? // empty)"
    ' 2>/dev/null | while IFS='|' read -r pos def example; do
        [[ -z "$def" ]] && continue
        echo -e "  ${GREEN}${pos}${RESET}"
        echo -e "    ${def}"
        [[ -n "$example" ]] && echo -e "    ${DIM}\"${example}\"${RESET}"
        echo ""
    done
}

# --- Backend 2: sdcv (offline) ---
sdcv_lookup() {
    command -v sdcv >/dev/null 2>&1 || return 1
    local result
    result=$(sdcv -n "$word" 2>/dev/null) || return 1
    [[ "$result" == *"Nothing similar"* ]] && return 1
    echo -e "${BOLD}${BLUE}${word}${RESET}"
    echo ""
    echo "$result" | sed 's/^/  /'
    echo ""
}

# --- Backend 3: Free Dictionary API (fallback) ---
free_lookup() {
    local resp
    resp=$(curl -sf --connect-timeout 5 --max-time 10 \
        "https://api.dictionaryapi.dev/api/v2/entries/en_US/${word}") || return 1
    [[ "$resp" == *"No Definitions Found"* ]] && return 1

    echo -e "${BOLD}${BLUE}${word}${RESET}"
    echo ""

    # phonetic
    local phonetic
    phonetic=$(echo "$resp" | jq -r '[.[].phonetic // empty] | first // empty' 2>/dev/null)
    [[ -n "$phonetic" ]] && echo -e "  ${DIM}${phonetic}${RESET}" && echo ""

    # definitions
    echo "$resp" | jq -r '
        .[].meanings[] |
        .partOfSpeech as $pos |
        .definitions[:3][] |
        "\($pos)|\(.definition)|\(.example // empty)"
    ' 2>/dev/null | while IFS='|' read -r pos def example; do
        [[ -z "$def" ]] && continue
        echo -e "  ${GREEN}${pos}${RESET}"
        echo -e "    ${def}"
        [[ -n "$example" ]] && echo -e "    ${DIM}\"${example}\"${RESET}"
        echo ""
    done

    echo -e "  ${DIM}source: dictionaryapi.dev${RESET}"
}

# --- Dispatch ---
if [[ -n "${OD_APP_ID:-}" && -n "${OD_APP_KEY:-}" ]]; then
    oxford_lookup && exit 0
    echo -e "${DIM}Oxford API failed, trying fallback...${RESET}" >&2
fi

if [[ "${SDICT_USE_SDCV:-0}" == "1" ]]; then
    sdcv_lookup && exit 0
    echo -e "${DIM}sdcv failed, trying fallback...${RESET}" >&2
fi

free_lookup || die "no definition found for '${word}'"
