#!/usr/bin/env python3
from __future__ import annotations
import datetime,json,os,sys,time,urllib.parse,urllib.request
from pathlib import Path
from zoneinfo import ZoneInfo
B='https://postiz-api.pain.io.vn/public/v1';FB='cmrioo6m00015j7c8ppe2dj97';YT='cmrhv05ze0009j7c8gjy7lmcn';H={'Authorization':os.environ['POSTIZ_API_KEY']}
def get_posts(a,b):
 q=urllib.parse.urlencode({'startDate':a,'endDate':b});r=json.load(urllib.request.urlopen(urllib.request.Request(B+'/posts?'+q,headers=H),timeout=180));return r if isinstance(r,list) else r.get('posts',r.get('data',[]))
def utc_iso(d):return d.astimezone(datetime.timezone.utc).isoformat(timespec='milliseconds').replace('+00:00','Z')
def main():
 p=Path(sys.argv[1]).resolve();up=json.load(open(p/'logs/postiz_uploads_bgm_remediation.json'))
 now=datetime.datetime.now(ZoneInfo('Asia/Ho_Chi_Minh'));lead=now+datetime.timedelta(minutes=15);end=now+datetime.timedelta(days=21)
 rows=get_posts(utc_iso(now-datetime.timedelta(days=1)),utc_iso(end+datetime.timedelta(days=1)));occ={FB:set(),YT:set()}
 for x in rows:
  it=x.get('integration');iid=it.get('id') if isinstance(it,dict) else x.get('integrationId') or it;dt=x.get('publishDate') or x.get('date')
  if iid in occ and dt:occ[iid].add(dt)
 candidates=[]
 for add in range(22):
  day=(now+datetime.timedelta(days=add)).date()
  for hh,mm in ((9,20),(19,0)):
   local=datetime.datetime(day.year,day.month,day.day,hh,mm,tzinfo=ZoneInfo('Asia/Ho_Chi_Minh'))
   if local>lead:candidates.append((local,utc_iso(local)))
 assert candidates and all((x[0].hour,x[0].minute) in ((9,20),(19,0)) for x in candidates) and any(x[0].hour==19 for x in candidates)
 local,chosen=next(x for x in candidates if chosen_free(x[1],occ))
 title=(p/'metadata/title.txt').read_text().strip();desc=(p/'metadata/description.txt').read_text().strip();raw=[x.strip() for x in (p/'metadata/tags.txt').read_text().split(',') if x.strip()]
 tags=[];total=0
 for x in raw:
  cost=len(x)*2
  if total+cost>=490:break
  tags.append({'value':x,'label':x});total+=cost
 payload={'type':'schedule','date':chosen,'shortLink':False,'tags':tags,'posts':[{'integration':{'id':FB},'value':[{'content':desc,'image':[{'id':up['facebook_video']['id'],'path':up['facebook_video']['path']}]}],'settings':{'__type':'facebook'}},{'integration':{'id':YT},'value':[{'content':desc,'image':[{'id':up['youtube_video']['id'],'path':up['youtube_video']['path']}]}],'settings':{'__type':'youtube','title':title,'type':'public','selfDeclaredMadeForKids':'no','thumbnail':{'id':up['thumbnail']['id'],'path':up['thumbnail']['path']}}}]}
 r=json.load(urllib.request.urlopen(urllib.request.Request(B+'/posts',data=json.dumps(payload).encode(),headers={**H,'Content-Type':'application/json'},method='POST'),timeout=300));rr=r if isinstance(r,list) else r.get('posts',r.get('data',[]));ids={x.get('postId') or x.get('id') for x in rr};ids.discard(None);assert len(ids)==2,(r,ids)
 found={}
 for _ in range(10):
  for x in get_posts(utc_iso(local-datetime.timedelta(hours=2)),utc_iso(local+datetime.timedelta(hours=2))):
   pid=x.get('id') or x.get('postId')
   if pid in ids:
    it=x.get('integration');iid=it.get('id') if isinstance(it,dict) else x.get('integrationId') or it;found[pid]={'integration_id':iid,'publish_date':x.get('publishDate') or x.get('date'),'state':x.get('state')}
  if len(found)==2 and {v['integration_id'] for v in found.values()}=={FB,YT} and all(v['state']=='QUEUE' and v['publish_date']==chosen for v in found.values()):break
  time.sleep(5)
 assert len(found)==2 and {v['integration_id'] for v in found.values()}=={FB,YT} and all(v['state']=='QUEUE' and v['publish_date']==chosen for v in found.values()),found
 out={'status':'PASS','reason':'distinct-bgm-remediation','date_local':local.isoformat(),'date_utc':chosen,'posts':found,'verified_at':datetime.datetime.now(datetime.timezone.utc).isoformat()};(p/'logs/postiz_calendar_bgm_remediation.json').write_text(json.dumps(out,ensure_ascii=False,indent=2)+'\n')
 d=json.load(open(p/'project.json'));d['postiz']=out;d['status']='completed';d['current_step']='completed';d['bgm_remediation']={'status':'PASS','bgm_volume':0.2,'distinct_variants':True,'calendar':out,'completed_at':out['verified_at']};open(p/'project.json','w').write(json.dumps(d,ensure_ascii=False,indent=2)+'\n');print(json.dumps(out,ensure_ascii=False))
def chosen_free(ts,occ):return ts not in occ[FB] and ts not in occ[YT]
if __name__=='__main__':main()
