// Build-time SDK compilation. Runtime PHP uses data, never downloaded executable code.
import {writeFile,mkdir,rm} from 'node:fs/promises';
import {createClient,Model} from '@picsart/ai-sdk';
import {syncModels} from '../src/server/model-sync';
import {modelSchema} from '../src/server/supported-models';
import {imageParams} from '../src/server/image-settings';
import {videoParams} from '../src/server/model-settings';
import catalog from '../shared/template-catalog.json';
const models=await syncModels();
const prompt='__PICSART_RUNTIME_PROMPT__',url='https://runtime-placeholder.invalid/picsart-reference.png';
const workflows:Record<string,{workflow:string;editWorkflow?:string;sync:boolean;pricingId:string}>={};
const requests:Record<string,Record<string,unknown>>={};
let captured:{workflow:string;payload:unknown}|undefined;
const ai=createClient({transport:{execute:async()=>{throw Error('Build cannot execute');},submit:async r=>{captured={workflow:r.workflow,payload:r.payload};return 'compiled';},poll:async()=>{throw Error('Build cannot poll');}}});
async function compile(id:string,key:string,params:Record<string,unknown>){
 captured=undefined;
 await ai.submit(id as Parameters<typeof ai.submit>[0],params as never);
 const prepared=captured as unknown as {workflow:string;payload:unknown}|undefined;
 if(!prepared)throw Error('No SDK request');
 // SDK embeds a JSON-encoded copy of params in Drive metadata. PHP records canonical
 // parameters in its own receipt; omit this duplicate so substitutions remain typed leaves.
 const payload=prepared.payload as {options?:{drive?:{attributes?:unknown}}};
 if(payload.options?.drive)delete payload.options.drive.attributes;
 function verifyLeaves(value:unknown):void {
  if(value&&typeof value==='object'){for(const v of Object.values(value))verifyLeaves(v);return;}
  if(typeof value==='string'&&[prompt,url].some(marker=>value.includes(marker)&&value!==marker))throw Error(`Non-leaf SDK placeholder in ${id}`);
 }
 verifyLeaves(prepared.payload);verifyLeaves(params);
 (requests[id]??={})[key]={...prepared,params};
}
for(const id of [...(models.image??[]).map(m=>m.id),...models.video.map(m=>m.id),'picsart-sod-v8-2','picsart-enhance']) {
 const m=Model(id) as unknown as {def:{workflow:string;editWorkflow?:string;syncExecute?:boolean;modelId?:string}};
 workflows[id]={workflow:m.def.workflow,editWorkflow:m.def.editWorkflow,sync:!!m.def.syncExecute,pricingId:m.def.modelId??id};
 const schema=modelSchema(id);
 if(models.video.some(m=>m.id===id)) {
  for(const loop of [false,true])for(const option of models.videoOptions![id][loop?'loop':'standard'])for(const duration of option.durations){
   const input={prompt,url,duration,resolution:option.resolution,aspectRatio:option.aspectRatio,loop};
   await compile(id,JSON.stringify([duration,option.resolution,option.aspectRatio,loop]),videoParams(schema,input));
  }
 }else if(id==='picsart-sod-v8-2'||id==='picsart-enhance'){
  await compile(id,'tool',{imageUrls:[url]});
 }else {
  for(const hasSource of [false,true])for(const aspect of ['auto','1:1','3:4','16:9','9:16']){
   try{await compile(id,JSON.stringify([hasSource,aspect]),imageParams(schema,prompt,hasSource?url:undefined,aspect));}catch{/* Unsupported combinations are not exposed by PHP. */}
  }
 }
}
await mkdir('plugin/picsart-product-videos/data',{recursive:true});
const requestDir='plugin/picsart-product-videos/data/requests';
await rm(requestDir,{recursive:true,force:true});await mkdir(requestDir,{recursive:true});
const requestFiles:Record<string,string>={};
for(const [id,variants] of Object.entries(requests)){
 const filename=`model-${Object.keys(requestFiles).length}.json`;
 await writeFile(`${requestDir}/${filename}`,JSON.stringify(variants)+'\n');requestFiles[id]=filename;
}
await writeFile('plugin/picsart-product-videos/data/runtime-manifest.json',JSON.stringify({sdkVersion:'6.2.3',catalog:models,workflows,requests:requestFiles,templates:catalog.templates.filter(t=>t.workspace),fidelity:catalog.fidelity,promptMarker:prompt,urlMarker:url})+'\n');
console.log(`Compiled ${Object.values(requests).reduce((n,r)=>n+Object.keys(r).length,0)} canonical SDK requests.`);
