<?php
declare(strict_types=1);
ini_set('display_errors', '0');

require_once __DIR__ . '/../includes/console_shell.php';
require_login();

$pageLink = 'attendance/attendance-configuration.php';
$errors = [];
$flash = $_SESSION['flash_attendance_configuration'] ?? null;
unset($_SESSION['flash_attendance_configuration']);

function ac_stmt(mysqli $con, string $sql): mysqli_stmt
{
    $stmt = $con->prepare($sql);
    if (!$stmt) throw new RuntimeException('Unable to prepare attendance configuration query.');
    return $stmt;
}

function ac_options(mysqli $con, string $sql): array
{
    $rows = [];
    $result = $con->query($sql);
    if ($result) {
        while ($row = $result->fetch_assoc()) $rows[] = $row;
        $result->free();
    }
    return $rows;
}

function ac_ids($value): array
{
    $ids = array_map('intval', (array)$value);
    $ids = array_values(array_unique(array_filter($ids, static fn($id) => $id > 0)));
    sort($ids, SORT_NUMERIC);
    return $ids;
}

function ac_csv_ids($value, array $validIds): string
{
    $valid = array_fill_keys($validIds, true);
    $ids = [];
    foreach (ac_ids($value) as $id) {
        if (isset($valid[$id])) $ids[] = $id;
    }
    return implode(',', $ids);
}

function ac_valid_id(mysqli $con, string $table, int $id, string $extra = ''): bool
{
    $allowed = ['jos_app_payrolllocation', 'jos_app_mmonth', 'jos_app_year'];
    if ($id <= 0 || !in_array($table, $allowed, true)) return false;
    $stmt = ac_stmt($con, 'SELECT id FROM `' . $table . '` WHERE id=? ' . $extra . ' LIMIT 1');
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $valid = (bool)$stmt->get_result()->fetch_assoc();
    $stmt->close();
    return $valid;
}

function ac_function_options(): array
{
    return [
        'monthly_days' => 'Monthly Days',
        'monthly_shifthrs' => 'Monthly Shift Hrs',
        'presentday_count' => 'Present Day Count',
        'monthly_presenthrs' => 'Monthly Present Hrs',
        'weeklyoff_count' => 'Weekly Off Count',
        'holiday_count' => 'Holiday Count',
        'holiday_hrs' => 'Holiday Hrs',
        'holiday_present' => 'Holiday Present',
        'holiday_phothrs' => 'Holiday PH OT Hrs',
        'undeclare_phcount' => 'Undeclared PH Count',
        'optional_phcount' => 'Optional PH Count',
        'optionalph_present' => 'Optional PH Present',
        'unpaid_offcount' => 'Unpaid Off Count',
        'absent_count' => 'Absent Count',
        'shortday_count' => 'Short Day Count',
        'shortdayhrs' => 'Short Day Hrs',
        'halfday_count' => 'Half Day Count',
        'halfleave_count' => 'Half Leave Count',
        'fullleave_count' => 'Full Leave Count',
        'esileave_count' => 'ESI Leave Count',
        'early_count' => 'Early Count',
        'earlyloss_hrs' => 'Early Loss Hrs',
        'losthrs_count' => 'Lost Hrs Count',
        'losthrs_hrs' => 'Lost Hrs',
        'lmhrs_count' => 'Late Mark Hrs Count',
        'lmhrs_hrs' => 'Late Mark Hrs',
        'lmhrs_present' => 'Late Mark Present',
        'wot_hrs' => 'WOT Hrs',
        'wot_count' => 'WOT Count',
        'ot_hrs' => 'OT Hrs',
        'minimum_othrs' => 'Minimum OT Hrs',
        'doubleot_hrs' => 'Double OT Hrs',
        'singleot_hrs' => 'Single OT Hrs',
        'cwot_hrs' => 'CWOT Hrs',
        'cwot_count' => 'CWOT Count',
        'ot_count' => 'OT Count',
        'maxlmhrs_count' => 'Max Late Mark Count',
        'maxlmhrs_hrs' => 'Max Late Mark Hrs',
        'ad_lmhrs' => 'Additional Late Mark Hrs',
    ];
}

function ac_calc_labels(): array
{
    return ['' => 'None', '1' => 'Days', '2' => 'Rupees', '4' => 'Count', '3' => 'Hrs'];
}

function ac_publish_labels(): array
{
    return [0 => 'Un-Publish', 1 => 'Publish', 2 => 'Only Calculate'];
}

function ac_round_labels(): array
{
    return [0 => 'No', 1 => 'Up', 2 => 'Down', 3 => 'Nearest', 4 => 'Mod', 5 => 'Half OR Full Day', 6 => '2 Decimal'];
}

function ac_log_labels(): array
{
    return [0 => 'First log to Last log', 1 => 'In log - Out log pair'];
}

function ac_config_exists(mysqli $con, int $orgid, int $month, int $year): bool
{
    $stmt = ac_stmt($con, 'SELECT id FROM jos_app_configuration_grid WHERE orgid=? AND month=? AND year=? LIMIT 1');
    $stmt->bind_param('iii', $orgid, $month, $year);
    $stmt->execute();
    $exists = (bool)$stmt->get_result()->fetch_assoc();
    $stmt->close();
    return $exists;
}

function ac_existing_rows(mysqli $con, int $orgid, int $month, int $year): array
{
    $rows = [];
    $stmt = ac_stmt($con, 'SELECT * FROM jos_app_configuration_grid WHERE orgid=? AND month=? AND year=? ORDER BY `ordering`,id');
    $stmt->bind_param('iii', $orgid, $month, $year);
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) $rows[(int)$row['component']] = $row;
    $stmt->close();
    return $rows;
}

function ac_write_history(mysqli $con, int $id): void
{
    $modifiedBy = (int)(current_user()['id'] ?? 0);
    $stmt = ac_stmt($con, 'INSERT INTO jos_app_configuration_grid_editlog (attendid,month,year,orgid,logcalculation,function_name,calculation,`ordering`,publish,component,`value`,cutting,calculation_on,calculation_mins,shortname,roundup,modify_by,`date`) SELECT id,month,year,orgid,logcalculation,function_name,calculation,`ordering`,publish,component,`value`,cutting,calculation_on,calculation_mins,shortname,roundup,?,NOW() FROM jos_app_configuration_grid WHERE id=?');
    $stmt->bind_param('ii', $modifiedBy, $id);
    if (!$stmt->execute()) throw new RuntimeException('Unable to write attendance configuration history.');
    $stmt->close();
}

function ac_insert_row(mysqli $con, array $row): int
{
    $stmt = ac_stmt($con, 'INSERT INTO jos_app_configuration_grid (orgid,month,year,logcalculation,component,shortname,calculation,calculation_on,calculation_mins,`value`,cutting,`ordering`,publish,function_name,roundup) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
    $stmt->bind_param(
        'iiiiissssssiisi',
        $row['orgid'],
        $row['month'],
        $row['year'],
        $row['logcalculation'],
        $row['component'],
        $row['shortname'],
        $row['calculation'],
        $row['calculation_on'],
        $row['calculation_mins'],
        $row['value'],
        $row['cutting'],
        $row['ordering'],
        $row['publish'],
        $row['function_name'],
        $row['roundup']
    );
    if (!$stmt->execute()) throw new RuntimeException('Unable to insert attendance configuration row.');
    $id = (int)$con->insert_id;
    $stmt->close();
    ac_write_history($con, $id);
    return $id;
}

function ac_clean_decimal($value, string $label, array &$errors, float $min = 0.0, float $max = 999999.0): string
{
    $raw = trim((string)$value);
    if ($raw === '') return '0';
    if (!preg_match('/^\d+(\.\d{1,4})?$/', $raw)) {
        $errors[] = $label . ' must be a valid non-negative number.';
        return '0';
    }
    $number = (float)$raw;
    if ($number < $min || $number > $max) $errors[] = $label . ' is outside the allowed range.';
    return rtrim(rtrim(number_format($number, 4, '.', ''), '0'), '.');
}

$acl = require_acl('can_view', $pageLink);

$payrollLocations = ac_options($con, 'SELECT id,name FROM jos_app_payrolllocation WHERE status=1 ORDER BY name,id');
$months = ac_options($con, 'SELECT id,month AS name FROM jos_app_mmonth ORDER BY id');
$years = ac_options($con, 'SELECT id,year AS name,assessment FROM jos_app_year ORDER BY id DESC');
$components = ac_options($con, 'SELECT id,componentname,functionname FROM jos_app_salarycomponentmaster WHERE attend_config=1 ORDER BY `orderby`,id');

$payrollMap = $monthMap = $yearMap = $componentMap = [];
foreach ($payrollLocations as $row) $payrollMap[(int)$row['id']] = (string)$row['name'];
foreach ($months as $row) $monthMap[(int)$row['id']] = (string)$row['name'];
foreach ($years as $row) $yearMap[(int)$row['id']] = (string)$row['name'];
foreach ($components as $row) $componentMap[(int)$row['id']] = (string)$row['componentname'];
$componentIds = array_keys($componentMap);

$mode = (string)($_GET['mode'] ?? '');
$orgid = max(0, (int)($_GET['orgid'] ?? 0));
$month = max(0, (int)($_GET['month'] ?? 0));
$year = max(0, (int)($_GET['year'] ?? 0));
$isForm = in_array($mode, ['add', 'edit', 'view', 'copy'], true);
$isView = $mode === 'view';
$existingRows = [];

if (in_array($mode, ['edit', 'view'], true)) {
    if (!$orgid || !$month || !$year || !ac_config_exists($con, $orgid, $month, $year)) {
        $_SESSION['flash_attendance_configuration'] = 'Attendance configuration was not found.';
        redirect('/attendance/attendance-configuration.php');
    }
    $existingRows = ac_existing_rows($con, $orgid, $month, $year);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = (string)($_POST['action'] ?? '');
    if (!verify_csrf($_POST['_csrf'] ?? null)) {
        $errors[] = 'Security token expired. Please refresh and try again.';
    } elseif ($action === 'save') {
        $orgid = max(0, (int)($_POST['orgid'] ?? 0));
        $month = max(0, (int)($_POST['month'] ?? 0));
        $year = max(0, (int)($_POST['year'] ?? 0));
        $logcalculation = (int)($_POST['logcalculation'] ?? -1);
        $exists = $orgid && $month && $year ? ac_config_exists($con, $orgid, $month, $year) : false;
        if ($exists && empty($acl['can_edit'])) $errors[] = 'You do not have permission to edit attendance configurations.';
        if (!$exists && empty($acl['can_add'])) $errors[] = 'You do not have permission to add attendance configurations.';
        if (!ac_valid_id($con, 'jos_app_payrolllocation', $orgid, 'AND status=1')) $errors[] = 'Select a valid payroll location.';
        if (!ac_valid_id($con, 'jos_app_mmonth', $month)) $errors[] = 'Select a valid month.';
        if (!ac_valid_id($con, 'jos_app_year', $year)) $errors[] = 'Select a valid year.';
        if (!in_array($logcalculation, [0, 1], true)) $errors[] = 'Select a valid working calculation.';

        $calcAllowed = array_keys(ac_calc_labels());
        $publishAllowed = array_keys(ac_publish_labels());
        $roundAllowed = array_keys(ac_round_labels());
        $rowsToSave = [];
        foreach ($components as $index => $component) {
            $componentId = (int)$component['id'];
            $label = (string)$component['componentname'];
            $shortname = trim((string)(($_POST['shortname'][$componentId] ?? '') ?: ($component['functionname'] ?? '')));
            $shortname = mb_substr($shortname, 0, 100);
            $calculation = (string)($_POST['calculation'][$componentId] ?? '');
            $calculationOn = ac_csv_ids($_POST['calculation_on'][$componentId] ?? [], $componentIds);
            $calculationMins = ac_csv_ids($_POST['calculation_mins'][$componentId] ?? [], $componentIds);
            $value = ac_clean_decimal($_POST['value'][$componentId] ?? '0', $label . ' value', $errors);
            $cutting = ac_clean_decimal($_POST['cutting'][$componentId] ?? '0', $label . ' cutting', $errors);
            $ordering = (int)($_POST['ordering'][$componentId] ?? ($index + 1));
            $publish = (int)($_POST['publish'][$componentId] ?? 0);
            $roundup = (int)($_POST['roundup'][$componentId] ?? 0);
            $functions = [];
            foreach ((array)($_POST['function_name'][$componentId] ?? []) as $functionName) {
                $functionName = trim((string)$functionName);
                if ($functionName === '') continue;
                if (!preg_match('/^[A-Za-z0-9_]+$/', $functionName)) {
                    $errors[] = $label . ' has an invalid function selection.';
                    continue;
                }
                $functions[] = $functionName;
            }
            $functions = array_values(array_unique($functions));
            if (!in_array($calculation, $calcAllowed, true)) $errors[] = $label . ' has an invalid calculation type.';
            if (!in_array($publish, $publishAllowed, true)) $errors[] = $label . ' has an invalid publish status.';
            if (!in_array($roundup, $roundAllowed, true)) $errors[] = $label . ' has an invalid round option.';
            if ($ordering < 0 || $ordering > 10000) $errors[] = $label . ' ordering must be between 0 and 10000.';
            if ($functions && ($calculationOn !== '' || $calculationMins !== '')) {
                $errors[] = $label . ' can use either Function Name or Calculation Add/Minus, not both.';
            }
            $rowsToSave[] = [
                'orgid' => $orgid,
                'month' => $month,
                'year' => $year,
                'logcalculation' => $logcalculation,
                'component' => $componentId,
                'shortname' => $shortname,
                'calculation' => $calculation,
                'calculation_on' => $calculationOn,
                'calculation_mins' => $calculationMins,
                'value' => $value,
                'cutting' => $cutting,
                'ordering' => $ordering,
                'publish' => $publish,
                'function_name' => implode(',', $functions),
                'roundup' => $roundup,
            ];
        }

        if (!$errors) {
            $con->begin_transaction();
            try {
                $stmt = ac_stmt($con, 'DELETE FROM jos_app_configuration_grid WHERE orgid=? AND month=? AND year=?');
                $stmt->bind_param('iii', $orgid, $month, $year);
                $stmt->execute();
                $stmt->close();
                foreach ($rowsToSave as $row) ac_insert_row($con, $row);
                $con->commit();
                audit_log($exists ? 'attendance_configuration.update' : 'attendance_configuration.create', 'jos_app_configuration_grid', $orgid . ':' . $month . ':' . $year, $payrollMap[$orgid] ?? '');
                $_SESSION['flash_attendance_configuration'] = $exists ? 'Attendance configuration updated successfully.' : 'Attendance configuration added successfully.';
                redirect('/attendance/attendance-configuration.php');
            } catch (Throwable $e) {
                $con->rollback();
                $errors[] = 'Unable to save the attendance configuration. No changes were committed.';
            }
        }
        $isForm = true;
        $mode = 'edit';
        $existingRows = [];
        foreach ($rowsToSave ?? [] as $row) $existingRows[(int)$row['component']] = $row;
    } elseif ($action === 'delete') {
        if (empty($acl['can_delete'])) $errors[] = 'You do not have permission to delete attendance configurations.';
        $orgid = max(0, (int)($_POST['orgid'] ?? 0));
        $month = max(0, (int)($_POST['month'] ?? 0));
        $year = max(0, (int)($_POST['year'] ?? 0));
        if (!$orgid || !$month || !$year || !ac_config_exists($con, $orgid, $month, $year)) $errors[] = 'Attendance configuration was not found.';
        if (!$errors) {
            $stmt = ac_stmt($con, 'DELETE FROM jos_app_configuration_grid WHERE orgid=? AND month=? AND year=?');
            $stmt->bind_param('iii', $orgid, $month, $year);
            if ($stmt->execute()) {
                audit_log('attendance_configuration.delete', 'jos_app_configuration_grid', $orgid . ':' . $month . ':' . $year, json_encode(['orgid' => $orgid, 'month' => $month, 'year' => $year]));
                $_SESSION['flash_attendance_configuration'] = 'Attendance configuration deleted successfully.';
                redirect('/attendance/attendance-configuration.php');
            }
            $stmt->close();
            $errors[] = 'Unable to delete the attendance configuration.';
        }
    } elseif ($action === 'copy') {
        $fromOrg = max(0, (int)($_POST['from_orgid'] ?? 0));
        $fromMonth = max(0, (int)($_POST['from_month'] ?? 0));
        $fromYear = max(0, (int)($_POST['from_year'] ?? 0));
        $toOrg = max(0, (int)($_POST['to_orgid'] ?? 0));
        $toMonth = max(0, (int)($_POST['to_month'] ?? 0));
        $toYear = max(0, (int)($_POST['to_year'] ?? 0));
        $overwrite = (int)($_POST['overwrite'] ?? 0) === 1;
        if (!ac_config_exists($con, $fromOrg, $fromMonth, $fromYear)) $errors[] = 'Source configuration was not found.';
        if (!ac_valid_id($con, 'jos_app_payrolllocation', $toOrg, 'AND status=1')) $errors[] = 'Select a valid target payroll location.';
        if (!ac_valid_id($con, 'jos_app_mmonth', $toMonth)) $errors[] = 'Select a valid target month.';
        if (!ac_valid_id($con, 'jos_app_year', $toYear)) $errors[] = 'Select a valid target year.';
        $targetExists = $toOrg && $toMonth && $toYear ? ac_config_exists($con, $toOrg, $toMonth, $toYear) : false;
        if ($targetExists && !$overwrite) $errors[] = 'Target configuration already exists. Select overwrite to replace it.';
        if ($targetExists && empty($acl['can_edit'])) $errors[] = 'You do not have permission to overwrite attendance configurations.';
        if (!$targetExists && empty($acl['can_add'])) $errors[] = 'You do not have permission to copy attendance configurations.';

        if (!$errors) {
            $sourceRows = ac_existing_rows($con, $fromOrg, $fromMonth, $fromYear);
            if (!$sourceRows) $errors[] = 'Source configuration has no rows to copy.';
        }
        if (!$errors) {
            $con->begin_transaction();
            try {
                if ($targetExists) {
                    $stmt = ac_stmt($con, 'DELETE FROM jos_app_configuration_grid WHERE orgid=? AND month=? AND year=?');
                    $stmt->bind_param('iii', $toOrg, $toMonth, $toYear);
                    $stmt->execute();
                    $stmt->close();
                }
                foreach ($sourceRows as $source) {
                    ac_insert_row($con, [
                        'orgid' => $toOrg,
                        'month' => $toMonth,
                        'year' => $toYear,
                        'logcalculation' => (int)$source['logcalculation'],
                        'component' => (int)$source['component'],
                        'shortname' => (string)$source['shortname'],
                        'calculation' => (string)$source['calculation'],
                        'calculation_on' => (string)$source['calculation_on'],
                        'calculation_mins' => (string)$source['calculation_mins'],
                        'value' => (string)$source['value'],
                        'cutting' => (string)$source['cutting'],
                        'ordering' => (int)$source['ordering'],
                        'publish' => (int)$source['publish'],
                        'function_name' => (string)$source['function_name'],
                        'roundup' => (int)$source['roundup'],
                    ]);
                }
                $con->commit();
                audit_log('attendance_configuration.copy', 'jos_app_configuration_grid', $toOrg . ':' . $toMonth . ':' . $toYear, $fromOrg . ':' . $fromMonth . ':' . $fromYear);
                $_SESSION['flash_attendance_configuration'] = 'Attendance configuration copied successfully.';
                redirect('/attendance/attendance-configuration.php');
            } catch (Throwable $e) {
                $con->rollback();
                $errors[] = 'Unable to copy the attendance configuration. No changes were committed.';
            }
        }
        $isForm = true;
        $mode = 'copy';
    }
}

$filterOrg = max(0, (int)($_GET['filter_org'] ?? 0));
$filterMonth = max(0, (int)($_GET['filter_month'] ?? 0));
$filterYear = max(0, (int)($_GET['filter_year'] ?? 0));
$filterLog = (string)($_GET['filter_log'] ?? '');
$search = trim((string)($_GET['q'] ?? ''));
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = 20;
$totalRows = 0;
$rows = [];
$pages = 1;

if (!$isForm) {
    $where = ['1=1'];
    $types = '';
    $params = [];
    if ($filterOrg > 0) { $where[] = 'g.orgid=?'; $types .= 'i'; $params[] = $filterOrg; }
    if ($filterMonth > 0) { $where[] = 'g.month=?'; $types .= 'i'; $params[] = $filterMonth; }
    if ($filterYear > 0) { $where[] = 'g.year=?'; $types .= 'i'; $params[] = $filterYear; }
    if ($filterLog !== '' && in_array((int)$filterLog, [0, 1], true)) { $where[] = 'g.logcalculation=?'; $types .= 'i'; $params[] = (int)$filterLog; }
    if ($search !== '') { $where[] = '(p.name LIKE ? OR m.month LIKE ? OR y.year LIKE ?)'; $types .= 'sss'; $like = '%' . $search . '%'; $params[] = $like; $params[] = $like; $params[] = $like; }
    $whereSql = implode(' AND ', $where);

    $countSql = 'SELECT COUNT(*) AS total FROM (SELECT g.orgid,g.month,g.year FROM jos_app_configuration_grid g LEFT JOIN jos_app_payrolllocation p ON p.id=g.orgid LEFT JOIN jos_app_mmonth m ON m.id=g.month LEFT JOIN jos_app_year y ON y.id=g.year WHERE ' . $whereSql . ' GROUP BY g.orgid,g.month,g.year) grouped';
    $stmt = ac_stmt($con, $countSql);
    if ($types !== '') $stmt->bind_param($types, ...$params);
    $stmt->execute();
    $totalRows = (int)($stmt->get_result()->fetch_assoc()['total'] ?? 0);
    $stmt->close();
    $pages = max(1, (int)ceil($totalRows / $perPage));
    $page = min($page, $pages);
    $offset = ($page - 1) * $perPage;

    $listSql = 'SELECT g.orgid,g.month,g.year,MAX(g.logcalculation) AS logcalculation,COUNT(*) AS row_count,SUM(g.publish=1) AS published_count,SUM(g.publish=2) AS calculate_count,p.name AS payroll_name,m.month AS month_name,y.year AS year_name FROM jos_app_configuration_grid g LEFT JOIN jos_app_payrolllocation p ON p.id=g.orgid LEFT JOIN jos_app_mmonth m ON m.id=g.month LEFT JOIN jos_app_year y ON y.id=g.year WHERE ' . $whereSql . ' GROUP BY g.orgid,g.month,g.year,p.name,m.month,y.year ORDER BY y.year DESC,g.year DESC,g.month DESC,p.name ASC LIMIT ? OFFSET ?';
    $stmt = ac_stmt($con, $listSql);
    $listTypes = $types . 'ii';
    $listParams = $params;
    $listParams[] = $perPage;
    $listParams[] = $offset;
    $stmt->bind_param($listTypes, ...$listParams);
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) $rows[] = $row;
    $stmt->close();
}

$input = 'mt-1 w-full rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm text-slate-800 outline-none focus:border-brand-500 focus:ring-2 focus:ring-brand-100';
$selectSmall = 'rounded-xl border border-slate-200 px-3 py-2.5 text-sm';
$functionOptions = ac_function_options();
foreach ($existingRows as $existingRow) {
    foreach (array_filter(array_map('trim', explode(',', (string)($existingRow['function_name'] ?? '')))) as $functionName) {
        if (preg_match('/^[A-Za-z0-9_]+$/', $functionName) && !isset($functionOptions[$functionName])) {
            $functionOptions[$functionName] = $functionName;
        }
    }
}
$calcLabels = ac_calc_labels();
$publishLabels = ac_publish_labels();
$roundLabels = ac_round_labels();
$logLabels = ac_log_labels();

console_header('Attendance Configuration', $pageLink);
?>
<div class="mb-4 flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
  <div><div class="mb-2 flex items-center gap-2 text-xs font-semibold text-slate-500"><a href="/dashboard.php">Dashboard</a><i class="fa-solid fa-chevron-right text-[9px]"></i><span>D. Masters</span><i class="fa-solid fa-chevron-right text-[9px]"></i><span>Attendance Settings</span><i class="fa-solid fa-chevron-right text-[9px]"></i><span class="text-brand-600">Attendance Configuration</span></div><h1 class="text-2xl font-bold text-slate-900">Attendance Configuration</h1><p class="mt-1 text-sm text-slate-500">Configure payroll attendance component calculations by location and period.</p></div>
</div>

<?php if ($flash): ?><div class="mb-5 rounded-xl border border-emerald-100 bg-emerald-50 px-5 py-4 text-sm font-semibold text-emerald-700"><i class="fa-solid fa-circle-check mr-2"></i><?= h($flash) ?></div><?php endif; ?>
<?php if ($errors): ?><div class="mb-5 rounded-xl border border-red-100 bg-red-50 px-5 py-4 text-sm font-semibold text-red-700"><div class="font-bold">Please fix the following</div><ul class="mt-2 list-inside list-disc"><?php foreach ($errors as $error): ?><li><?= h($error) ?></li><?php endforeach; ?></ul></div><?php endif; ?>

<?php if ($isForm && $mode === 'copy'): ?>
<form method="post" class="rounded-2xl border border-slate-100 bg-white p-5 shadow-sm">
  <input type="hidden" name="_csrf" value="<?= h(csrf_token()) ?>"><input type="hidden" name="action" value="copy">
  <div class="mb-5 flex flex-wrap items-center justify-between gap-3"><div class="flex items-center gap-3"><span class="flex h-10 w-10 items-center justify-center rounded-xl bg-brand-50 text-brand-600"><i class="fa-solid fa-copy"></i></span><div><h2 class="font-bold text-slate-800">Copy Attendance Configuration</h2><p class="text-xs text-slate-400">Copy an existing payroll-location period into another period.</p></div></div><a href="/attendance/attendance-configuration.php" class="rounded-lg border border-slate-200 px-4 py-2 text-sm font-bold text-slate-600 hover:bg-slate-50"><i class="fa-solid fa-arrow-left mr-2"></i>Back to List</a></div>
  <div class="grid gap-5 lg:grid-cols-2">
    <section class="rounded-xl border border-slate-100 p-4"><h3 class="mb-3 text-sm font-bold text-slate-700">Source</h3><div class="grid gap-3 md:grid-cols-3"><label class="text-sm font-semibold text-slate-700">Payroll Location<select name="from_orgid" required class="<?= $input ?>"><option value="">Select</option><?php foreach($payrollLocations as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $orgid===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?></option><?php endforeach; ?></select></label><label class="text-sm font-semibold text-slate-700">Month<select name="from_month" required class="<?= $input ?>"><option value="">Select</option><?php foreach($months as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $month===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?></option><?php endforeach; ?></select></label><label class="text-sm font-semibold text-slate-700">Year<select name="from_year" required class="<?= $input ?>"><option value="">Select</option><?php foreach($years as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $year===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?></option><?php endforeach; ?></select></label></div></section>
    <section class="rounded-xl border border-slate-100 p-4"><h3 class="mb-3 text-sm font-bold text-slate-700">Target</h3><div class="grid gap-3 md:grid-cols-3"><label class="text-sm font-semibold text-slate-700">Payroll Location<select name="to_orgid" required class="<?= $input ?>"><option value="">Select</option><?php foreach($payrollLocations as $option): ?><option value="<?= (int)$option['id'] ?>"><?= h($option['name']) ?></option><?php endforeach; ?></select></label><label class="text-sm font-semibold text-slate-700">Month<select name="to_month" required class="<?= $input ?>"><option value="">Select</option><?php foreach($months as $option): ?><option value="<?= (int)$option['id'] ?>"><?= h($option['name']) ?></option><?php endforeach; ?></select></label><label class="text-sm font-semibold text-slate-700">Year<select name="to_year" required class="<?= $input ?>"><option value="">Select</option><?php foreach($years as $option): ?><option value="<?= (int)$option['id'] ?>"><?= h($option['name']) ?></option><?php endforeach; ?></select></label></div><label class="mt-4 flex items-center gap-2 text-sm font-semibold text-slate-600"><input type="checkbox" name="overwrite" value="1" class="rounded border-slate-300 text-brand-600">Overwrite target if it already exists</label></section>
  </div>
  <div class="mt-5 flex justify-end gap-2"><a href="/attendance/attendance-configuration.php" class="rounded-lg border border-slate-200 px-5 py-2.5 text-sm font-bold text-slate-600">Cancel</a><button class="rounded-lg bg-brand-600 px-5 py-2.5 text-sm font-bold text-white hover:bg-brand-700"><i class="fa-solid fa-copy mr-2"></i>Copy Configuration</button></div>
</form>
<?php elseif ($isForm): ?>
<?php
$defaultLog = 0;
if ($existingRows) {
    $firstExisting = reset($existingRows);
    $defaultLog = (int)($firstExisting['logcalculation'] ?? 0);
}
?>
<form method="post" id="attendance-config-form" class="space-y-4">
  <input type="hidden" name="_csrf" value="<?= h(csrf_token()) ?>"><input type="hidden" name="action" value="save">
  <section class="rounded-2xl border border-slate-100 bg-white p-4 shadow-sm">
    <div class="mb-4 flex flex-wrap items-center justify-between gap-3"><div class="flex items-center gap-3"><span class="flex h-9 w-9 items-center justify-center rounded-lg bg-brand-50 text-brand-600"><i class="fa-solid fa-sliders"></i></span><div><h2 class="font-bold text-slate-800"><?= $isView ? 'View Configuration' : ($existingRows ? 'Edit Configuration' : 'New Configuration') ?></h2><p class="text-xs text-slate-400">Rows follow the legacy payroll component configuration grid.</p></div></div><a href="/attendance/attendance-configuration.php" class="rounded-lg border border-slate-200 bg-white px-4 py-2 text-sm font-bold text-slate-600 hover:bg-slate-50"><i class="fa-solid fa-arrow-left mr-2"></i>Back to List</a></div>
    <div class="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
      <label class="text-sm font-semibold text-slate-700">Payroll Location *<select name="orgid" required <?= $isView?'disabled':'' ?> class="<?= $input ?>"><option value="">Select Payroll Location</option><?php foreach($payrollLocations as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $orgid===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?></option><?php endforeach; ?></select></label>
      <label class="text-sm font-semibold text-slate-700">Month *<select name="month" required <?= $isView?'disabled':'' ?> class="<?= $input ?>"><option value="">Select Month</option><?php foreach($months as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $month===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?></option><?php endforeach; ?></select></label>
      <label class="text-sm font-semibold text-slate-700">Year *<select name="year" required <?= $isView?'disabled':'' ?> class="<?= $input ?>"><option value="">Select Year</option><?php foreach($years as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $year===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?><?= $option['assessment']?' · '.h($option['assessment']):'' ?></option><?php endforeach; ?></select></label>
      <label class="text-sm font-semibold text-slate-700">Working Calculation *<select name="logcalculation" required <?= $isView?'disabled':'' ?> class="<?= $input ?>"><?php foreach($logLabels as $key=>$label): ?><option value="<?= (int)$key ?>" <?= $defaultLog===(int)$key?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></label>
    </div>
  </section>

  <section class="overflow-hidden rounded-2xl border border-slate-100 bg-white shadow-sm">
    <div class="border-b border-slate-100 px-5 py-4"><h2 class="font-bold text-slate-800">Component Rules</h2><p class="mt-1 text-xs font-medium text-slate-400">A row may use either function selection or add/minus calculation components.</p></div>
    <div class="overflow-x-auto"><table class="w-full min-w-[1800px] text-left text-xs"><thead class="bg-slate-50 text-[10px] uppercase tracking-wider text-slate-400"><tr><th class="px-3 py-3 w-12">Sr</th><th class="px-3 py-3 w-52">Component</th><th class="px-3 py-3 w-32">Short Name</th><th class="px-3 py-3 w-32">Calculation</th><th class="px-3 py-3 w-56">Function</th><th class="px-3 py-3 w-56">Add (+)</th><th class="px-3 py-3 w-56">Minus (-)</th><th class="px-3 py-3 w-28">Value</th><th class="px-3 py-3 w-28">Cutting</th><th class="px-3 py-3 w-24">Order</th><th class="px-3 py-3 w-36">Publish</th><th class="px-3 py-3 w-36">Round</th></tr></thead><tbody class="divide-y divide-slate-100">
      <?php if (!$components): ?><tr><td colspan="12" class="px-6 py-14 text-center font-semibold text-slate-400">No attendance components are marked for configuration.</td></tr><?php endif; ?>
      <?php foreach($components as $index=>$component): $cid=(int)$component['id']; $row=$existingRows[$cid]??[]; $selectedFunctions=array_filter(array_map('trim', explode(',', (string)($row['function_name']??'')))); $selectedAdd=ac_ids(explode(',', (string)($row['calculation_on']??''))); $selectedMinus=ac_ids(explode(',', (string)($row['calculation_mins']??''))); ?>
      <tr class="align-top hover:bg-slate-50/70">
        <td class="px-3 py-3 font-semibold text-slate-500"><?= $index + 1 ?></td>
        <td class="px-3 py-3"><div class="font-bold text-slate-800"><?= h($component['componentname']) ?></div><div class="text-[10px] text-slate-400">ID <?= $cid ?></div></td>
        <td class="px-3 py-3"><input name="shortname[<?= $cid ?>]" value="<?= h((string)($row['shortname'] ?? ($component['functionname'] ?? ''))) ?>" <?= $isView?'readonly':'' ?> class="w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"></td>
        <td class="px-3 py-3"><select name="calculation[<?= $cid ?>]" <?= $isView?'disabled':'' ?> class="w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"><?php foreach($calcLabels as $key=>$label): ?><option value="<?= h((string)$key) ?>" <?= (string)($row['calculation']??'')===(string)$key?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></td>
        <td class="px-3 py-3"><select name="function_name[<?= $cid ?>][]" multiple <?= $isView?'disabled':'' ?> class="h-24 w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"><?php foreach($functionOptions as $key=>$label): ?><option value="<?= h($key) ?>" <?= in_array($key,$selectedFunctions,true)?'selected':'' ?>><?= h($key) ?></option><?php endforeach; ?></select></td>
        <td class="px-3 py-3"><select name="calculation_on[<?= $cid ?>][]" multiple <?= $isView?'disabled':'' ?> class="h-24 w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"><?php foreach($components as $option): ?><option value="<?= (int)$option['id'] ?>" <?= in_array((int)$option['id'],$selectedAdd,true)?'selected':'' ?>><?= h($option['componentname']) ?></option><?php endforeach; ?></select></td>
        <td class="px-3 py-3"><select name="calculation_mins[<?= $cid ?>][]" multiple <?= $isView?'disabled':'' ?> class="h-24 w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"><?php foreach($components as $option): ?><option value="<?= (int)$option['id'] ?>" <?= in_array((int)$option['id'],$selectedMinus,true)?'selected':'' ?>><?= h($option['componentname']) ?></option><?php endforeach; ?></select></td>
        <td class="px-3 py-3"><input name="value[<?= $cid ?>]" value="<?= h((string)($row['value'] ?? '0')) ?>" <?= $isView?'readonly':'' ?> class="w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"></td>
        <td class="px-3 py-3"><input name="cutting[<?= $cid ?>]" value="<?= h((string)($row['cutting'] ?? '0')) ?>" <?= $isView?'readonly':'' ?> class="w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"></td>
        <td class="px-3 py-3"><input type="number" name="ordering[<?= $cid ?>]" value="<?= h((string)($row['ordering'] ?? ($index + 1))) ?>" <?= $isView?'readonly':'' ?> class="w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"></td>
        <td class="px-3 py-3"><select name="publish[<?= $cid ?>]" <?= $isView?'disabled':'' ?> class="w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"><?php foreach($publishLabels as $key=>$label): ?><option value="<?= (int)$key ?>" <?= (int)($row['publish']??0)===(int)$key?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></td>
        <td class="px-3 py-3"><select name="roundup[<?= $cid ?>]" <?= $isView?'disabled':'' ?> class="w-full rounded-lg border border-slate-200 px-2 py-2 text-xs"><?php foreach($roundLabels as $key=>$label): ?><option value="<?= (int)$key ?>" <?= (int)($row['roundup']??0)===(int)$key?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></td>
      </tr>
      <?php endforeach; ?>
    </tbody></table></div>
  </section>
  <?php if (!$isView): ?><div class="flex flex-wrap justify-end gap-2"><a href="/attendance/attendance-configuration.php" class="rounded-lg border border-slate-200 bg-white px-5 py-2.5 text-sm font-bold text-slate-600">Cancel</a><button class="rounded-lg bg-brand-600 px-5 py-2.5 text-sm font-bold text-white hover:bg-brand-700"><i class="fa-solid fa-floppy-disk mr-2"></i>Save Configuration</button></div><?php endif; ?>
</form>
<?php else: ?>
<section class="overflow-hidden rounded-2xl border border-slate-100 bg-white shadow-sm">
  <div class="flex flex-col gap-3 border-b border-slate-100 px-5 py-4 sm:flex-row sm:items-center sm:justify-between"><div><h2 class="font-bold text-slate-800">Attendance Configuration List</h2><p class="mt-1 text-xs font-medium text-slate-400">Configurations are grouped by payroll location, month and year.</p></div><div class="flex flex-wrap gap-2"><?php if(!empty($acl['can_add'])): ?><a href="?mode=copy" class="inline-flex items-center justify-center gap-2 rounded-lg border border-slate-200 px-4 py-2.5 text-sm font-bold text-slate-600 hover:bg-slate-50"><i class="fa-solid fa-copy"></i>Copy</a><a href="?mode=add" class="inline-flex items-center justify-center gap-2 rounded-lg bg-brand-600 px-4 py-2.5 text-sm font-bold text-white shadow-sm hover:bg-brand-700"><i class="fa-solid fa-plus"></i>Add</a><?php endif; ?></div></div>
  <form method="get" class="grid gap-3 border-b border-slate-100 p-5 md:grid-cols-2 xl:grid-cols-6"><input type="search" name="q" value="<?= h($search) ?>" placeholder="Search payroll, month, year" class="<?= $selectSmall ?>"><select name="filter_org" class="<?= $selectSmall ?>"><option value="0">All Payroll Locations</option><?php foreach($payrollLocations as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $filterOrg===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?></option><?php endforeach; ?></select><select name="filter_month" class="<?= $selectSmall ?>"><option value="0">All Months</option><?php foreach($months as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $filterMonth===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?></option><?php endforeach; ?></select><select name="filter_year" class="<?= $selectSmall ?>"><option value="0">All Years</option><?php foreach($years as $option): ?><option value="<?= (int)$option['id'] ?>" <?= $filterYear===(int)$option['id']?'selected':'' ?>><?= h($option['name']) ?></option><?php endforeach; ?></select><select name="filter_log" class="<?= $selectSmall ?>"><option value="">All Working Calculations</option><?php foreach($logLabels as $key=>$label): ?><option value="<?= (int)$key ?>" <?= $filterLog!=='' && (int)$filterLog===(int)$key?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select><div class="flex gap-2"><button class="flex-1 rounded-xl bg-slate-900 px-4 py-2.5 text-sm font-bold text-white"><i class="fa-solid fa-filter mr-2"></i>Filter</button><a href="/attendance/attendance-configuration.php" class="rounded-xl border border-slate-200 px-4 py-2.5 text-sm font-bold text-slate-600">Clear</a></div></form>
  <div class="overflow-x-auto"><table class="w-full min-w-[1100px] text-left text-sm"><thead class="bg-slate-50 text-[10px] uppercase tracking-wider text-slate-400"><tr><th class="px-5 py-4 w-20">Sr No</th><th class="px-5 py-4">Payroll Location</th><th class="px-5 py-4">Period</th><th class="px-5 py-4">Working Calculation</th><th class="px-5 py-4">Rows</th><th class="px-5 py-4">Status Mix</th><th class="px-5 py-4 text-right">Actions</th></tr></thead><tbody class="divide-y divide-slate-100">
    <?php if (!$rows): ?><tr><td colspan="7" class="px-6 py-14 text-center font-semibold text-slate-400">No attendance configurations found.</td></tr><?php endif; ?>
    <?php foreach($rows as $index=>$row): $params=['orgid'=>(int)$row['orgid'],'month'=>(int)$row['month'],'year'=>(int)$row['year']]; ?>
    <tr class="hover:bg-slate-50/70"><td class="px-5 py-4 font-semibold text-slate-500"><?= (($page-1)*$perPage)+$index+1 ?></td><td class="px-5 py-4"><div class="font-bold text-slate-800"><?= h($row['payroll_name'] ?: ($payrollMap[(int)$row['orgid']] ?? 'Unknown')) ?></div><div class="text-xs text-slate-400">Location #<?= (int)$row['orgid'] ?></div></td><td class="px-5 py-4"><div class="font-bold text-slate-800"><?= h($row['month_name'] ?: ($monthMap[(int)$row['month']] ?? 'Unknown')) ?> <?= h($row['year_name'] ?: ($yearMap[(int)$row['year']] ?? (string)$row['year'])) ?></div><div class="text-xs text-slate-400">Month <?= (int)$row['month'] ?>, Year <?= (int)$row['year'] ?></div></td><td class="px-5 py-4 font-semibold text-slate-700"><?= h($logLabels[(int)$row['logcalculation']] ?? 'Unknown') ?></td><td class="px-5 py-4"><span class="rounded-full bg-brand-50 px-3 py-1 text-xs font-bold text-brand-700"><?= (int)$row['row_count'] ?> rows</span></td><td class="px-5 py-4"><div class="flex flex-wrap gap-1"><span class="rounded-md bg-emerald-50 px-2 py-1 text-[10px] font-bold text-emerald-700"><?= (int)$row['published_count'] ?> publish</span><span class="rounded-md bg-amber-50 px-2 py-1 text-[10px] font-bold text-amber-700"><?= (int)$row['calculate_count'] ?> calculate</span></div></td><td class="px-5 py-4"><div class="flex justify-end gap-2"><a href="?<?= h(http_build_query(['mode'=>'view'] + $params)) ?>" class="rounded-lg border border-slate-200 px-3 py-2 text-slate-600 hover:bg-slate-50" title="View"><i class="fa-solid fa-eye"></i></a><?php if(!empty($acl['can_edit'])): ?><a href="?<?= h(http_build_query(['mode'=>'edit'] + $params)) ?>" class="rounded-lg border border-slate-200 px-3 py-2 text-slate-600 hover:bg-brand-50 hover:text-brand-600" title="Edit"><i class="fa-solid fa-pen"></i></a><?php endif; ?><?php if(!empty($acl['can_add'])): ?><a href="?<?= h(http_build_query(['mode'=>'copy'] + $params)) ?>" class="rounded-lg border border-slate-200 px-3 py-2 text-slate-600 hover:bg-slate-50" title="Copy"><i class="fa-solid fa-copy"></i></a><?php endif; ?><?php if(!empty($acl['can_delete'])): ?><form method="post" onsubmit="return confirm('Delete this attendance configuration?');"><input type="hidden" name="_csrf" value="<?= h(csrf_token()) ?>"><input type="hidden" name="action" value="delete"><input type="hidden" name="orgid" value="<?= (int)$row['orgid'] ?>"><input type="hidden" name="month" value="<?= (int)$row['month'] ?>"><input type="hidden" name="year" value="<?= (int)$row['year'] ?>"><button class="rounded-lg border border-red-100 px-3 py-2 text-red-500 hover:bg-red-50" title="Delete"><i class="fa-solid fa-trash"></i></button></form><?php endif; ?></div></td></tr>
    <?php endforeach; ?>
  </tbody></table></div>
  <?php if($totalRows>$perPage): ?><div class="flex items-center justify-between border-t border-slate-100 px-5 py-4 text-sm"><span class="font-medium text-slate-500"><?= $totalRows ?> configurations</span><div class="flex gap-2"><?php $base=['q'=>$search,'filter_org'=>$filterOrg,'filter_month'=>$filterMonth,'filter_year'=>$filterYear,'filter_log'=>$filterLog]; if($page>1): ?><a class="rounded-lg border border-slate-200 px-4 py-2 font-semibold" href="?<?= h(http_build_query($base + ['page'=>$page-1])) ?>">Previous</a><?php endif; ?><?php if($page<$pages): ?><a class="rounded-lg border border-slate-200 px-4 py-2 font-semibold" href="?<?= h(http_build_query($base + ['page'=>$page+1])) ?>">Next</a><?php endif; ?></div></div><?php endif; ?>
</section>
<?php endif; ?>
<script>
document.addEventListener('DOMContentLoaded', function () {
  var form = document.getElementById('attendance-config-form');
  if (!form) return;
  form.addEventListener('submit', function (event) {
    var rows = form.querySelectorAll('tbody tr');
    for (var i = 0; i < rows.length; i++) {
      var functions = rows[i].querySelector('select[name^="function_name"]');
      var add = rows[i].querySelector('select[name^="calculation_on"]');
      var minus = rows[i].querySelector('select[name^="calculation_mins"]');
      var hasFunction = functions && Array.from(functions.selectedOptions).length > 0;
      var hasFormula = (add && Array.from(add.selectedOptions).length > 0) || (minus && Array.from(minus.selectedOptions).length > 0);
      if (hasFunction && hasFormula) {
        event.preventDefault();
        alert('A component row can use either Function Name or Calculation Add/Minus, not both.');
        rows[i].scrollIntoView({behavior: 'smooth', block: 'center'});
        return;
      }
    }
  });
});
</script>
<?php console_footer(); ?>
