#!/usr/bin/env python3
import argparse,csv,subprocess,sys
from pathlib import Path
from urllib.parse import urlparse
A=Path("/home/bowerybay/public_html/wilgus-automation")
IMG=Path("/home/bowerybay/public_html/wilgus-images/WILGUS")
OUT=Path("/home/bowerybay/public_html/wilgus-videos-vertical-wilgus")
AS=A/"wilgus-v6-assets"
CAT=A/"wilgus-meta-hotel-catalog.csv"; IMS=A/"meta-hotel-images.csv"
BOLD="/usr/share/fonts/truetype/liberation/LiberationSerif-Bold.ttf"
REG="/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf"
NAVY="0x0E2A5A"
def die(x): print("ERROR:",x,file=sys.stderr); sys.exit(1)
def esc(x): return str(x).replace("\\",r"\\").replace(":",r"\:").replace("'",r"\'").replace("%",r"\%")
def table(p,k):
    with p.open("r",encoding="utf-8-sig",newline="") as f:return {r[k].strip():r for r in csv.DictReader(f)}
def n(v):
    s=str(v).strip()
    try:
        x=float(s); return str(int(x)) if x.is_integer() else s
    except:return s
def pic(pid,u):
    p=IMG/pid/Path(urlparse(u).path).name
    if not p.is_file():die(f"{pid}: missing {p}")
    return p
def make(pid,c,m):
    address=c.get("address.addr1","").strip()
    city=(c.get("address.city","").strip() or c.get("neighborhood[0]","").strip()).upper()
    state=c.get("address.region","").strip().upper()
    loc=f"{city}, {state}" if state else city
    beds=n(c.get("custom_number_0","")); baths=n(c.get("custom_number_1","")); sleeps=n(c.get("custom_number_2",""))
    if not all([address,city,beds,baths,sleeps]):die(f"{pid}: incomplete catalog data")
    ps=[pic(pid,m.get(f"image[{j}].url","").strip()) for j in range(6)]
    OUT.mkdir(parents=True,exist_ok=True); o=OUT/f"{pid}.mp4"
    if o.exists(): print("SKIP:",o); return
    td=OUT/".text";td.mkdir(exist_ok=True)
    af=td/f"{pid}-a.txt";lf=td/f"{pid}-l.txt"
    af.write_text(address,encoding="utf-8");lf.write_text(loc,encoding="utf-8")
    aq=str(af).replace(":",r"\:");lq=str(lf).replace(":",r"\:")
    ins=[]
    for p in ps:ins+=["-loop","1","-t","2","-i",str(p)]
    ins+=["-loop","1","-t","10","-i",str(AS/"wilgus-v6-master-overlay.png")]
    f=[]
    for j in range(6):f.append(f"[{j}:v]scale=1080:480:force_original_aspect_ratio=increase,crop=1080:480,setsar=1,format=yuv420p[p{j}]")
    f += [
      "[p0][p1]xfade=transition=fade:duration=0.4:offset=1.6[x1]",
      "[x1][p2]xfade=transition=fade:duration=0.4:offset=3.2[x2]",
      "[x2][p3]xfade=transition=fade:duration=0.4:offset=4.8[x3]",
      "[x3][p4]xfade=transition=fade:duration=0.4:offset=6.4[x4]",
      "[x4][p5]xfade=transition=fade:duration=0.4:offset=8.0[photos]",
      "color=c=0xF8F5EE:s=1080x1920:d=10[bg]",
      "[bg][photos]overlay=0:344[b]",
      "[6:v]format=rgba[master]",
      "[b][master]overlay=0:0[base]"
    ]
    f.append(
      f"[base]"
      f"drawtext=fontfile='{BOLD}':text='{esc(beds)}':fontcolor={NAVY}:fontsize=54:x=230-text_w/2:y=846,"
      f"drawtext=fontfile='{BOLD}':text='{esc(baths)}':fontcolor={NAVY}:fontsize=54:x=525-text_w/2:y=846,"
      f"drawtext=fontfile='{BOLD}':text='{esc(sleeps)}':fontcolor={NAVY}:fontsize=54:x=830-text_w/2:y=846,"
      f"drawtext=fontfile='{BOLD}':textfile='{aq}':fontcolor={NAVY}:fontsize=39:x=(w-text_w)/2:y=977,"
      f"drawtext=fontfile='{REG}':textfile='{lq}':fontcolor={NAVY}:fontsize=29:x=(w-text_w)/2:y=1027[out]"
    )
    cmd=["ffmpeg","-y",*ins,"-filter_complex",";".join(f),"-map","[out]","-t","10","-r","30",
         "-c:v","libx264","-crf","20","-preset","medium","-pix_fmt","yuv420p","-movflags","+faststart",str(o)]
    print(f"{pid}: {address} | {loc} | {beds} bed | {baths} bath | sleeps {sleeps}")
    subprocess.run(cmd,check=True);af.unlink(missing_ok=True);lf.unlink(missing_ok=True);print("DONE:",o)
def main():
    for p in [CAT,IMS,AS/"wilgus-v6-master-overlay.png"]:
        if not p.is_file():die(f"missing {p}")
    a=argparse.ArgumentParser();a.add_argument("property_id");q=a.parse_args()
    c=table(CAT,"id");m=table(IMS,"hotel_id")
    ids=sorted(set(c)&set(m)) if q.property_id.lower()=="all" else [q.property_id.strip()]
    print(f"Generating {len(ids)} properties into {OUT}")
    for pid in ids:
        if pid not in c or pid not in m:die(f"{pid}: not in both CSVs")
        make(pid,c[pid],m[pid])
if __name__=="__main__":main()
