<?php
declare(strict_types=1);
require_once __DIR__.'/daily-attendance-log-common.php';
function dsr_options(mysqli $con):array{return['payrolls'=>dal_rows($con,'SELECT id,name FROM jos_app_payrolllocation WHERE status=1 ORDER BY name,id'),'departments'=>dal_rows($con,'SELECT id,department name FROM jos_app_department ORDER BY department,id'),'categories'=>dal_rows($con,'SELECT id,designation_name name FROM jos_app_emp_category ORDER BY designation_name,id'),'branches'=>dal_rows($con,'SELECT id,name FROM jos_app_orglocation ORDER BY name,id'),'shifts'=>dal_rows($con,'SELECT id,COALESCE(NULLIF(shift_type,""),shortname) name FROM jos_app_empshift ORDER BY shift_type,id')];}
function dsr_filters(array $s):array{return['date'=>dal_date((string)($s['filter_date']??''))??date('Y-m-d'),'payroll'=>dal_int($s['filter_payrolllocation']??0),'department'=>dal_int($s['filter_department']??0),'category'=>dal_int($s['filt_cat']??0),'branch'=>dal_int($s['filter_orglocation']??0),'status'=>in_array((int)($s['stype']??0),[0,1,2],true)?(int)($s['stype']??0):0,'shift'=>dal_int($s['filter_shift']??0)];}
function dsr_validate(array $f,array $o):array{$e=[];if(!$f['payroll'])$e[]='Payroll Location is required.';foreach([['payroll','payrolls','payroll location'],['department','departments','department'],['category','categories','category'],['branch','branches','branch location'],['shift','shifts','shift']]as[$k,$l,$n])if(!dal_valid_option($o[$l],$f[$k]))$e[]='Invalid or unauthorized '.$n.'.';return$e;}
function dsr_minutes(string $v):?int{$v=trim($v);if($v===''||$v==='0')return null;$t=strtotime($v);return$t===false?null:(int)date('H',$t)*60+(int)date('i',$t);}
function dsr_report(mysqli $con,array $f):array{
 $where=['e.status=1','e.payroll_location=?'];$types='i';$p=[$f['payroll']];foreach([['e.depat','department'],['e.category','category'],['e.branch_location','branch']]as[$c,$k])if($f[$k]){$where[]="$c=?";$types.='i';$p[]=$f[$k];}
 $emps=dal_rows($con,'SELECT DISTINCT e.id,e.name,e.orderby,e.branch_location,e.depat,e.designation,d.department,b.name branch_name,ec.designation_name designation_name FROM jos_app_employee e LEFT JOIN jos_app_employee_locationlog el ON el.app_empid=e.id LEFT JOIN jos_app_department d ON d.id=e.depat LEFT JOIN jos_app_orglocation b ON b.id=e.branch_location LEFT JOIN jos_app_emp_category ec ON ec.id=e.category WHERE '.implode(' AND ',$where).' ORDER BY e.orderby=0,e.orderby,e.name,e.id',$types,$p);if(!$emps)return[];
 $ids=array_map('intval',array_column($emps,'id'));$marks=implode(',',array_fill(0,count($ids),'?'));$idTypes=str_repeat('i',count($ids));$day=$f['date'];
 $sched=[];if(dal_table_exists($con,'jos_app_mscheduling')){foreach(dal_rows($con,'SELECT m.empid,m.schedule,s.shift_type,s.shortname,s.in_time,s.out_time FROM jos_app_mscheduling m LEFT JOIN jos_app_empshift s ON s.id=m.schedule WHERE m.empid IN ('.$marks.') AND DATE(CONCAT(m.year,"-",m.month,"-",m.day))=?',$idTypes.'s',array_merge($ids,[$day]))as$x)$sched[(int)$x['empid']]=$x;}
 $logs=dal_rows($con,'SELECT a.*,s.shift_type,s.shortname,s.in_time shift_in,s.out_time shift_out,l.gatepass FROM jos_app_attendance_log a LEFT JOIN jos_app_empshift s ON s.id=a.shiftid LEFT JOIN jos_app_orglocation l ON l.id=a.orglocation WHERE a.empid IN ('.$marks.') AND DATE(a.entrydate)=? ORDER BY a.empid,a.entrydate,a.id',$idTypes.'s',array_merge($ids,[$day]));$by=[];foreach($logs as$x)$by[(int)$x['empid']][]=$x;
 $temp=[];if(dal_table_exists($con,'jos_app_attendance_log_temp'))$temp=dal_rows($con,'SELECT * FROM jos_app_attendance_log_temp WHERE empid IN ('.$marks.') AND DATE(date)=? AND COALESCE(type,0)<>4 ORDER BY empid,date,time,id',$idTypes.'s',array_merge($ids,[$day]));$tempBy=[];foreach($temp as$x)$tempBy[(int)$x['empid']][]=$x;
 $leave=[];if(dal_table_exists($con,'jos_app_leavestatus_log'))foreach(dal_rows($con,'SELECT empid,leavetype,status FROM jos_app_leavestatus_log WHERE empid IN ('.$marks.') AND DATE(leavedate)=? AND status IN (2,3) ORDER BY id DESC',$idTypes.'s',array_merge($ids,[$day]))as$x)if(!isset($leave[(int)$x['empid']]))$leave[(int)$x['empid']]=$x;
 $rows=[];foreach($emps as$e){$id=(int)$e['id'];$sc=$sched[$id]??null;if($f['shift']&&(int)($sc['schedule']??0)!==$f['shift'])continue;$punch=[];$worked=0;$scheduled=0;$notOut=false;$approved=false;foreach($by[$id]??[]as$x){if((int)($x['gatepass']??1)!==1)continue;$in=trim((string)($x['in_time']??''));$out=trim((string)($x['out_time']??''));if($in!=='')$punch[]='In - '.dal_display_time($in);if($out!=='')$punch[]='Out - '.dal_display_time($out);elseif($in!=='')$notOut=true;$worked+=dal_duration($in,$out,substr((string)$x['entrydate'],0,10),substr((string)($x['exitdate']??''),0,10));$approved=$approved||!empty($x['approved_by']);}
 foreach($tempBy[$id]??[]as$x){$v=trim((string)($x['time']??''));if($v!=='')$punch[]='Punch - '.dal_display_time($v);}
 if($sc)$scheduled=dal_duration((string)$sc['in_time'],(string)$sc['out_time'],$day,'');$status=$worked>0||$punch?'Present':'Absent';if(isset($leave[$id])&&!$punch)$status='Leave';elseif(!$punch&&strtolower(date('l',strtotime($day)))==='sunday')$status='Weeklyoff';if($notOut)$status='Not logout';$statusCode=($worked>0||$punch||$notOut)?'P':'A';if(($f['status']===1&&$statusCode!=='P')||($f['status']===2&&$statusCode!=='A'))continue;$extra=max(0,$worked-$scheduled);$loss=max(0,$scheduled-$worked);$late=0;if($sc&&$punch){$first=dsr_minutes(preg_replace('/^.*-\s*/','',$punch[0]));$start=dsr_minutes((string)$sc['in_time']);if($first!==null&&$start!==null)$late=max(0,$first-$start);}
 $rows[]=['employee'=>$e,'schedule'=>$sc,'scheduled'=>$scheduled,'punches'=>$punch,'worked'=>$worked,'extra'=>$extra,'loss'=>$loss,'status'=>$status,'late'=>$late,'approved'=>$approved];}
 return$rows;}
function dsr_render(array $rows):void{?><div class="overflow-x-auto"><table class="min-w-[1350px] w-full text-sm"><thead class="bg-slate-900 text-white"><tr><?php foreach(['Sr No','Employee Name','Designation','Branch','Schedule Shift','Total Working Hrs.','Present Working Hrs.','Total Hrs.','Extra/Lost hrs','Status','Late Mark']as$h):?><th class="border border-slate-700 px-3 py-3 text-center font-bold"><?=h($h)?></th><?php endforeach;?></tr></thead><tbody class="divide-y divide-slate-100"><?php foreach($rows as$i=>$r):?><tr class="align-top"><td class="border p-3 text-center"><?=$i+1?></td><td class="border p-3 text-center font-bold"><?=h($r['employee']['name'])?></td><td class="border p-3 text-center"><?=h($r['employee']['designation_name']?:$r['employee']['designation'])?></td><td class="border p-3 text-center"><?=h($r['employee']['branch_name']??'')?></td><td class="border p-3 text-center font-bold"><?=h($r['schedule']?($r['schedule']['shift_type']?:$r['schedule']['shortname']):'Not assigned')?></td><td class="border p-3 text-center"><?=h(dal_hhmm($r['scheduled']))?></td><td class="border p-3 text-center"><?=h($r['punches']?implode("\n",$r['punches']):'-')?></td><td class="border p-3 text-center font-bold"><?=h(dal_hhmm($r['worked']))?></td><td class="border p-3 text-center"><?=h($r['extra']?'E : + '.dal_hhmm($r['extra']):($r['loss']?'L : - '.dal_hhmm($r['loss']):'-'))?></td><td class="border p-3 text-center font-bold"><?=h($r['status'])?></td><td class="border p-3 text-center"><?=h(($r['late']?dal_hhmm($r['late']):'-').($r['approved']?' LM approval':''))?></td></tr><?php endforeach;if(!$rows):?><tr><td colspan="11" class="px-6 py-12 text-center font-semibold text-slate-400">No employees match the selected filters.</td></tr><?php endif;?></tbody></table></div><?php }
