import React from 'react';
import {AbsoluteFill,Composition,OffthreadVideo,Img,Sequence,registerRoot,staticFile,useCurrentFrame,interpolate,cancelRender,delayRender,continueRender} from 'remotion';
import {loadFont} from '@remotion/fonts';
import edit from './production/edit.json';

const fontFamily='HiobProject';
const accents={basic:'#FAF7EE',question:'#FFF19E',info:'#B9FFE4',cta:'#D4FF89'};
const resource=(file:string)=>staticFile(file.replace(/^public\//,''));
const textCheck=delayRender('Checking Korean title and phrase widths');
const fontReady=loadFont({family:fontFamily,url:resource(edit.font.file),weight:'400'});
fontReady.then(()=>{
  const canvas=document.createElement('canvas'),context=canvas.getContext('2d');
  if(!context)throw new Error('자막 폭을 검사하지 못했습니다.');
  for(const [items,size,width]of [[edit.captions,edit.captionPx,794],[edit.titles,edit.titlePx,838]] as const){
    context.font=`400 ${size}px "${fontFamily}"`;
    for(const cue of items)for(const line of cue.lines)if(context.measureText(line).width>width)throw new Error(`${cue.id}: 글자가 안전영역을 넘습니다. 작은 글자로 바꾸기 전에 의미 구절과 줄바꿈을 나누세요.`);
  }
  context.font=`400 23px "${fontFamily}"`;
  if(context.measureText(edit.disclosure).width>838)throw new Error('고지 문구가 안전영역을 넘습니다. 문구를 줄이세요.');
  context.font=`400 28px "${fontFamily}"`;
  for(const panel of edit.images)if(context.measureText(panel.label).width>790)throw new Error(`${panel.id}: 자료 제목이 너무 깁니다.`);
  continueRender(textCheck);
}).catch(cancelRender);

function Shot({cut}:{cut:(typeof edit.cuts)[number]}){
  return <AbsoluteFill style={{overflow:'hidden'}}><OffthreadVideo src={resource(cut.file)} muted trimBefore={cut.trimBefore} style={{width:'100%',height:'100%',objectFit:'cover'}}/><AbsoluteFill style={{background:'linear-gradient(180deg,rgba(9,23,25,.62),transparent 34%,transparent 48%,rgba(9,23,25,.45))'}}/></AbsoluteFill>;
}
function TextCue({cue,title=false}:{cue:any;title?:boolean}){
  const frame=useCurrentFrame(),offset=interpolate(frame,[0,5],[10,0],{extrapolateRight:'clamp'});
  const top=title?(cue.position==='middle'?730:310):(edit.captionPosition==='middle'?810:1200);
  return <div data-safe-text style={{position:'absolute',left:76,right:166,top,fontFamily,fontSize:title?edit.titlePx:edit.captionPx,fontWeight:400,lineHeight:1.15,color:title?accents[cue.style as keyof typeof accents]:'#FAF7EE',textAlign:title?'left':'center',textShadow:'0 3px 12px #0008',background:title?'transparent':'#102731ed',padding:title?0:'12px 22px 16px',borderRadius:title?0:15,transform:`translateY(${offset}px)`}}>{cue.lines.map((line:string,i:number)=>{
    if(!title&&cue.emphasis&&line.includes(cue.emphasis)){const index=line.indexOf(cue.emphasis);return <div key={i} style={{whiteSpace:'pre'}}>{line.slice(0,index)}<span style={{color:'#B9FFE4'}}>{cue.emphasis}</span>{line.slice(index+cue.emphasis.length)}</div>;}
    return <div key={i} style={{whiteSpace:'pre'}}>{line}</div>;
  })}</div>;
}
function Reel(){
  return <AbsoluteFill style={{background:'#102731',overflow:'hidden'}}>
    {edit.cuts.map(cut=><Sequence key={cut.id} from={cut.from} durationInFrames={cut.durationInFrames} premountFor={10}><Shot cut={cut}/></Sequence>)}
    {edit.images.map(panel=><Sequence key={'image-'+panel.id} from={Math.round(panel.start*edit.fps)} durationInFrames={Math.round(panel.end*edit.fps)-Math.round(panel.start*edit.fps)} premountFor={5}><div style={{position:'absolute',top:600,left:76,width:838,height:520,boxSizing:'border-box',background:'#FAF7EE',padding:24,borderRadius:18,boxShadow:'0 8px 32px #0005'}}><div data-safe-text style={{fontFamily,fontSize:28,color:'#102731',height:44,whiteSpace:'pre'}}>{panel.label}</div><Img src={resource(panel.file)} style={{width:'100%',height:428,objectFit:'contain'}}/></div></Sequence>)}
    {edit.titles.map(cue=><Sequence key={cue.id} from={Math.round(cue.start*edit.fps)} durationInFrames={Math.round(cue.end*edit.fps)-Math.round(cue.start*edit.fps)} premountFor={5}><TextCue cue={cue} title/></Sequence>)}
    {edit.captions.map(cue=><Sequence key={cue.id} from={Math.round(cue.start*edit.fps)} durationInFrames={Math.round(cue.end*edit.fps)-Math.round(cue.start*edit.fps)} premountFor={5}><TextCue cue={cue}/></Sequence>)}
    {edit.disclosure&&<div data-safe-text style={{position:'absolute',left:76,right:166,top:222,fontFamily,fontSize:23,color:'#FAF7EE',textShadow:'0 2px 8px #000'}}>{edit.disclosure}</div>}
  </AbsoluteFill>;
}
registerRoot(()=> <Composition id="HiobReel" component={Reel} width={1080} height={1920} fps={edit.fps} durationInFrames={edit.durationInFrames}/>);
