import type {Event} from './engine';

/** Educational indicators only. Not a complete legal OTR1 compliance assessment. */
export type OtrIndicator={code:string;severity:'info'|'warning';message:string;seconds?:number};
export type DaySummary={date:string;drivingSeconds:number;workSeconds:number;restSeconds:number;distanceKmEstimate:number};
const DAY=86400000;
const overlap=(start:number,end:number,a:number,b:number)=>Math.max(0,Math.min(end,b)-Math.max(start,a))/1000;
const dateKey=(timestamp:number)=>new Date(timestamp).toISOString().slice(0,10);
export function summarize57Days(events:Event[],now:number):DaySummary[]{
 const midnight=Date.parse(dateKey(now)+'T00:00:00.000Z');
 return Array.from({length:57},(_,index)=>{
  const start=midnight-(56-index)*DAY,end=start+DAY;
  const sum:DaySummary={date:dateKey(start),drivingSeconds:0,workSeconds:0,restSeconds:0,distanceKmEstimate:0};
  for(const e of events){const sec=overlap(e.start,e.end,start,end);if(!sec)continue;
   if(e.activity==='DRIVING'){sum.drivingSeconds+=sec;sum.distanceKmEstimate+=e.speed*sec/3600;}
   if(e.activity==='WORK')sum.workSeconds+=sec;
   if(e.activity==='REST')sum.restSeconds+=sec;
  }
  return sum;
 });
}
/** Accumulated driving since a qualifying uninterrupted 45-minute break, or a
 * qualifying split 15-minute break followed by a 30-minute break. Work and
 * availability do not count as breaks. Input may be unsorted or fragmented.
 * Only simulated recorded events are considered.
 */
export function drivingAfterQualifyingBreak(events:Event[]):number{
 const sorted=[...events].filter(e=>e.end>e.start).sort((a,b)=>a.start-b.start);
 let driving=0,firstPart=false,restRun=0,lastRestEnd:number|null=null;
 const completeRest=()=>{
  if(restRun>=2700||(firstPart&&restRun>=1800)){driving=0;firstPart=false;}
  else if(restRun>=900)firstPart=true;
  restRun=0;lastRestEnd=null;
 };
 for(const e of sorted){
  if(e.activity==='REST'){
   if(lastRestEnd!==null&&e.start!==lastRestEnd)completeRest();
   restRun+=Math.max(0,(e.end-e.start)/1000);
   lastRestEnd=e.end;
  }else{
   if(restRun>0)completeRest();
   if(e.activity==='DRIVING')driving+=(e.end-e.start)/1000;
  }
 }
 if(restRun>0)completeRest();
 return driving;
}
export function educationalOtrIndicators(events:Event[],now:number):OtrIndicator[]{
 const days=summarize57Days(events,now),current=days.at(-1)!;
 const result:OtrIndicator[]=[];
 const since=drivingAfterQualifyingBreak(events);
 if(since>4.5*3600)result.push({code:'BREAK_4H30',severity:'warning',message:'Conduite cumulée au-delà de 4 h 30 sans pause qualifiante enregistrée.',seconds:since});
 if(current.drivingSeconds>9*3600)result.push({code:'DAY_9H',severity:'info',message:'Plus de 9 h de conduite aujourd’hui : une extension peut être permise selon les conditions applicables.',seconds:current.drivingSeconds});
 if(current.drivingSeconds>10*3600)result.push({code:'DAY_10H',severity:'warning',message:'Plus de 10 h de conduite sur cette journée UTC simulée.',seconds:current.drivingSeconds});
 const weekStart=(t:number)=>{const date=new Date(t),dow=(date.getUTCDay()+6)%7;return Date.UTC(date.getUTCFullYear(),date.getUTCMonth(),date.getUTCDate()-dow)};
 const week=weekStart(now);
 const currentWeek=days.filter(d=>Date.parse(d.date+'T00:00:00Z')>=week).reduce((s,d)=>s+d.drivingSeconds,0);
 if(currentWeek>56*3600)result.push({code:'WEEK_56H',severity:'warning',message:'Conduite hebdomadaire supérieure à 56 h dans les événements simulés.',seconds:currentWeek});
 const fortnight=days.filter(d=>Date.parse(d.date+'T00:00:00Z')>=week-7*DAY).reduce((s,d)=>s+d.drivingSeconds,0);
 if(fortnight>90*3600)result.push({code:'FORTNIGHT_90H',severity:'warning',message:'Conduite supérieure à 90 h sur la semaine courante et la précédente.',seconds:fortnight});
 return result;
}
