#!/usr/bin/env python3
"""Пересчитывает локальные времена слов в единую глобальную шкалу."""
from __future__ import annotations
import argparse, json
from pathlib import Path

def main():
    ap=argparse.ArgumentParser(); ap.add_argument('stitch_plan'); ap.add_argument('--out',default='timeline.json'); args=ap.parse_args()
    plan=json.loads(Path(args.stitch_plan).read_text(encoding='utf-8')); global_words=[]; offset=0.0; clips=[]
    for si,s in enumerate(plan['sources']):
        d=json.loads(Path(s['transcript']).read_text(encoding='utf-8')); words=d['words'] if isinstance(d,dict) else d
        clip_d=max(0,float(s['out'])-float(s['in']))
        clips.append({'source_index':si,'file':s['file'],'source_in':float(s['in']),'source_out':float(s['out']),
                      'global_start':round(offset,3),'global_end':round(offset+clip_d,3)})
        for w in words:
            if w['start']+1e-6 < float(s['in']) or w['start'] >= float(s['out']): continue
            global_words.append({**w,'id':len(global_words),'source_word_id':w.get('id'),'source_index':si,'local_start':w['start'],'local_end':w['end'],
                'start':round(offset+w['start']-float(s['in']),3),'end':round(offset+w['end']-float(s['in']),3)})
        offset+=clip_d
    timeline={'version':'2.1','clips':clips,'words':global_words,'expected_duration':round(offset,3),
              'first_word_start':global_words[0]['start'] if global_words else None,
              'last_word_end':global_words[-1]['end'] if global_words else None,
              'tail_after_speech':round(offset-global_words[-1]['end'],3) if global_words else None}
    Path(args.out).write_text(json.dumps(timeline,ensure_ascii=False,indent=2),encoding='utf-8')
    print(json.dumps({'clips':len(clips),'words':len(global_words),'expected_duration':timeline['expected_duration']},ensure_ascii=False,indent=2))
if __name__=='__main__': main()
