#!/bin/bash
# Monta il video finale (9:16, 1080x1920, 30 fps) dalle clip generate: le mette in fila come
# dice montaggio.tsv, sotto le scene mute mette la voce, aggiunge una chiusura di 3 secondi con
# prodotto e offerta, imprime i sottotitoli, normalizza il volume e controlla che la voce non
# abbia buchi. Non va modificato: legge tutto dalla cartella del video.
#
# Uso: monta_video.sh <cartella_video>
#
# Cartella video attesa:
#   montaggio.tsv               ordine delle clip (vedi montaggio.tsv.esempio)
#   clip/<nome>.mp4             le clip generate (orchestrate.sh)
#   audio/battute/<file>.mp3    le voci da mettere sotto le scene mute
#   montaggio/sottotitoli.ass   sottotitoli (consigliati: su Meta si guarda senza audio); se manca, avvisa e va avanti
#   chiusura.txt                3 righe: titolo (prezzo/offerta), riga 2, riga 3; se manca, niente chiusura
#   prodotto.png|webp|jpg       foto del prodotto per la chiusura (fondo pieno, meglio nero)
# Risultato: <cartella_video>/video-finale.mp4
# Richiede: ffmpeg con libass e libx264, ffprobe, python3; lib_video.sh accanto allo script.
# Variabili opzionali: FONT_BOLD=/percorso/font.ttf (vedi lib_video.sh)
set -e
source "$(dirname "$0")/lib_video.sh" || { echo "manca lib_video.sh accanto a $0: va scaricata insieme agli script"; exit 1; }
V=$1
[ -d "$V" ] || { echo "uso: monta_video.sh <cartella_video>"; exit 1; }
[ -f "$V/montaggio.tsv" ] || { echo "manca $V/montaggio.tsv (vedi montaggio.tsv.esempio)"; exit 1; }
W="$V/montaggio"                                 # file intermedi
mkdir -p "$W"
# Il finale si scrive sul disco di sistema e poi si copia: scritto su un disco Windows montato
# in WSL (/mnt/c) l'unione si è fermata con "No space left on device" anche con spazio libero.
OUT_TMP="${TMPDIR:-/tmp}/video-finale-$$.mp4"
OUT="$V/video-finale.mp4"
FONT=$(trova_font) || exit 1
SUBS="$W/sottotitoli.ass"

# 1) Ogni clip a 1080x1920, 30 fps, audio stereo 44.1 kHz. Le clip parlate (InfiniteTalk, 480x832)
#    vengono ingrandite e ritagliate a 9:16.
VF="scale=1080:1920:force_original_aspect_ratio=increase:flags=lanczos,crop=1080:1920,fps=30,setsar=1,format=yuv420p"
ENC="-c:v libx264 -preset slow -crf 17 -c:a aac -b:a 192k -ar 44100 -ac 2"
# -nostdin: queste due girano dentro il ciclo che legge montaggio.tsv da stdin; senza,
# ffmpeg si mangia il resto del file e viene montata una clip sola, senza errori.
parlata(){  # $1 = nome clip (con audio già dentro)
  ffmpeg -nostdin -v error -y -i "$V/clip/$1.mp4" -vf "$VF" $ENC "$W/$1.mp4"
}
muta(){     # $1 = nome clip, $2 = mp3 da mettere sotto
  local d; d=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$V/clip/$1.mp4")
  ffmpeg -nostdin -v error -y -i "$V/clip/$1.mp4" -i "$V/audio/battute/$2" -map 0:v -map 1:a -vf "$VF" -af apad -t "$d" $ENC "$W/$1.mp4"
}
declare -a PARTI
while IFS=$'\t' read -r nome audio; do
  [ -z "$nome" ] || [ "${nome:0:1}" = "#" ] && continue
  [ -f "$V/clip/$nome.mp4" ] || { echo "manca $V/clip/$nome.mp4"; exit 1; }
  if [ -n "$audio" ]; then
    [ -f "$V/audio/battute/$audio" ] || { echo "manca $V/audio/battute/$audio"; exit 1; }
    muta "$nome" "$audio"
  else
    parlata "$nome"
  fi
  PARTI+=("$W/$nome.mp4")
done < "$V/montaggio.tsv"
[ ${#PARTI[@]} -gt 0 ] || { echo "montaggio.tsv non ha righe valide"; exit 1; }
_vlog "CLIP normalizzate: ${#PARTI[@]}"

# 2) Chiusura di 3 secondi: prodotto su fondo NERO (le foto prodotto hanno il fondo pieno: su un
#    fondo colorato si vede il riquadro), titolo con prezzo/offerta e due righe.
CODA=0
if [ -f "$V/chiusura.txt" ]; then
  prod=""; for e in png webp jpg jpeg; do [ -f "$V/prodotto.$e" ] && { prod="$V/prodotto.$e"; break; }; done
  [ -n "$prod" ] || { echo "chiusura.txt c'è ma manca prodotto.png/webp/jpg"; exit 1; }
  mapfile -t RIGHE < "$V/chiusura.txt"
  esc(){ printf '%s' "$1" | sed "s/\\\\/\\\\\\\\/g; s/'/\\\\\\\\\\\\'/g; s/:/\\\\:/g; s/%/\\\\%/g"; }
  T1=$(esc "${RIGHE[0]:-}"); T2=$(esc "${RIGHE[1]:-}"); T3=$(esc "${RIGHE[2]:-}")
  ffmpeg -v error -y -f lavfi -i "color=c=black:s=1080x1920:r=30:d=3" -i "$prod" -f lavfi -i "anullsrc=r=44100:cl=stereo" \
   -filter_complex "[1:v]scale=900:900:force_original_aspect_ratio=decrease:flags=lanczos,format=rgba[p];[0:v][p]overlay=(W-w)/2:430[b];[b]drawtext=fontfile='$FONT':text='$T1':fontcolor=0xE9C46A:fontsize=96:x=(w-text_w)/2:y=260,drawtext=fontfile='$FONT':text='$T2':fontcolor=white:fontsize=64:x=(w-text_w)/2:y=1400,drawtext=fontfile='$FONT':text='$T3':fontcolor=white:fontsize=64:x=(w-text_w)/2:y=1490,fade=t=in:st=0:d=0.3,format=yuv420p[v]" \
   -map "[v]" -map 2:a -t 3 $ENC "$W/end.mp4"
  PARTI+=("$W/end.mp4"); CODA=3
  _vlog "CHIUSURA pronta (3 s)"
else
  _vlog "nessuna chiusura.txt: il video finisce con l'ultima clip"
fi

# 3) Unione, sottotitoli impressi (se ci sono), volume normalizzato a -16 LUFS.
#    Stile consigliato per l'ASS: grassetto 76, bianco con bordo nero 7, centrato, 560 px dal
#    basso (fuori dai pulsanti di Meta); righe da massimo 28 caratteri.
inputs=(); fc=""; n=0
for p in "${PARTI[@]}"; do inputs+=(-i "$p"); fc="$fc[$n:v][$n:a]"; n=$((n+1)); done
fc="${fc}concat=n=$n:v=1:a=1[cv][ca]"
if [ -f "$SUBS" ]; then
  fc="$fc;[cv]subtitles='$SUBS':fontsdir='$(dirname "$FONT")'[sv]"
else
  _vlog "ATTENZIONE: manca $SUBS, il video esce senza sottotitoli"
  fc="$fc;[cv]null[sv]"
fi
fc="$fc;[ca]loudnorm=I=-16:TP=-1.5:LRA=11[na]"
ffmpeg -v error -y "${inputs[@]}" -filter_complex "$fc" \
 -map "[sv]" -map "[na]" -c:v libx264 -preset slow -crf 18 -profile:v high -pix_fmt yuv420p -r 30 -c:a aac -b:a 192k -ar 44100 -movflags +faststart "$OUT_TMP"

# 4) Voce su tutta la durata PRIMA di consegnare (esclusa la chiusura muta): un video è già uscito
#    muto dal secondo 9 e se n'è accorto il cliente.
controlla_audio "$OUT_TMP" 1.5 "$CODA"
cp "$OUT_TMP" "$OUT"; rm -f "$OUT_TMP"
ffprobe -v error -show_entries format=duration:stream=width,height -of compact "$OUT"
_vlog "FATTO: $OUT"
