from pathlib import Path
import subprocess

ROOT=Path('/home/spazio/cosmos-reels')
SRC=ROOT/'source'; TMP=ROOT/'tmp-v2'; OUT=ROOT/'out-v2'; SUB=ROOT/'subs-v2'
for p in (TMP,OUT,SUB): p.mkdir(parents=True,exist_ok=True)
FONTS='/opt/cosmosluminosity/content/themes/clean/assets/fonts'

# Every source remains fully visible inside a 16:9 editorial window.
# No face, hair contour, chin, hand, or full-body gesture is sacrificed to a 9:16 crop.
REELS={
'01_old_life_still_works_v2':{
 'clips':[('20261019_121805.mp4',18,3),('20261019_121805.mp4',24,3),('20261019_121805.mp4',48,3),('20261026_013647.mp4',83,3.5)],
 'events':[(0,2.8,'YOUR OLD LIFE\\NSTILL WORKS.','main'),(2.8,8.7,'IT SIMPLY CANNOT HOLD\\NWHO YOU ARE BECOMING.','main'),(8.7,12.2,'NOT FAILURE.\\NEXPANSION.','accent')]
},
'02_you_are_not_lost_v2':{
 'clips':[('20261024_163840.mp4',8,3),('20261024_163840.mp4',21,4),('20261017_165151.mp4',64,3),('20261017_165151.mp4',72,3.5)],
 'events':[(0,2.8,'YOU ARE NOT LOST.','accent'),(2.8,8.7,'YOU ARE BETWEEN\\NWHAT NO LONGER FITS','main'),(8.7,13.2,'AND WHAT HAS NOT\\NTAKEN SHAPE YET.','main')]
},
'03_choose_a_season_v2':{
 'clips':[('20261024_144707.mp4',7,3),('20261024_144707.mp4',14,3),('20261026_020000.mp4',22,3),('20261026_020000.mp4',33,3.5)],
 'events':[(0,4.1,'YOU DO NOT NEED\\NA SMALLER SELF.','main'),(4.1,8.5,'CHOOSE WHAT BECOMES REAL\\NIN THIS SEASON.','main'),(8.5,12.2,'CHOOSE A SEASON.\\NKEEP YOUR WHOLENESS.','accent')]
},
'04_visibility_before_confidence_v2':{
 'clips':[('20261026_014149.mp4',100,4),('20261026_014149.mp4',120,4),('20261024_144707.mp4',14,3),('20261026_013647.mp4',133,4.5)],
 'events':[(0,3.8,'YOU MAY NOT\\NFEEL READY.','main'),(3.8,8.0,'CONFIDENCE DOES NOT\\NCOME FIRST.','main'),(8.0,10.9,'VISIBILITY DOES.','accent'),(10.9,15.2,'BE SEEN BEFORE\\NIT IS PERFECT.','main')]
},
'05_intuition_without_fantasy_v2':{
 'clips':[('20261024_144951.mp4',14,3),('20261024_144951.mp4',21,4),('20261026_020000.mp4',99,4),('20261026_020000.mp4',110,4.5)],
 'events':[(0,5.1,'WHEN YOU STOP LYING\\NTO YOURSELF,','main'),(5.1,8.5,'INTUITION\\NGETS LOUDER.','accent'),(8.5,12.0,'THEN TEST IT\\NIN MATERIAL LIFE.','main'),(12.0,15.2,'HONESTY. ACTION. FEEDBACK.','accent')]
}}

def at(s):
 h=int(s//3600); m=int((s%3600)//60); sec=s%60
 return f'{h}:{m:02d}:{sec:05.2f}'

def ass(name,cfg,duration):
 # One type family only: Cormorant Garamond.
 hdr='''[Script Info]
ScriptType: v4.00+
PlayResX: 1080
PlayResY: 1920
WrapStyle: 2
ScaledBorderAndShadow: yes

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: main,Cormorant Garamond SemiBold,67,&H00F7F0E8,&H000000FF,&H700B0711,&H00000000,-1,0,0,0,100,100,2.2,0,1,2.2,0,8,130,130,1475,1
Style: accent,Cormorant Garamond SemiBold,73,&H0064BDE1,&H000000FF,&H700B0711,&H00000000,-1,0,0,0,100,100,2.6,0,1,2.2,0,8,130,130,1475,1
Style: brand,Cormorant Garamond Medium,31,&H00D0B46D,&H000000FF,&H600B0711,&H00000000,-1,0,0,0,100,100,6,0,1,1.5,0,2,120,120,315,1
Style: index,Cormorant Garamond Medium,27,&H00D0B46D,&H000000FF,&H600B0711,&H00000000,-1,0,0,0,100,100,3,0,1,1.2,0,9,115,115,100,1

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
'''
 lines=[]
 for start,end,text,style in cfg['events']:
  # Positioned at y≈300: below top UI, above the editorial image window.
  lines.append(f'Dialogue: 1,{at(start)},{at(end)},{style},,0,0,0,,{{\\pos(540,350)\\fad(220,220)}}{text}')
 lines += [
   f'Dialogue: 1,{at(0)},{at(duration)},brand,,0,0,0,,COSMOS LUMINOSITY',
   f'Dialogue: 1,{at(0)},{at(duration)},index,,0,0,0,,BETWEEN IDENTITIES  ·  {name[:2]}',
 ]
 p=SUB/(name+'.ass'); p.write_text(hdr+'\n'.join(lines)+'\n')
 return p

for name,cfg in REELS.items():
 clips=[]
 for i,(fn,start,dur) in enumerate(cfg['clips']):
  src=SRC/fn; dst=TMP/f'{name}_{i}.mp4'; clips.append(dst)
  # Layer 1: cover-style blurred extension, heavily darkened/purple-tinted.
  # Layer 2: entire 1920×1080 source scaled to 1000×563, centered in editorial window.
  # This is the face-integrity rule in code: foreground uses scale only, never crop.
  fc=(
   "[0:v]scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,"
   "boxblur=38:18,eq=brightness=-0.25:saturation=0.50:contrast=1.04,"
   "colorbalance=bs=.10:rs=.035[bg];"
   "[0:v]scale=1000:563:flags=lanczos,eq=contrast=1.035:saturation=.88:brightness=-.01,"
   "unsharp=5:5:.30:5:5:0[fg];"
   "[bg][fg]overlay=40:590:shortest=1,"
   "drawbox=x=39:y=589:w=1002:h=565:color=0xE1BD64@0.62:t=2,"
   "drawbox=x=0:y=0:w=1080:h=1920:color=0x170A25@0.11:t=fill,"
   "fps=30,format=yuv420p"
  )
  subprocess.run(['ffmpeg','-y','-hide_banner','-loglevel','error','-ss',str(start),'-t',str(dur),'-i',str(src),'-filter_complex',fc,'-an','-c:v','libx264','-preset','veryfast','-crf','19','-movflags','+faststart',str(dst)],check=True)
 concat=TMP/f'{name}.txt'; concat.write_text('\n'.join(f"file '{p}'" for p in clips)+'\n')
 base=TMP/f'{name}_base.mp4'
 subprocess.run(['ffmpeg','-y','-hide_banner','-loglevel','error','-f','concat','-safe','0','-i',str(concat),'-c','copy',str(base)],check=True)
 duration=sum(x[2] for x in cfg['clips']); sub=ass(name,cfg,duration); final=OUT/f'{name}.mp4'
 subprocess.run(['ffmpeg','-y','-hide_banner','-loglevel','error','-i',str(base),'-vf',f"subtitles='{sub}':fontsdir='{FONTS}'",'-an','-c:v','libx264','-preset','medium','-crf','20','-profile:v','high','-level','4.1','-pix_fmt','yuv420p','-movflags','+faststart',str(final)],check=True)
 print(final,final.stat().st_size)
