#!/bin/bash
# daily_sunrise_video.sh — collect today's sunrise images, speed-adjust to
# SUNRISE_TARGET_SECS, burn the local sunrise time vertically on the right
# side, and write the final video.  Upload is handled by a separate systemd
# service (sky-cam-sunrise-upload) triggered via OnSuccess= so the two jobs
# have independent log entries and failure states.
#
# Resilience: the speed-adjusted video is saved permanently before the overlay
# step.  If overlay fails, the sped video survives at:
#   <output_dir>/<date>-daily-sunrise-sped.mp4
# Re-run this script once the issue is resolved; the sped file is deleted
# automatically when the overlay step succeeds.

set -euo pipefail

SCRIPT_DIR="$(dirname "$(realpath "$0")")"
source "$SCRIPT_DIR/sky-cam.conf"
export TZ="$TIMEZONE"

CAM_NAME="${1:-$SUNRISE_CAM}"

# ── Date / paths ──────────────────────────────────────────────────────────────
current_date=$(date +%Y-%m-%d)
output_date=$(date +%Y-%m)

image_dir="$BASE_DIR/$CAM_NAME/$current_date"
output_dir="$MOVIES_DIR/$CAM_NAME/$output_date/sunrise-only"
mkdir -p "$output_dir"

# ── Sunrise time ──────────────────────────────────────────────────────────────
sunrise_time=$(python3 "$SCRIPT_DIR/sunrise.py")
if [[ -z "$sunrise_time" ]]; then
    "$SCRIPT_DIR/notify.sh" "FAILED: sunrise $current_date" \
        "Could not retrieve sunrise time from sunrise.py" || true
    echo "Error: Failed to retrieve sunrise time."
    exit 1
fi
echo "Sunrise (UTC): $sunrise_time"

sunrise_time_local=$(TZ="$TIMEZONE" date -d "$sunrise_time" +"%H-%M-%S")
echo "Sunrise (local): $sunrise_time_local"

# ── Capture window ────────────────────────────────────────────────────────────
time_to_seconds() { IFS='-' read -r h m s <<< "$1"; echo $((10#$h * 3600 + 10#$m * 60 + 10#$s)); }

sunrise_sec=$(time_to_seconds "$sunrise_time_local")
start_sec=$((sunrise_sec - SUNRISE_PRE_MIN * 60))
end_sec=$((sunrise_sec + SUNRISE_POST_MIN * 60))
echo "Window: $((start_sec/3600)):$(printf '%02d' $(((start_sec%3600)/60))) → $((end_sec/3600)):$(printf '%02d' $(((end_sec%3600)/60)))"

# ── Wait for capture window to finish ────────────────────────────────────────
# The timer fires early (default 03:00); we sleep internally so images from
# the full window are available before we start encoding.
midnight=$(date -d "today 00:00:00" +%s)
now_day_sec=$(( $(date +%s) - midnight ))
if [ "$now_day_sec" -lt "$end_sec" ]; then
    wait_sec=$(( end_sec - now_day_sec + 30 ))
    echo "Waiting ${wait_sec}s for capture window to finish (ends $(date -d "@$(( midnight + end_sec ))" '+%H:%M:%S'))..."
    sleep "$wait_sec"
else
    echo "Capture window already closed at $(date -d "@$(( midnight + end_sec ))" '+%H:%M:%S') — processing available images"
fi

# ── Collect images in window ──────────────────────────────────────────────────
if [ ! -d "$image_dir" ]; then
    "$SCRIPT_DIR/notify.sh" "FAILED: sunrise $current_date" \
        "Image directory not found: $image_dir" || true
    echo "Error: image directory not found: $image_dir"
    exit 1
fi

temp_list=$(mktemp --suffix=.txt)
raw_video=""
temp_audio=""
trap 'rm -f "$temp_list" "$raw_video" "$temp_audio" 2>/dev/null || true' EXIT

find "$image_dir" -type f -name "*.jpg" | sort | while read -r img; do
    img_sec=$(time_to_seconds "$(basename "$img" .jpg)")
    if [[ $img_sec -ge $start_sec && $img_sec -le $end_sec ]]; then
        echo "file '$img'"
    fi
done > "$temp_list"

num_images=$(wc -l < "$temp_list")
if [[ $num_images -lt 1 ]]; then
    "$SCRIPT_DIR/notify.sh" "FAILED: sunrise $current_date" \
        "No images found in sunrise window" || true
    echo "No images found in sunrise window."
    exit 1
fi
echo "Images in window: $num_images"

# ── Font detection (same fallback chain as montage-mvt.sh) ───────────────────
FONT=""
if command -v fc-match &>/dev/null; then
    FONT=$(fc-match "DejaVu Sans:style=Regular" --format="%{file}" 2>/dev/null || true)
fi
if [ -z "$FONT" ]; then
    for f in \
        /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf \
        /usr/share/fonts/dejavu/DejaVuSans.ttf \
        /usr/share/fonts/TTF/DejaVuSans.ttf \
        /usr/share/fonts/truetype/freefont/FreeSans.ttf; do
        [ -f "$f" ] && { FONT="$f"; break; }
    done
fi

# ── Step 1: Raw video from images ─────────────────────────────────────────────
raw_video=$(mktemp --suffix=.mp4)
echo "Step 1/3: encoding raw video..."
if ! ffmpeg -loglevel warning \
    -f concat -safe 0 -i "$temp_list" \
    -c:v libx264 -pix_fmt yuv420p -crf "$CRF_SUNRISE" -vsync 2 -an \
    -y "$raw_video"; then
    "$SCRIPT_DIR/notify.sh" "FAILED: sunrise step 1/3 (encode) $current_date" \
        "ffmpeg raw encode from images failed — check: journalctl -u sky-cam-sunrise.service" || true
    exit 1
fi

raw_dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$raw_video")
speed_factor=$(echo "scale=3; $raw_dur / $SUNRISE_TARGET_SECS" | bc)
echo "Raw: ${raw_dur}s  speed factor: ${speed_factor}x"

# ── Step 2: Speed-adjust — saved permanently so overlay failure is recoverable ─
# Deleted automatically if step 3 succeeds.
sped_video="$output_dir/$current_date-daily-sunrise-sped.mp4"
echo "Step 2/3: speed-adjust → $sped_video"
if ! ffmpeg -loglevel warning \
    -i "$raw_video" \
    -vf "setpts=PTS/${speed_factor}" \
    -c:v libx264 -pix_fmt yuv420p -crf "$CRF_SUNRISE" -an \
    -y "$sped_video"; then
    rm -f "$sped_video"
    "$SCRIPT_DIR/notify.sh" "FAILED: sunrise step 2/3 (speed) $current_date" \
        "speed-adjust failed — no video saved" || true
    exit 1
fi

sped_dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$sped_video")
echo "Speed-adjusted: ${sped_dur}s  (saved — overlay still pending)"

# ── Build overlay filter (skipped if SUNRISE_OVERLAY_ENABLED=false) ──────────
SR_TIME=$(echo "$sunrise_time_local" | cut -d'-' -f1,2 | tr '-' ':')
DT=""
if [ "${SUNRISE_OVERLAY_ENABLED:-true}" = "true" ]; then
    SR_VERT=$(echo "$SR_TIME" | awk 'BEGIN{FS=""}{for(i=1;i<=NF;i++){printf "%s",$i; if(i<NF)printf "\\n"}}')
    DT="drawtext"
    [ -n "$FONT" ] && DT="${DT}=fontfile='${FONT}'" || DT="${DT}"
    DT="${DT}:text='${SR_VERT}'"
    DT="${DT}:fontcolor=white@${SUNRISE_OVERLAY_OPACITY}"
    DT="${DT}:fontsize=h/22"
    DT="${DT}:line_spacing=4"
    DT="${DT}:x=w-tw-18:y=(h-th)/2"
    DT="${DT}:shadowcolor=black@0.55:shadowx=1:shadowy=1"
fi

# ── Step 3: Audio mix + overlay — each independently optional/fallible ────────
# Step 3a: mixes audio into a temp copy of the sped video (video stream is
#          copied, not re-encoded — fast, and lets step 3b fail independently).
# Step 3b: burns the overlay onto whatever 3a produced.
# Failure matrix → upload always fires:
#   audio ✓  overlay ✓  → final has audio + overlay
#   audio ✓  overlay ✗  → final has audio,   no overlay
#   audio ✗  overlay ✓  → final has overlay, no audio
#   audio ✗  overlay ✗  → sped video promoted (no audio, no overlay)
final_video="$output_dir/$current_date-daily-sunrise.mp4"
fade_out=$(echo "scale=1; $SUNRISE_TARGET_SECS - 0.5" | bc)

# ── Pick audio source ─────────────────────────────────────────────────────────
audio_src=""
audio_offset="0"  # cam audio is pre-centred on sunrise; library files are trimmed to fit

cam_audio="$image_dir/sunrise-audio.m4a"
if [ "${AUDIO_ENABLED:-false}" = "true" ]; then
    if [ -f "$cam_audio" ]; then
        # Already exactly SUNRISE_TARGET_SECS, centred on sunrise — no offset needed
        audio_src="$cam_audio"
        echo "Audio: camera recording (centred on sunrise)"
    else
        library_dir="$SCRIPT_DIR/sunrise-sounds"
        if [ -d "$library_dir" ]; then
            random_file=$(find "$library_dir" -name "*.mp3" | shuf -n 1 2>/dev/null || true)
            if [ -n "$random_file" ]; then
                audio_src="$random_file"
                echo "Audio: library fallback  $(basename "$audio_src")"
            fi
        fi
    fi
fi

# ── Step 3a: mix audio (video copied, not re-encoded) ────────────────────────
work_video="$sped_video"
has_audio=false

if [ -n "$audio_src" ]; then
    temp_audio=$(mktemp --suffix=.mp4)
    echo "Step 3a/3: mixing audio → temp"
    if ffmpeg -loglevel warning \
        -i "$sped_video" \
        -ss "$audio_offset" -t "$SUNRISE_TARGET_SECS" -i "$audio_src" \
        -filter_complex "[1:a]afade=t=in:st=0:d=0.5,afade=t=out:st=${fade_out}:d=0.5[aout]" \
        -map "0:v" -map "[aout]" \
        -c:v copy -c:a aac -b:a 128k \
        -y "$temp_audio"; then
        work_video="$temp_audio"
        has_audio=true
        echo "Audio: mixed OK"
    else
        rm -f "$temp_audio"; temp_audio=""
        echo "Audio mix failed — step 3b will be overlay-only"
        "$SCRIPT_DIR/notify.sh" "WARNING: sunrise audio mix failed $current_date" \
            "Audio could not be mixed — continuing with overlay only" || true
        [ "$audio_src" = "$cam_audio" ] && rm -f "$cam_audio"
    fi
fi

# ── Step 3b: burn overlay (or promote work_video directly if disabled) ────────
if $has_audio; then audio_out_flags=(-c:a copy); else audio_out_flags=(-an); fi

step3b_ok=false
if [ -n "$DT" ]; then
    echo "Step 3b/3: overlay → $final_video"
    if ffmpeg -loglevel warning \
        -i "$work_video" \
        -vf "${DT}" \
        -c:v libx264 -pix_fmt yuv420p -crf "$CRF_SUNRISE" \
        "${audio_out_flags[@]}" \
        -y "$final_video"; then
        step3b_ok=true
    else
        if $has_audio; then promote_label="audio-mixed"; else promote_label="speed-only"; fi
        mv "$work_video" "$final_video"
        [ "$work_video" != "$sped_video" ] && rm -f "$sped_video"
        temp_audio=""
        [ -f "$cam_audio" ] && rm -f "$cam_audio"
        echo "Overlay failed — promoting ${promote_label} video as upload target"
        "$SCRIPT_DIR/notify.sh" "WARNING: sunrise overlay failed $current_date" \
            "Overlay failed — uploading ${promote_label} video (no timestamp)" || true
        step3b_ok=true  # degraded but recoverable — upload still fires
    fi
else
    echo "Step 3b/3: overlay disabled — promoting as final"
    mv "$work_video" "$final_video"
    [ "$work_video" != "$sped_video" ] && rm -f "$sped_video"
    temp_audio=""
    step3b_ok=true
fi

if $step3b_ok; then
    actual_dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$final_video")
    echo "Done: $final_video  (${actual_dur}s, sunrise at ${SR_TIME})"
    rm -f "$sped_video" "$temp_audio" 2>/dev/null || true; temp_audio=""
    [ -f "$cam_audio" ] && rm -f "$cam_audio"
    "$SCRIPT_DIR/notify.sh" "Sunrise ready: $current_date" \
        "$(basename "$final_video") — ${actual_dur}s, sunrise at ${SR_TIME}" || true
fi
