#!/bin/bash
set -euo pipefail

# -------------------------------
# Check input
# -------------------------------
if [ $# -lt 1 ]; then
    echo "Usage: $0 <input-file.mkv>"
    exit 1
fi

INPUT="$1"
BASENAME=$(basename "$INPUT" | sed 's/\.[^.]*$//')
OUTDIR="${BASENAME}-Transcode"

echo "========================================"
echo "Processing: $INPUT"
echo "Output: $OUTDIR"
echo "========================================"

mkdir -p "$OUTDIR/sub-titles" "$OUTDIR/video" "$OUTDIR/audio"

# -------------------------------
# 0️⃣ Generate mediainfo.json
# -------------------------------
echo "[0/5] Generating mediainfo.json"
ffprobe -v quiet -print_format json -show_format -show_streams "$INPUT" > "$OUTDIR/mediainfo.json"

# -------------------------------
# 1️⃣ Generate Master Playlist (Early Step)
# -------------------------------
# We generate the skeleton now so the structure is ready.
echo "[1/5] Initializing master playlist"
MASTER="$OUTDIR/playlist.m3u8"
printf "#EXTM3U\n#EXT-X-VERSION:3\n\n" > "$MASTER"

# Add Audio Tracks to Master
AUDIO_STREAMS=$(jq -r '.streams[] | select(.codec_type=="audio") | @base64' "$OUTDIR/mediainfo.json")
IDX=0
FIRST_AUDIO=true
for s in $AUDIO_STREAMS; do
    _jq() { echo "$s" | base64 --decode | jq -r "$1"; }
    LANG=$(_jq '.tags.language // "und"')
    TITLE=$(_jq '.tags.title // "Track"')
    
    DISPLAY_NAME="${TITLE}"
    GROUP_ID="audio" # Keeping it simple for compatibility
    
    DEFAULT_VAL="NO"
    if [ "$FIRST_AUDIO" = true ]; then DEFAULT_VAL="YES"; FIRST_AUDIO=false; fi

    printf "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"audio\",NAME=\"%s\",LANGUAGE=\"%s\",DEFAULT=%s,AUTOSELECT=YES,URI=\"audio/%s_%s/stream.m3u8\"\n" \
        "$DISPLAY_NAME" "$LANG" "$DEFAULT_VAL" "$IDX" "$LANG" >> "$MASTER"
    IDX=$((IDX+1))
done

# Add Subtitle placeholders to Master
SUB_STREAMS=$(jq -r '.streams[] | select(.codec_type=="subtitle") | @base64' "$OUTDIR/mediainfo.json")
HAS_SUBS=0
IDX=0
for s in $SUB_STREAMS; do
    _jq() { echo "$s" | base64 --decode | jq -r "$1"; }
    CODEC=$(_jq '.codec_name')
    # Only include text-based for HLS
    if [[ "$CODEC" == "subrip" || "$CODEC" == "ass" || "$CODEC" == "ssa" || "$CODEC" == "mov_text" || "$CODEC" == "webvtt" ]]; then
        LANG=$(_jq '.tags.language // "und"')
        DISPLAY_LANG=$(echo "$LANG" | tr '[:lower:]' '[:upper:]')
        printf "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"%s\",LANGUAGE=\"%s\",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,URI=\"sub-titles/%s_%s.vtt\"\n" \
            "$DISPLAY_LANG" "$LANG" "$IDX" "$LANG" >> "$MASTER"
        HAS_SUBS=$((HAS_SUBS+1))
    fi
    IDX=$((IDX+1))
done

printf "\n" >> "$MASTER"

# Add Video Variants
PROFILES=("1080p:2000" "720p:1200")
for profile in "${PROFILES[@]}"; do
    RES=${profile%%:*}
    BITRATE=${profile##*:}
    
    # We estimate resolution for the master tag initially
    V_RES="1920x1080"; if [ "$RES" == "720p" ]; then V_RES="1280x720"; fi
    
    INF="#EXT-X-STREAM-INF:BANDWIDTH=$((BITRATE*1024)),RESOLUTION=$V_RES,CODECS=\"avc1.640028,mp4a.40.2\",AUDIO=\"audio\""
    if [ "$HAS_SUBS" -gt 0 ]; then INF="$INF,SUBTITLES=\"subs\""; fi
    
    printf "%s\nvideo/%s/stream.m3u8\n" "$INF" "$RES" >> "$MASTER"
done

# -------------------------------
# 2️⃣ Extract subtitles
# -------------------------------
echo "[2/5] Extracting subtitles"
IDX=0
# Get codec info via ffprobe
mapfile -t SUB_INFO < <(ffprobe -v error -select_streams s -show_entries stream=index,codec_name:stream_tags=language -of csv=p=0 "$INPUT")

for i in "${SUB_INFO[@]}"; do
    INDEX=$(echo "$i" | cut -d',' -f1)
    CODEC=$(echo "$i" | cut -d',' -f2)
    LANG=$(echo "$i" | cut -d',' -f3); LANG=${LANG:-und}
    
    FNAME="$OUTDIR/sub-titles/${IDX}_${LANG}.vtt"

    if [[ "$CODEC" == "subrip" || "$CODEC" == "ass" || "$CODEC" == "ssa" || "$CODEC" == "mov_text" || "$CODEC" == "webvtt" ]]; then
        ffmpeg -y -i "$INPUT" -map "0:$INDEX" -c:s webvtt "$FNAME"
    elif [[ "$CODEC" == "dvd_subtitle" || "$CODEC" == "hdmv_pgs_subtitle" ]]; then
        ffmpeg -y -i "$INPUT" -map "0:$INDEX" -c:s copy "$OUTDIR/sub-titles/${IDX}_${LANG}.mkv"
    fi
    IDX=$((IDX+1))
done

# -------------------------------
# 3️⃣ Encode Video (GPU)
# -------------------------------
echo "[3/5] Encoding video variants"
# Logic for Aspect Ratio selection (Shortened for brevity)
for profile in "${PROFILES[@]}"; do
    RES=${profile%%:*}
    BITRATE=${profile##*:}
    mkdir -p "$OUTDIR/video/$RES"
    
    # Simple aspect check
    W_H=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "$INPUT")
    
    ffmpeg -y -hwaccel cuda -i "$INPUT" \
        -map 0:v:0 -c:v h264_nvenc -b:v "${BITRATE}k" \
        -vf "scale=trunc(oh*a/2)*2:$([ "$RES" == "1080p" ] && echo 1080 || echo 720),setsar=1" \
        -profile:v high -pix_fmt yuv420p -an \
        -f hls -hls_time 600 -hls_list_size 0 \
        "$OUTDIR/video/$RES/stream.m3u8"
done

# -------------------------------
# 4️⃣ Encode Audio
# -------------------------------
echo "[4/5] Encoding audio tracks"
IDX=0
for s in $AUDIO_STREAMS; do
    _jq() { echo "$s" | base64 --decode | jq -r "$1"; }
    LANG=$(_jq '.tags.language // "und"')
    STREAM_INDEX=$(_jq '.index')
    AUDIO_OUT="$OUTDIR/audio/${IDX}_${LANG}"
    mkdir -p "$AUDIO_OUT"
    
    ffmpeg -y -i "$INPUT" -map "0:$STREAM_INDEX" -c:a aac -b:a 128k -vn \
        -f hls -hls_time 600 -hls_list_size 0 \
        "$AUDIO_OUT/stream.m3u8"
    IDX=$((IDX+1))
done

echo "[5/5] Done! Playlist: $MASTER"
