<?php
declare(strict_types=1);

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

function arc_rows(mysqli $con,string $sql,string $types='',array $params=[]):array
{
    return gsr_rows($con,$sql,$types,$params);
}

function arc_options(mysqli $con,array $access):array
{
    $employees=gsr_employee_options($con,$access);
    $months=arc_rows($con,'SELECT id,month name FROM jos_app_mmonth ORDER BY id ASC');
    $years=arc_rows($con,'SELECT id,year name FROM jos_app_year ORDER BY id DESC LIMIT 3');
    $components=arc_rows($con,"SELECT id,componentname name FROM jos_app_salarycomponentmaster WHERE otallow_status=1 ORDER BY orderby,id");

    $branchWhere=[];$branchTypes='';$branchParams=[];
    gsr_add_in('id',$access['branch'],$branchWhere,$branchTypes,$branchParams);
    $branches=arc_rows($con,'SELECT id,name FROM jos_app_orglocation WHERE '.($branchWhere?implode(' AND ',$branchWhere):'1=1').' ORDER BY name,id',$branchTypes,$branchParams);

    return [
        'employees'=>$employees,
        'months'=>$months,
        'years'=>$years,
        'components'=>$components,
        'payrolls'=>gsr_authorized_payrolls($con,$access),
        'branches'=>$branches,
        'types'=>[
            ['id'=>1,'name'=>'Monthly'],
            ['id'=>2,'name'=>'Per Day'],
            ['id'=>3,'name'=>'Per Hrs'],
        ],
    ];
}

function arc_has_id(array $rows,int $id):bool
{
    return gsr_id_in($rows,$id);
}

function arc_record(mysqli $con,array $access,int $id):?array
{
    if($id<1)return null;
    $where=['r.id=?','e.status IN (0,1)'];$types='i';$params=[$id];
    gsr_scope($access,$where,$types,$params);
    $rows=arc_rows($con,'SELECT r.* FROM jos_app_emp_eardeduction r INNER JOIN jos_app_employee e ON e.id=r.empid LEFT JOIN jos_app_employee_locationlog b ON b.app_empid=e.id WHERE '.implode(' AND ',$where).' GROUP BY r.id LIMIT 1',$types,$params);
    return $rows[0]??null;
}

function arc_post_values():array
{
    return [
        'empid'=>max(0,(int)($_POST['empid']??0)),
        'month'=>max(0,(int)($_POST['month']??0)),
        'year'=>max(0,(int)($_POST['year']??0)),
        'component'=>max(0,(int)($_POST['type']??0)),
        's_type'=>max(0,(int)($_POST['s_type']??0)),
        'grosspay'=>trim((string)($_POST['grosspay']??'')),
    ];
}

function arc_validate(array $value,array $options):array
{
    $errors=[];
    if(!arc_has_id($options['employees'],$value['empid']))$errors[]='Select a valid authorized employee.';
    if(!arc_has_id($options['months'],$value['month']))$errors[]='Select a valid month.';
    if(!arc_has_id($options['years'],$value['year']))$errors[]='Select a valid year.';
    if(!arc_has_id($options['components'],$value['component']))$errors[]='Select a valid OT / Allowance component.';
    if(!in_array($value['s_type'],[1,2,3],true))$errors[]='Select a valid type.';
    if($value['grosspay']===''||!is_numeric($value['grosspay']))$errors[]='Enter a valid amount.';
    elseif((float)$value['grosspay']<0)$errors[]='Amount cannot be negative.';
    elseif(strlen($value['grosspay'])>18)$errors[]='Amount is too large.';
    return array_values(array_unique($errors));
}

function arc_table_columns(mysqli $con,string $table):array
{
    return gsr_columns($con,$table);
}

function arc_insert_history(mysqli $con,int $id,array $value):void
{
    $available=array_flip(arc_table_columns($con,'jos_app_emp_eardeduction_editlog'));
    $candidate=[
        'earid'=>$id,
        'date'=>date('Y-m-d H:i:s'),
        'systemdate'=>date('Y-m-d H:i:s'),
        'month'=>$value['month'],
        'year'=>$value['year'],
        'empid'=>$value['empid'],
        'component'=>$value['component'],
        'grosspay'=>(float)$value['grosspay'],
        'rateperhr'=>0,
        's_type'=>$value['s_type'],
        'modify_by'=>(int)(current_user()['id']??0),
    ];
    $data=[];foreach($candidate as $column=>$entry)if(isset($available[$column]))$data[$column]=$entry;
    if(!$data)return;
    $columns=array_keys($data);$marks=implode(',',array_fill(0,count($columns),'?'));
    $types='';$params=[];foreach($data as $entry){if(is_int($entry))$types.='i';elseif(is_float($entry))$types.='d';else $types.='s';$params[]=$entry;}
    $stmt=gsr_stmt($con,'INSERT INTO jos_app_emp_eardeduction_editlog (`'.implode('`,`',$columns).'`) VALUES ('.$marks.')');
    $stmt->bind_param($types,...$params);$stmt->execute();$stmt->close();
}

function arc_save(mysqli $con,array $value,int $id):int
{
    $amount=(float)$value['grosspay'];
    $con->begin_transaction();
    try{
        if($id>0){
            $stmt=gsr_stmt($con,'UPDATE jos_app_emp_eardeduction SET date=CURDATE(),systemdate=NOW(),month=?,year=?,empid=?,component=?,s_type=?,rateperday=0,grosspay=?,rateperhr=0 WHERE id=?');
            $stmt->bind_param('iiiiidi',$value['month'],$value['year'],$value['empid'],$value['component'],$value['s_type'],$amount,$id);
        }else{
            $stmt=gsr_stmt($con,'INSERT INTO jos_app_emp_eardeduction (date,systemdate,month,year,empid,component,s_type,rateperday,grosspay,rateperhr) VALUES (CURDATE(),NOW(),?,?,?,?,?,0,?,0)');
            $stmt->bind_param('iiiiid',$value['month'],$value['year'],$value['empid'],$value['component'],$value['s_type'],$amount);
        }
        $stmt->execute();if(!$id)$id=$stmt->insert_id;$stmt->close();
        arc_insert_history($con,$id,$value);
        $con->commit();return $id;
    }catch(Throwable $e){$con->rollback();throw $e;}
}

function arc_filters(array $options,array &$errors):array
{
    $filters=[
        'filter_emp'=>max(0,(int)($_GET['filter_emp']??0)),
        'filt_payroll_location'=>max(0,(int)($_GET['filt_payroll_location']??0)),
        'filt_orglocation'=>max(0,(int)($_GET['filt_orglocation']??0)),
        'filter_type'=>max(0,(int)($_GET['filter_type']??0)),
        'filt_salary'=>max(0,(int)($_GET['filt_salary']??0)),
    ];
    foreach([
        ['filter_emp','employees','employee'],
        ['filt_payroll_location','payrolls','payroll location'],
        ['filt_orglocation','branches','branch location'],
        ['filter_type','components','OT / Allowance'],
        ['filt_salary','types','salary type'],
    ] as [$key,$list,$label]){
        if($filters[$key]&&!arc_has_id($options[$list],$filters[$key])){
            $errors[]='Invalid or unauthorized '.$label.'.';$filters[$key]=0;
        }
    }
    return $filters;
}

function arc_filter_query(array $filters):string
{
    return http_build_query(array_filter($filters,fn($value)=>(int)$value>0));
}

function arc_list(mysqli $con,array $access,array $filters,int $limit=0,int $offset=0,bool $count=false)
{
    $where=['e.status IN (0,1)'];$types='';$params=[];
    gsr_scope($access,$where,$types,$params);
    foreach([
        ['filter_emp','r.empid'],
        ['filt_payroll_location','e.payroll_location'],
        ['filt_orglocation','e.branch_location'],
        ['filter_type','r.component'],
        ['filt_salary','r.s_type'],
    ] as [$key,$column]){
        if($filters[$key]){$where[]=$column.'=?';$types.='i';$params[]=$filters[$key];}
    }
    $from=' FROM jos_app_emp_eardeduction r INNER JOIN jos_app_employee e ON e.id=r.empid LEFT JOIN jos_app_employee_locationlog b ON b.app_empid=e.id LEFT JOIN jos_app_salarycomponentmaster c ON c.id=r.component LEFT JOIN jos_app_mmonth m ON m.id=r.month';
    if($count){
        return (int)(arc_rows($con,'SELECT COUNT(DISTINCT r.id) total'.$from.' WHERE '.implode(' AND ',$where),$types,$params)[0]['total']??0);
    }
    $sql='SELECT r.id,r.empid,r.month,r.year,r.component,r.s_type,r.grosspay,e.name employee_name,c.componentname component_name,m.month month_name,(SELECT COUNT(*) FROM jos_app_emp_eardeduction_editlog h WHERE h.earid=r.id) history_count'.$from.' WHERE '.implode(' AND ',$where).' GROUP BY r.id ORDER BY (e.orderby=0),e.orderby,e.id,r.id';
    if($limit>0){$sql.=' LIMIT ? OFFSET ?';$types.='ii';$params[]=$limit;$params[]=$offset;}
    return arc_rows($con,$sql,$types,$params);
}

function arc_type_label(int $type):string
{
    return [1=>'Monthly',2=>'Per Day',3=>'Per Hrs'][$type]??'';
}

