<?php
declare(strict_types=1);

require_once __DIR__.'/gross-salary-report-common.php';

function scr_options(mysqli $con,array $access):array
{
    $payrolls=gsr_authorized_payrolls($con,$access);
    $where=["payscalename<>''"];$types='';$params=[];gsr_add_in('orgid',$access['payroll'],$where,$types,$params);
    $payscales=gsr_rows($con,'SELECT id,payscalename name,orgid FROM jos_app_payscale_nongrid WHERE '.implode(' AND ',$where).' ORDER BY payscalename,id',$types,$params);
    $categories=gsr_rows($con,'SELECT id,designation_name name FROM jos_app_emp_category ORDER BY designation_name,id');
    $subbranchEnabled=(int)(gsr_rows($con,'SELECT subbranch FROM jos_app_usersetting ORDER BY id LIMIT 1')[0]['subbranch']??0)===1;
    $subbranches=[];if($subbranchEnabled){$w=[];$t='';$p=[];gsr_add_in('id',$access['subbranch'],$w,$t,$p);$subbranches=gsr_rows($con,'SELECT id,subbranch name FROM jos_app_subbranch WHERE '.($w?implode(' AND ',$w):'1=1').' ORDER BY subbranch,id',$t,$p);}
    $employees=gsr_employee_options($con,$access);
    return compact('payrolls','payscales','categories','subbranches','employees','subbranchEnabled');
}

function scr_has_id(array $rows,int $id):bool{return $id===0||gsr_id_in($rows,$id);}

function scr_filters(mysqli $con,array $access,array $options,array &$errors):array
{
    $f=['filter_payscale'=>max(0,(int)($_GET['filter_payscale']??0)),'filter_emp'=>max(0,(int)($_GET['filter_emp']??0)),'filt_org'=>max(0,(int)($_GET['filt_org']??0)),'filt_pf'=>(string)($_GET['filt_pf']??''),'filt_cat'=>max(0,(int)($_GET['filt_cat']??0)),'filt_subbranch'=>max(0,(int)($_GET['filt_subbranch']??0))];
    foreach([['filter_payscale','payscales','Pay Scale'],['filter_emp','employees','employee'],['filt_org','payrolls','payroll location'],['filt_cat','categories','category'],['filt_subbranch','subbranches','sub-branch']] as [$key,$list,$label])if(!scr_has_id($options[$list],$f[$key])){$errors[]='Invalid or unauthorized '.$label.'.';$f[$key]=0;}
    if(!in_array($f['filt_pf'],['','1','2'],true)){$errors[]='Invalid PF Applicable value.';$f['filt_pf']='';}
    if(!$options['subbranchEnabled'])$f['filt_subbranch']=0;
    return $f;
}

function scr_report(mysqli $con,array $access,array $f):array
{
    $where=['e.gen_salary=1','e.status IN (0,1)'];$types='';$params=[];gsr_add_in('e.payroll_location',$access['payroll'],$where,$types,$params);gsr_add_in('e.branch_location',$access['branch'],$where,$types,$params);gsr_add_in('e.subbranch',$access['subbranch'],$where,$types,$params);gsr_add_in('e.addpayroll_location',$access['additional'],$where,$types,$params);gsr_add_in('b.orglocation',$access['terminal'],$where,$types,$params);
    foreach([['filter_payscale','e.payscale'],['filter_emp','e.id'],['filt_org','e.payroll_location'],['filt_cat','e.category'],['filt_subbranch','e.subbranch']] as [$key,$column])if((int)$f[$key]>0){$where[]=$column.'=?';$types.='i';$params[]=(int)$f[$key];}
    if($f['filt_pf']!==''){$where[]='e.pf_appli=?';$types.='i';$params[]=(int)$f['filt_pf'];}
    $sql="SELECT DISTINCT e.id,e.name,e.orderby,e.payscale,e.payroll_location,e.category,e.pf_appli,
                 ps.payscalename,ps.month payscale_month,ps.year payscale_year,
                 gp.s_type,gp.grosspay,gp.rateperday,gp.rateperhr
          FROM jos_app_employee e
          LEFT JOIN jos_app_employee_locationlog b ON b.app_empid=e.id
          LEFT JOIN jos_app_payscale_nongrid ps ON ps.id=e.payscale
          LEFT JOIN jos_app_emp_gross_pay gp ON gp.id=(SELECT g2.id FROM jos_app_emp_gross_pay g2 WHERE g2.empid=e.id AND DATE(CONCAT(g2.year,'-',LPAD(g2.month,2,'0'),'-01'))<=DATE_FORMAT(CURDATE(),'%Y-%m-01') ORDER BY DATE(CONCAT(g2.year,'-',LPAD(g2.month,2,'0'),'-01')) DESC,g2.id DESC LIMIT 1)
          WHERE ".implode(' AND ',$where).' ORDER BY e.orderby,e.id';
    $employees=gsr_rows($con,$sql,$types,$params);
    $componentWhere=[];$ct='';$cp=[];if((int)$f['filt_org']>0){$componentWhere[]='so.orgid=?';$ct.='i';$cp[]=(int)$f['filt_org'];}else gsr_add_in('so.orgid',$access['payroll'],$componentWhere,$ct,$cp);
    $components=gsr_rows($con,"SELECT so.componentname id,MIN(so.componenttype) componenttype,MIN(so.orderby) orderby,sc.componentname name FROM jos_app_salaryorganisation so INNER JOIN jos_app_salarycomponentmaster sc ON sc.id=so.componentname INNER JOIN jos_app_emp_payscale_config_grid d ON d.component_id=so.componenttype AND d.componenttype_id=so.componentname WHERE ".($componentWhere?implode(' AND ',$componentWhere):'1=1').' AND d.calculation>=0 GROUP BY so.componentname,sc.componentname ORDER BY componenttype,orderby,so.componentname',$ct,$cp);
    $details=[];$scaleIds=array_values(array_unique(array_filter(array_map(fn($r)=>(int)$r['payscale'],$employees))));
    if($scaleIds){$marks=implode(',',array_fill(0,count($scaleIds),'?'));foreach(gsr_rows($con,"SELECT d.payscaleid,d.componenttype_id,d.calculation,d.value_amt,d.percentageof,c.calculation_type FROM jos_app_emp_payscale_config_grid d LEFT JOIN jos_app_calculation_type c ON c.id=d.calculation WHERE d.payscaleid IN ($marks)",str_repeat('i',count($scaleIds)),$scaleIds) as $row)$details[(int)$row['payscaleid']][(int)$row['componenttype_id']]=$row;}
    $componentNames=[];foreach(gsr_rows($con,'SELECT id,componentname FROM jos_app_salarycomponentmaster') as $row)$componentNames[(int)$row['id']]=(string)$row['componentname'];
    return compact('employees','components','details','componentNames');
}

function scr_query(array $f):string{return http_build_query(array_filter($f,fn($v)=>$v!==''&&(int)$v>0));}
function scr_rate(array $e):string{if(in_array((int)$e['s_type'],[1,5],true))return(string)($e['grosspay']??'');if(in_array((int)$e['s_type'],[2,3],true))return(string)($e['rateperday']??'');return(string)($e['rateperhr']??'');}
function scr_type_code(int $type):string{return[1=>'M',2=>'D',3=>'DW',4=>'H',5=>'MW'][$type]??'';}
function scr_percentage_names(string $value,array $names):string{$out=[];foreach(array_filter(array_map('intval',explode(',',$value))) as $id)if(isset($names[$id]))$out[]=$names[$id];return implode(', ',$out);}
function scr_h($value):string{$text=(string)$value;if(defined('SCR_EXPORT')&&SCR_EXPORT===true&&preg_match('/^[=+\-@]/u',$text))$text="'".$text;return h($text);}

function scr_render_table(array $data):void
{
    ['employees'=>$employees,'components'=>$components,'details'=>$details,'componentNames'=>$componentNames]=$data;?>
    <div class="overflow-x-auto"><table class="w-full min-w-[1200px] border-collapse text-sm"><thead class="bg-slate-100 text-xs font-extrabold uppercase text-slate-700"><tr><th class="border border-slate-200 px-4 py-3">No</th><th class="border border-slate-200 px-4 py-3">Name</th><th colspan="2" class="border border-slate-200 px-4 py-3">Payscale</th><?php foreach($components as $c):?><th class="border border-slate-200 px-4 py-3"><?=scr_h($c['name'])?></th><?php endforeach;?></tr></thead><tbody><?php if(!$employees):?><tr><td colspan="<?=4+count($components)?>" class="border border-slate-200 px-5 py-14 text-center font-semibold text-slate-400">No salary configuration records found.</td></tr><?php endif;?><?php foreach($employees as $i=>$e):$scale=(int)$e['payscale'];$map=$details[$scale]??[];?><tr><td rowspan="4" class="border border-slate-200 px-4 py-3 align-top font-bold"><?=$i+1?> <?=scr_h(scr_type_code((int)$e['s_type']))?></td><td rowspan="4" class="border border-slate-200 px-4 py-3 align-top font-bold"><?=scr_h($e['name'])?><div class="mt-1 text-xs font-semibold text-slate-500">Rs: <?=scr_h(scr_rate($e))?></div></td><td rowspan="4" class="border border-slate-200 px-4 py-3 align-top"><?=scr_h($e['payscalename']??'')?><div class="mt-1 text-xs text-slate-500"><?=scr_h((string)($e['payscale_month']??''))?> <?=scr_h((string)($e['payscale_year']??''))?></div></td></tr><tr><td class="border border-slate-200 px-4 py-3 font-bold">Calculation Type</td><?php foreach($components as $c):$d=$map[(int)$c['id']]??[];?><td class="border border-slate-200 px-4 py-3 text-center"><?=scr_h($d['calculation_type']??'')?></td><?php endforeach;?></tr><tr><td class="border border-slate-200 px-4 py-3 font-bold">Value</td><?php foreach($components as $c):$d=$map[(int)$c['id']]??[];?><td class="border border-slate-200 px-4 py-3 text-center"><?=scr_h((string)($d['value_amt']??''))?></td><?php endforeach;?></tr><tr><td class="border border-slate-200 px-4 py-3 font-bold">% OF</td><?php foreach($components as $c):$d=$map[(int)$c['id']]??[];?><td class="border border-slate-200 px-4 py-3 text-center"><?=scr_h(scr_percentage_names((string)($d['percentageof']??''),$componentNames))?></td><?php endforeach;?></tr><?php endforeach;?></tbody></table></div><?php
}
