#!/bin/bash
# ==============================================================================================
# ============================= Radarr — TMDb Removed ==========================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Remove movies from Radarr that TMDb has dropped. Radarr marks these with
# status="deleted" — they generate health errors and can never be monitored
# or downloaded. Most are announced-but-never-released films delisted before
# release.
#
# Cache-first movie list (2026-07-17) — comes from the shared tracked-data cache via
# arr_get_tracked_data(), fresh (kept warm every 30min by arr_cache_prefill.sh), live fetch
# as fallback.
#
# ==============================================================================================
# OPERATIONAL MODEL
# ==============================================================================================
#
#   Queries Radarr API for movies with status="deleted" (TMDb removal marker)
#   Reports each entry with file status and size
#   Removes the movie record from Radarr
#   Optionally deletes associated files (disabled by default — most have none)
#   Optionally adds to Radarr's import exclusion list (default: true — prevents re-add)
#
# Files are NOT deleted by default — use --delete-files to also remove from disk.
# Per-deletion output is always visible — deletions are never silently swallowed.
#
# ==============================================================================================
# DESIGN PRINCIPLES
# ==============================================================================================
#
# Health Error Hygiene
#   status="deleted" entries can never be monitored or downloaded — they only
#   generate persistent health errors. Removing them is maintenance, not
#   data loss: the content never existed on disk for most of these entries.
#
# Conservative File Handling
#   Files are not deleted by default because most TMDb-removed entries are
#   announced-but-never-released films with no files. The --delete-files flag
#   is an explicit opt-in, not the default path.
#
# Exclusion List Prevents Re-add
#   Removed entries are added to Radarr's import exclusion list by default.
#   Without this, the same deleted entry can be re-added by lists or searches
#   and immediately generate the same health error again.
#
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
#   detect_hosts()  — exits cleanly if RADARR_URL empty (Radarr not on this host)
#   API pre-flight  — verifies Radarr reachable before querying
#   Dry-run mode    — full preview without removing anything
#
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#
# master.conf
#
#   RADARR_DROPPED_ADD_EXCLUSION — add removed movies to import exclusion (default: true)
#
# host*.conf
#
#   HOST1_RADARR_URL / HOST1_RADARR_API_KEY
#   Aliased by detect_hosts() — script uses RADARR_URL / RADARR_API_KEY
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
#   radarr_tmdb_removed.sh                    — remove records, keep files, add exclusion
#   radarr_tmdb_removed.sh --delete-files     — also delete files from disk
#   radarr_tmdb_removed.sh --dry-run          — preview without removing anything
#   radarr_tmdb_removed.sh --log              — verbose output
#   radarr_tmdb_removed.sh --status           — show config and exit
#
# ==============================================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

source "$SCRIPT_DIR/../load_config.sh"

# ── Parse --delete-files before standard parse_args ───────────────────────────────────────────
DELETE_FILES=false
FILTERED_ARGS=()
for arg in "$@"; do
    if [[ "$arg" == "--delete-files" ]]; then
        DELETE_FILES=true
    else
        FILTERED_ARGS+=("$arg")
    fi
done

parse_args "${FILTERED_ARGS[@]}"

# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
if [[ "$EUID" -ne 0 ]]; then
    error "Must be run as root"
    exit 1
fi

if ! command -v curl >/dev/null 2>&1; then
    error "curl not found"
    exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
    error "jq not found"
    exit 1
fi

acquire_lock

detect_hosts

if [[ -z "$RADARR_URL" ]]; then
    echo "Radarr not configured for $MY_ID — skipping"
    exit 0
fi

ADD_EXCLUSION="${RADARR_DROPPED_ADD_EXCLUSION:-true}"

log "$ICON_GEAR Config: url=${RADARR_URL} add-exclusion=${ADD_EXCLUSION} delete-files=${DELETE_FILES:-false}"
echo "  $MY_ID ($LOCAL_SERVER_NAME) — $RADARR_URL"
[[ "$DELETE_FILES" == true ]]  && warn "DELETE FILES MODE — files will be removed from disk"
[[ "$DELETE_FILES" == false ]] && echo "  Files: records only (use --delete-files to also remove from disk)"
[[ "$DRY_RUN" == true ]]       && warn "DRY RUN — no changes will be made"

# ==============================================================================================
# ━━━ Status ━━━
# ==============================================================================================
if [[ "$SHOW_STATUS" == true ]]; then
    echo ""
    echo "━━━━━ $ICON_SUMMARY STATUS ━━━━━"
    echo "$ICON_HOST   Identity:      $MY_ID ($LOCAL_SERVER_NAME)"
    echo "$ICON_GEAR   Radarr URL:    $RADARR_URL"
    echo "$ICON_GEAR   Add exclusion: $ADD_EXCLUSION"
    echo "$ICON_GEAR   Delete files:  $DELETE_FILES"
    echo "$ICON_GEAR   Dry Run:       $DRY_RUN"
    echo "━━━━━━━━━━━━━━━━━━━━━━━"
    exit 0
fi

# ==============================================================================================
# ━━━ Query Radarr ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_SYNC Querying Radarr ━━━"

if ! curl -sf --connect-timeout 5 --max-time 10 \
    "$RADARR_URL/api/v3/system/status?apikey=$RADARR_API_KEY" | jq -e '.version' >/dev/null 2>&1; then
    error "Radarr API unreachable at $RADARR_URL"
    exit 1
fi

# Cache-first — arr_get_tracked_data() serves the shared cache when it's fresh (kept current
# every 30min by arr_cache_prefill.sh in CRITICAL_MAINTENANCE_SCRIPTS), falls back to a live
# fetch when it's stale, and waits out an active rescan before either.
MOVIES=$(arr_get_tracked_data "radarr" "$RADARR_URL" "$RADARR_API_KEY" "v3")

if [[ -z "$MOVIES" || "$MOVIES" == "null" ]]; then
    error "Radarr movie API returned empty"
    exit 1
fi

TOTAL=$(echo "$MOVIES" | jq '. | length')
DROPPED=$(echo "$MOVIES" | jq '[.[] | select(.status == "deleted")] | length')
echo "  $TOTAL movies total — $DROPPED dropped from TMDb"

if [[ "$DROPPED" -eq 0 ]]; then
    echo "No TMDb-removed movies found — nothing to do"
    echo ""
    echo "━━━━━ $ICON_SUMMARY RADARR TMDB REMOVED SUMMARY ━━━━━"
    echo "$ICON_HOST   Identity: $MY_ID ($LOCAL_SERVER_NAME)"
    echo "$ICON_DONE   Status:   nothing to remove"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    exit 0
fi

# ==============================================================================================
# ━━━ Remove Dropped Movies ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_TRASH Remove TMDb-Dropped Movies ━━━"

START=$(date +%s)
REMOVED=()
FAILED=()
FILES_DELETED=0
FILES_SKIPPED=0

while IFS=$'\t' read -r id title year tmdb_id has_file file_size; do
    [[ -z "$id" ]] && continue

    SIZE_HUMAN=""
    if [[ "$has_file" == "true" && "$file_size" -gt 0 ]]; then
        SIZE_HUMAN=$(awk "BEGIN {printf \"%.1fGB\", $file_size / 1073741824}")
        log "$ICON_WARN  $title ($year) [tmdbid $tmdb_id] — HAS FILE: $SIZE_HUMAN"
    else
        log "$ICON_TRASH $title ($year) [tmdbid $tmdb_id] — no file"
    fi

    if [[ "$DRY_RUN" == true ]]; then
        warn "DRY RUN — would remove: $title"
        [[ "$DELETE_FILES" == true && "$has_file" == "true" ]] && \
            warn "DRY RUN — would delete file: $SIZE_HUMAN"
        REMOVED+=("$title")
        continue
    fi

    DELETE_PARAM="false"
    if [[ "$DELETE_FILES" == true && "$has_file" == "true" ]]; then
        DELETE_PARAM="true"
    fi

    RESP=$(curl -sf -X DELETE --connect-timeout 5 --max-time 15 \
        "$RADARR_URL/api/v3/movie/${id}?deleteFiles=${DELETE_PARAM}&addImportExclusion=${ADD_EXCLUSION}&apikey=$RADARR_API_KEY" \
        2>/dev/null)
    CURL_EXIT=$?

    if [[ "$CURL_EXIT" -eq 0 ]]; then
        echo "  Removed from Radarr ✅"
        REMOVED+=("$title")
        if [[ "$DELETE_PARAM" == "true" ]]; then
            (( FILES_DELETED++ ))
        elif [[ "$has_file" == "true" ]]; then
            (( FILES_SKIPPED++ ))
        fi
    else
        warn "  Failed to remove $title (curl exit $CURL_EXIT)"
        FAILED+=("$title")
    fi

done < <(echo "$MOVIES" | jq -r '
    .[] | select(.status == "deleted") |
    [
        (.id | tostring),
        .title,
        (.year | tostring),
        (.tmdbId | tostring),
        (if .hasFile then "true" else "false" end),
        (if .movieFile.size? then (.movieFile.size | tostring) else "0" end)
    ] | @tsv
')

END=$(date +%s)

# ==============================================================================================
# ━━━ Summary ━━━
# ==============================================================================================
echo ""
echo "━━━━━ $ICON_SUMMARY RADARR TMDB REMOVED SUMMARY ━━━━━"
echo "$ICON_HOST   Identity:  $MY_ID ($LOCAL_SERVER_NAME)"
echo "$ICON_TIME   Duration:  $(format_duration $(( END - START )))"
echo "$ICON_TRASH  Removed:   ${#REMOVED[@]} of $DROPPED"
[[ ${#FAILED[@]} -gt 0 ]] && echo "$ICON_ERROR  Failed:    ${FAILED[*]}"
[[ "$FILES_DELETED" -gt 0 ]] && echo "$ICON_TRASH  Files deleted: $FILES_DELETED"
[[ "$FILES_SKIPPED" -gt 0 ]] && echo "$ICON_WARN   Files kept:    $FILES_SKIPPED (had files — use --delete-files to remove)"
[[ "$ADD_EXCLUSION" == "true" ]] && echo "$ICON_GEAR   Import exclusion added for removed entries"

if [[ "$DRY_RUN" == true ]]; then
    warn "DRY RUN — no changes made"
elif [[ ${#FAILED[@]} -eq 0 ]]; then
    echo "$ICON_DONE Status: done ✅"
else
    warn "Status: ${#FAILED[@]} removal(s) failed"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

[[ ${#FAILED[@]} -gt 0 ]] && exit 1
exit 0
