<?php
declare(strict_types=1);

require_once __DIR__ . '/../attendance/daily-attendance-log-common.php';

function dnlo_scope(mysqli $con): array
{
    $user = current_user() ?: [];
    if ((int)($user['role_id'] ?? 0) === 1) return ['restricted' => false, 'terminals' => []];
    $columns = dal_columns($con, 'jos_admin_users');
    if (!dal_has($columns, 'terminal_access')) return ['restricted' => true, 'terminals' => []];
    $rows = dal_rows($con, 'SELECT terminal_access FROM jos_admin_users WHERE id=? AND status=1 LIMIT 1', 'i', [(int)($user['id'] ?? 0)]);
    $ids = array_values(array_unique(array_filter(array_map('intval', explode(',', (string)($rows[0]['terminal_access'] ?? ''))))));
    return ['restricted' => true, 'terminals' => $ids];
}

function dnlo_in(array $ids, string &$types, array &$params): string
{
    $types .= str_repeat('i', count($ids));
    array_push($params, ...$ids);
    return implode(',', array_fill(0, count($ids), '?'));
}

function dnlo_options(mysqli $con, array $scope): array
{
    $locations = [];
    if (!$scope['restricted']) {
        $locations = dal_rows($con, 'SELECT id,name FROM jos_app_orglocation ORDER BY name,id');
    } elseif ($scope['terminals']) {
        $types = ''; $params = [];
        $marks = dnlo_in($scope['terminals'], $types, $params);
        $locations = dal_rows($con, "SELECT id,name FROM jos_app_orglocation WHERE id IN ($marks) ORDER BY name,id", $types, $params);
    }
    $setting = dal_table_exists($con, 'jos_app_usersetting') ? (dal_rows($con, 'SELECT store_name,subbranch FROM jos_app_usersetting LIMIT 1')[0] ?? []) : [];
    return [
        'shifts' => dal_rows($con, 'SELECT id,COALESCE(NULLIF(shift_type,""),shortname) name FROM jos_app_empshift ORDER BY shift_type,id'),
        'departments' => dal_rows($con, 'SELECT id,department name FROM jos_app_department ORDER BY department,id'),
        'locations' => $locations,
        'subbranches' => !empty($setting['subbranch']) && dal_table_exists($con, 'jos_app_subbranch') ? dal_rows($con, 'SELECT id,subbranch name FROM jos_app_subbranch ORDER BY subbranch,id') : [],
        'show_subbranch' => !empty($setting['subbranch']),
        'company' => trim((string)($setting['store_name'] ?? '')) ?: APP_NAME,
        'export' => dnlo_export_enabled($con),
    ];
}

function dnlo_export_enabled(mysqli $con): bool
{
    if (!dal_table_exists($con, 'jos_app_exporttoexcel_config')) return false;
    return (bool)dal_rows($con, "SELECT id FROM jos_app_exporttoexcel_config WHERE layout='Daily Not Logged Out Report' AND status=1 LIMIT 1");
}

function dnlo_filters(array $source): array
{
    $submitted = array_key_exists('filter_date', $source);
    $raw = trim((string)($source['filter_date'] ?? ''));
    $date = dal_date($raw);
    if ($date === null && preg_match('/^\d{2}-\d{2}-\d{4}$/', $raw)) {
        $parsed = DateTimeImmutable::createFromFormat('!d-m-Y', $raw);
        if ($parsed && $parsed->format('d-m-Y') === $raw) $date = $parsed->format('Y-m-d');
    }
    return [
        'date' => $date ?? date('Y-m-d'),
        'date_valid' => !$submitted || $date !== null,
        'shift' => dal_int($source['filter_shift'] ?? 0),
        'department' => dal_int($source['filter_dept'] ?? 0),
        'branch' => dal_int($source['filter_branchlocation'] ?? 0),
        'terminal' => dal_int($source['filter_orglocation'] ?? 0),
        'subbranch' => dal_int($source['filt_subbranch'] ?? 0),
    ];
}

function dnlo_validate(array $filters, array $options): array
{
    $errors = [];
    if (!$filters['date_valid']) $errors[] = 'Enter a valid Date.';
    foreach ([['shift','shifts','shift'],['department','departments','department'],['branch','locations','branch location'],['terminal','locations','terminal location'],['subbranch','subbranches','sub branch']] as [$key,$list,$label]) {
        if (!dal_valid_option($options[$list], (int)$filters[$key])) $errors[] = 'Invalid or unauthorized ' . $label . '.';
    }
    if (!$options['show_subbranch'] && $filters['subbranch']) $errors[] = 'Sub Branch Location is not enabled.';
    return array_values(array_unique($errors));
}

function dnlo_employee_conditions(array $f, array $scope, string &$types, array &$params): array
{
    $where = ['e.status IN (0,1)', 'EXISTS (SELECT 1 FROM jos_app_employeeinfo ei WHERE ei.employeeid=e.id)'];
    if ($f['department']) { $where[] = 'e.depat=?'; $types .= 'i'; $params[] = $f['department']; }
    if ($f['branch']) { $where[] = 'e.branch_location=?'; $types .= 'i'; $params[] = $f['branch']; }
    if ($f['subbranch']) { $where[] = 'e.subbranch=?'; $types .= 'i'; $params[] = $f['subbranch']; }
    if ($f['shift']) { $where[] = 'EXISTS (SELECT 1 FROM jos_app_employeeinfo eis WHERE eis.employeeid=e.id AND FIND_IN_SET(?,eis.shift_type))'; $types .= 'i'; $params[] = $f['shift']; }
    $terminalIds = [];
    if ($f['terminal']) $terminalIds = [$f['terminal']];
    elseif ($scope['restricted']) $terminalIds = $scope['terminals'];
    if ($scope['restricted'] && !$terminalIds) $where[] = '1=0';
    else {
        $terminalSql = '';
        if ($terminalIds) {
            $marks = dnlo_in($terminalIds, $types, $params);
            $terminalSql = " AND el.orglocation IN ($marks)";
        }
        $where[] = "EXISTS (SELECT 1 FROM jos_app_employee_locationlog el WHERE el.app_empid=e.id$terminalSql)";
    }
    return $where;
}

function dnlo_report(mysqli $con, array $f, array $scope): array
{
    $types = ''; $params = [];
    $where = dnlo_employee_conditions($f, $scope, $types, $params);
    $employees = dal_rows($con, 'SELECT e.id,e.name,e.orderby,e.orglocation,e.branch_location,e.subbranch,b.name branch_name,sb.subbranch subbranch_name FROM jos_app_employee e LEFT JOIN jos_app_orglocation b ON b.id=e.orglocation LEFT JOIN jos_app_subbranch sb ON sb.id=e.subbranch WHERE ' . implode(' AND ', $where) . ' ORDER BY e.orderby=0,e.orderby,e.id', $types, $params);
    if (!$employees) return [];
    $employeeById = []; foreach ($employees as $employee) $employeeById[(int)$employee['id']] = $employee;
    $ids = array_keys($employeeById);
    $logTypes = ''; $logParams = [];
    $marks = dnlo_in($ids, $logTypes, $logParams); $logTypes .= 's'; $logParams[] = $f['date'];
    $logWhere = ["a.empid IN ($marks)", 'DATE(a.entrydate)=?'];
    if ($f['shift']) { $logWhere[] = 'a.shiftid=?'; $logTypes .= 'i'; $logParams[] = $f['shift']; }
    $logs = dal_rows($con, 'SELECT a.id,a.empid,a.entrydate,a.in_time,a.out_time,a.shiftid,a.orglocation,o.name location_name,s.in_time shift_in,s.out_time shift_out FROM jos_app_attendance_log a LEFT JOIN jos_app_orglocation o ON o.id=a.orglocation LEFT JOIN jos_app_empshift s ON s.id=a.shiftid WHERE ' . implode(' AND ', $logWhere) . ' ORDER BY a.empid,a.id', $logTypes, $logParams);
    $logsByEmployee = []; foreach ($logs as $log) $logsByEmployee[(int)$log['empid']][] = $log;
    $candidateIds = array_keys($logsByEmployee);
    if (dal_table_exists($con, 'jos_app_attendance_log_temp')) {
        $tempTypes = ''; $tempParams = [];
        $tempMarks = dnlo_in($ids, $tempTypes, $tempParams); $tempTypes .= 's'; $tempParams[] = $f['date'];
        $temp = dal_rows($con, "SELECT DISTINCT empid FROM jos_app_attendance_log_temp WHERE empid IN ($tempMarks) AND DATE(`date`)=?", $tempTypes, $tempParams);
        foreach ($temp as $row) $candidateIds[] = (int)$row['empid'];
    }
    $candidateIds = array_values(array_unique($candidateIds));
    if (!$candidateIds) return [];
    $monthStart = substr($f['date'], 0, 8) . '01';
    $countTypes = ''; $countParams = [];
    $countMarks = dnlo_in($candidateIds, $countTypes, $countParams); $countTypes .= 'ss'; array_push($countParams, $monthStart, $f['date']);
    $missing = dal_rows($con, "SELECT empid,DATE(entrydate) missing_date FROM jos_app_attendance_log WHERE empid IN ($countMarks) AND DATE(entrydate) BETWEEN ? AND ? AND COALESCE(out_time,'')='' ORDER BY empid,entrydate,id", $countTypes, $countParams);
    $missingByEmployee = []; foreach ($missing as $row) $missingByEmployee[(int)$row['empid']][] = $row['missing_date'];
    $rows = [];
    foreach ($candidateIds as $id) {
        $employeeLogs = $logsByEmployee[$id] ?? [];
        $last = $employeeLogs ? $employeeLogs[count($employeeLogs)-1] : null;
        if ($last && trim((string)$last['out_time']) !== '') continue;
        if (!isset($employeeById[$id])) continue;
        $rows[] = ['employee'=>$employeeById[$id], 'logs'=>$employeeLogs, 'missing_dates'=>$missingByEmployee[$id] ?? []];
    }
    return $rows;
}

function dnlo_render(array $rows): void { ?>
<div class="overflow-x-auto"><table class="min-w-[900px] w-full text-sm"><thead class="bg-slate-900 text-white"><tr><th class="border border-slate-700 px-3 py-3 text-center font-bold w-20">Sr No</th><th class="border border-slate-700 px-3 py-3 text-center font-bold">Name</th><th colspan="2" class="border border-slate-700 px-3 py-3 text-center font-bold">Log Details</th><th class="border border-slate-700 px-3 py-3 text-center font-bold">Not Logged Out</th></tr><tr class="bg-slate-800"><th></th><th></th><th class="border border-slate-700 px-3 py-2 text-center font-bold">Log In</th><th class="border border-slate-700 px-3 py-2 text-center font-bold">Log Out</th><th></th></tr></thead><tbody><?php foreach($rows as$i=>$row):$e=$row['employee'];?><tr class="align-top"><td class="border px-3 py-4 text-center font-semibold"><?=$i+1?></td><td class="border px-3 py-4 text-center"><b><?=h((string)$e['name'])?></b><?php if(!empty($e['branch_name'])):?><div class="mt-1 text-xs text-slate-500">[ <?=h((string)$e['branch_name'])?> ]</div><?php endif;?><?php if(!empty($e['subbranch_name'])):?><div class="text-xs text-slate-500">[ <?=h((string)$e['subbranch_name'])?> ]</div><?php endif;?><?php foreach($row['logs']as$j=>$log):?><div class="mt-1 text-xs font-semibold"><?=($j+1)?>) <?=h((string)$log['shift_in'])?> - <?=h((string)$log['shift_out'])?></div><?php endforeach;?></td><td class="border px-3 py-4 text-center"><?php foreach($row['logs']as$j=>$log):?><div><b><?=h((string)($log['location_name']?:'Staff App'))?></b><br><?=trim((string)$log['in_time'])!==''?($j+1).') '.h((string)$log['in_time']):''?></div><?php endforeach;?></td><td class="border px-3 py-4 text-center"><?php foreach($row['logs']as$j=>$log):?><div><?=trim((string)$log['out_time'])!==''?($j+1).') '.h((string)$log['out_time']):''?></div><?php endforeach;?></td><td class="border px-3 py-4 text-center"><b>Not Logged Out<br><?=count($row['missing_dates'])?></b><?php if($row['missing_dates']):?><div class="mt-2 text-sm"><?php foreach($row['missing_dates']as$d):?><?=h(date('d',strtotime((string)$d)))?> / <?php endforeach;?></div><?php endif;?></td></tr><?php endforeach;if(!$rows):?><tr><td colspan="5" class="px-6 py-12 text-center font-semibold text-slate-400">No not-logged-out records found for the selected filters.</td></tr><?php endif;?></tbody></table></div>
<?php }
