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

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

$pageLink = 'attendance/overtime-configuration.php';
$acl = require_acl('can_view', $pageLink);
$errors = [];
$flash = $_SESSION['flash_overtime_configuration'] ?? null;
unset($_SESSION['flash_overtime_configuration']);

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

function otc_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 otc_columns(mysqli $con, string $table): array
{
    static $cache = [];
    if (isset($cache[$table])) return $cache[$table];
    $safeTable = preg_replace('/[^A-Za-z0-9_]/', '', $table);
    $columns = [];
    $result = $con->query('SHOW COLUMNS FROM `' . $safeTable . '`');
    if ($result) {
        while ($row = $result->fetch_assoc()) $columns[] = (string)$row['Field'];
        $result->free();
    }
    return $cache[$table] = $columns;
}

function otc_has_column(mysqli $con, string $table, string $column): bool
{
    return in_array($column, otc_columns($con, $table), true);
}

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

function otc_exists(mysqli $con, int $id): bool
{
    $stmt = otc_stmt($con, 'SELECT id FROM jos_app_ot_config WHERE id=? LIMIT 1');
    $stmt->bind_param('i', $id);
    $stmt->execute();
    $exists = (bool)$stmt->get_result()->fetch_assoc();
    $stmt->close();
    return $exists;
}

function otc_hhmm_to_minutes(string $value, string $label, array &$errors, bool $required = false): int
{
    $value = trim($value);
    if ($value === '') {
        if ($required) $errors[] = $label . ' is required.';
        return 0;
    }
    if (!preg_match('/^\d{1,4}:[0-5]\d$/', $value)) {
        $errors[] = $label . ' must be in HH:MM format.';
        return 0;
    }
    [$hours, $minutes] = array_map('intval', explode(':', $value, 2));
    return ($hours * 60) + $minutes;
}

function otc_number($value, string $label, array &$errors, int $max = 999999, bool $required = false): string
{
    $raw = trim((string)$value);
    if ($raw === '') {
        if ($required) $errors[] = $label . ' is required.';
        return '';
    }
    if (!preg_match('/^\d+(\.\d{1,4})?$/', $raw)) {
        $errors[] = $label . ' must be a valid non-negative number.';
        return '';
    }
    if ((float)$raw > $max) $errors[] = $label . ' is outside the allowed range.';
    return $raw;
}

function otc_int_value($value, string $label, array &$errors, int $min = 0, int $max = 999999, bool $required = false): int
{
    $raw = trim((string)$value);
    if ($raw === '') {
        if ($required) $errors[] = $label . ' is required.';
        return 0;
    }
    if (!preg_match('/^\d+$/', $raw)) {
        $errors[] = $label . ' must be a whole number.';
        return 0;
    }
    $number = (int)$raw;
    if ($number < $min || $number > $max) $errors[] = $label . ' must be between ' . $min . ' and ' . $max . '.';
    return $number;
}

function otc_select_value($value, array $allowed, string $label, array &$errors): int
{
    $number = (int)$value;
    if (!in_array($number, $allowed, true)) $errors[] = 'Select a valid ' . $label . '.';
    return $number;
}

function otc_field_spec(): array
{
    return [
        'policyname' => 's',
        'minimumhrs' => 's',
        'minimummin' => 'i',
        'maxhrs' => 's',
        'maxmin' => 'i',
        'roundup_day' => 's',
        'roundup_monthly' => 's',
        'roundup_minutes' => 's',
        'grace' => 's',
        'apply_before' => 'i',
        'ot_approval' => 'i',
        'doubleottime' => 's',
        'halfot' => 'i',
        'month' => 'i',
        'year' => 'i',
        'ot' => 'i',
        'wot' => 'i',
        'cwot' => 'i',
        'combin_shift' => 'i',
        'combin_minimumhrs' => 's',
        'grace_beforeshift' => 's',
        'dayot' => 'i',
        'day_deduction' => 's',
        'deduction_limit' => 's',
        'day_additional' => 's',
        'nightot' => 'i',
        'night_deduction' => 's',
        'night_limit' => 's',
        'night_additional' => 's',
        'workhrs' => 's',
        'wot_full' => 'i',
        'wot_onshift' => 'i',
    ];
}

function otc_save_row(mysqli $con, int $id, array $data): int
{
    $columns = otc_columns($con, 'jos_app_ot_config');
    $spec = otc_field_spec();
    $fields = [];
    $types = '';
    $params = [];
    foreach ($spec as $field => $type) {
        if (!in_array($field, $columns, true)) continue;
        $fields[] = $field;
        $types .= $type;
        $params[] = $type === 'i' ? (int)$data[$field] : (string)$data[$field];
    }
    if (!$fields) throw new RuntimeException('No overtime configuration fields available.');

    if ($id > 0) {
        $sets = array_map(static fn($field) => '`' . $field . '`=?', $fields);
        $sql = 'UPDATE jos_app_ot_config SET ' . implode(',', $sets) . ' WHERE id=?';
        $stmt = otc_stmt($con, $sql);
        $types .= 'i';
        $params[] = $id;
        $stmt->bind_param($types, ...$params);
        if (!$stmt->execute()) throw new RuntimeException('Unable to update overtime configuration.');
        $stmt->close();
        return $id;
    }

    $sql = 'INSERT INTO jos_app_ot_config (`' . implode('`,`', $fields) . '`) VALUES (' . implode(',', array_fill(0, count($fields), '?')) . ')';
    $stmt = otc_stmt($con, $sql);
    $stmt->bind_param($types, ...$params);
    if (!$stmt->execute()) throw new RuntimeException('Unable to add overtime configuration.');
    $savedId = (int)$con->insert_id;
    $stmt->close();
    return $savedId;
}

function otc_insert_history(mysqli $con, int $configId): void
{
    $historyColumns = otc_columns($con, 'jos_app_ot_config_editlog');
    if (!$historyColumns) return;
    $stmt = otc_stmt($con, 'SELECT * FROM jos_app_ot_config WHERE id=? LIMIT 1');
    $stmt->bind_param('i', $configId);
    $stmt->execute();
    $source = $stmt->get_result()->fetch_assoc() ?: [];
    $stmt->close();
    if (!$source) return;

    $userId = (int)(current_user()['id'] ?? 0);
    $fields = [];
    $placeholders = [];
    $types = '';
    $params = [];
    foreach ($historyColumns as $column) {
        if ($column === 'id') continue;
        if ($column === 'otconfigid') {
            $fields[] = $column; $placeholders[] = '?'; $types .= 'i'; $params[] = $configId;
        } elseif ($column === 'date' || $column === 'sysdate' || $column === 'modifieddate') {
            $fields[] = $column; $placeholders[] = 'NOW()';
        } elseif ($column === 'modify_by' || $column === 'modified_by' || $column === 'modifed_by' || $column === 'userid') {
            $fields[] = $column; $placeholders[] = '?'; $types .= 'i'; $params[] = $userId;
        } elseif (array_key_exists($column, $source)) {
            $fields[] = $column; $placeholders[] = '?';
            if (is_numeric($source[$column]) && preg_match('/^-?\d+$/', (string)$source[$column])) {
                $types .= 'i'; $params[] = (int)$source[$column];
            } else {
                $types .= 's'; $params[] = (string)$source[$column];
            }
        }
    }
    if (!$fields) return;
    $sql = 'INSERT INTO jos_app_ot_config_editlog (`' . implode('`,`', $fields) . '`) VALUES (' . implode(',', $placeholders) . ')';
    $stmt = otc_stmt($con, $sql);
    if ($types !== '') $stmt->bind_param($types, ...$params);
    if (!$stmt->execute()) throw new RuntimeException('Unable to save overtime configuration history.');
    $stmt->close();
}

function otc_history_rows(mysqli $con, int $configId): array
{
    if (!otc_columns($con, 'jos_app_ot_config_editlog')) return [];
    $order = otc_has_column($con, 'jos_app_ot_config_editlog', 'date') ? '`date` DESC,id DESC' : 'id DESC';
    $rows = [];
    $stmt = otc_stmt($con, 'SELECT * FROM jos_app_ot_config_editlog WHERE otconfigid=? ORDER BY ' . $order);
    $stmt->bind_param('i', $configId);
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) $rows[] = $row;
    $stmt->close();
    return $rows;
}

function otc_label(array $labels, $value): string
{
    return $labels[(int)$value] ?? (string)$value;
}

$months = otc_options($con, 'SELECT id,month AS name FROM jos_app_mmonth ORDER BY id');
$years = otc_options($con, 'SELECT id,year AS name,assessment FROM jos_app_year ORDER BY id DESC');
$monthMap = $yearMap = [];
foreach ($months as $row) $monthMap[(int)$row['id']] = (string)$row['name'];
foreach ($years as $row) $yearMap[(int)$row['id']] = (string)$row['name'];

$applyBeforeLabels = [0 => 'Yes (All Days)', 1 => 'No', 2 => 'Exclude WOff And PH'];
$approvalLabels = [0 => 'Auto Approve', 1 => 'Auto Reject'];
$yesNoLabels = [0 => 'No', 1 => 'Yes'];
$wotFullLabels = [0 => 'Full WOT', 1 => 'WOT After Shift Hrs Only', 2 => 'WOT Multiply After Max Work Day'];

$mode = (string)($_GET['mode'] ?? '');
$editId = max(0, (int)($_GET['edit'] ?? 0));
$historyId = max(0, (int)($_GET['history'] ?? 0));
$isHistory = $historyId > 0;
$isForm = !$isHistory && ($mode === 'add' || $editId > 0);
$editRow = null;
$historyParent = null;
$historyRows = [];

if (!$isHistory && $mode === 'add' && empty($acl['can_add'])) {
    $_SESSION['flash_overtime_configuration'] = 'You do not have permission to add overtime configurations.';
    redirect('/attendance/overtime-configuration.php');
}

if (!$isHistory && $editId > 0 && empty($acl['can_edit'])) {
    $_SESSION['flash_overtime_configuration'] = 'You do not have permission to edit overtime configurations.';
    redirect('/attendance/overtime-configuration.php');
}

if ($historyId > 0) {
    $stmt = otc_stmt($con, 'SELECT c.*,m.month AS month_name,y.year AS year_name FROM jos_app_ot_config c LEFT JOIN jos_app_mmonth m ON m.id=c.month LEFT JOIN jos_app_year y ON y.id=c.year WHERE c.id=? LIMIT 1');
    $stmt->bind_param('i', $historyId);
    $stmt->execute();
    $historyParent = $stmt->get_result()->fetch_assoc() ?: null;
    $stmt->close();
    if (!$historyParent) {
        $_SESSION['flash_overtime_configuration'] = 'Overtime Configuration was not found.';
        redirect('/attendance/overtime-configuration.php');
    }
    $historyRows = otc_history_rows($con, $historyId);
}

if (!$isHistory && $editId > 0) {
    $stmt = otc_stmt($con, 'SELECT * FROM jos_app_ot_config WHERE id=? LIMIT 1');
    $stmt->bind_param('i', $editId);
    $stmt->execute();
    $editRow = $stmt->get_result()->fetch_assoc() ?: null;
    $stmt->close();
    if (!$editRow) {
        $_SESSION['flash_overtime_configuration'] = 'Overtime Configuration was not found.';
        redirect('/attendance/overtime-configuration.php');
    }
}

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') {
        $id = max(0, (int)($_POST['id'] ?? 0));
        if ($id > 0 && empty($acl['can_edit'])) $errors[] = 'You do not have permission to edit overtime configurations.';
        if ($id === 0 && empty($acl['can_add'])) $errors[] = 'You do not have permission to add overtime configurations.';
        if ($id > 0 && !otc_exists($con, $id)) $errors[] = 'Overtime Configuration was not found.';

        $policyName = trim((string)($_POST['policyname'] ?? ''));
        if ($policyName === '') $errors[] = 'Policy name is required.';
        if (strlen($policyName) > 255) $errors[] = 'Policy name is too long.';

        $month = max(0, (int)($_POST['month'] ?? 0));
        $year = max(0, (int)($_POST['year'] ?? 0));
        if (!otc_valid_id($con, 'jos_app_mmonth', $month)) $errors[] = 'Select a valid month.';
        if (!otc_valid_id($con, 'jos_app_year', $year)) $errors[] = 'Select a valid year.';

        $minimumhrs = trim((string)($_POST['minimumhrs'] ?? ''));
        $maxhrs = trim((string)($_POST['maxhrs'] ?? ''));
        $workhrs = trim((string)($_POST['workhrs'] ?? ''));
        $combinMinimumhrs = trim((string)($_POST['combin_minimumhrs'] ?? ''));
        $minimummin = otc_hhmm_to_minutes($minimumhrs, 'Minimum time', $errors);
        $maxmin = otc_hhmm_to_minutes($maxhrs, 'Maximum time', $errors);
        if ($workhrs !== '') otc_hhmm_to_minutes($workhrs, 'Total hrs for 1 day', $errors);

        $combinShift = otc_select_value($_POST['combin_shift'] ?? 0, [0, 1], 'combin shift setting', $errors);
        if ($combinShift === 1) otc_hhmm_to_minutes($combinMinimumhrs, 'Combin shift minimum time', $errors, true);
        if ($combinShift === 0) $combinMinimumhrs = '';

        $data = [
            'policyname' => $policyName,
            'minimumhrs' => $minimumhrs,
            'minimummin' => $minimummin,
            'maxhrs' => $maxhrs,
            'maxmin' => $maxmin,
            'roundup_day' => otc_int_value($_POST['roundup_day'] ?? '', 'Daily round to next', $errors),
            'roundup_monthly' => otc_int_value($_POST['roundup_monthly'] ?? '', 'Monthly round to next', $errors),
            'roundup_minutes' => otc_int_value($_POST['roundup_minutes'] ?? '', 'Daily roundup log', $errors),
            'grace' => otc_int_value($_POST['grace'] ?? '', 'Grace period for OT calculation', $errors),
            'apply_before' => otc_select_value($_POST['apply_before'] ?? 0, [0, 1, 2], 'policy apply before shift timing', $errors),
            'ot_approval' => otc_select_value($_POST['ot_approval'] ?? 0, [0, 1], 'OT approval configuration', $errors),
            'doubleottime' => otc_int_value($_POST['doubleottime'] ?? '', 'Double OT after time', $errors),
            'halfot' => otc_select_value($_POST['halfot'] ?? 0, [0, 1], 'half OT grace setting', $errors),
            'month' => $month,
            'year' => $year,
            'ot' => isset($_POST['ot']) ? 1 : 0,
            'wot' => isset($_POST['wot']) ? 1 : 0,
            'cwot' => isset($_POST['cwot']) ? 1 : 0,
            'combin_shift' => $combinShift,
            'combin_minimumhrs' => $combinMinimumhrs,
            'grace_beforeshift' => otc_int_value($_POST['grace_beforeshift'] ?? '', 'Grace period before shift', $errors),
            'dayot' => isset($_POST['dayot']) ? 1 : 0,
            'day_deduction' => otc_number($_POST['day_deduction'] ?? '', 'Day OT deduction day', $errors),
            'deduction_limit' => otc_number($_POST['deduction_limit'] ?? '', 'Day OT limit day', $errors),
            'day_additional' => otc_number($_POST['day_additional'] ?? '', 'Day OT additional day', $errors),
            'nightot' => isset($_POST['nightot']) ? 1 : 0,
            'night_deduction' => otc_number($_POST['night_deduction'] ?? '', 'Night OT deduction day', $errors),
            'night_limit' => otc_number($_POST['night_limit'] ?? '', 'Night OT limit day', $errors),
            'night_additional' => otc_number($_POST['night_additional'] ?? '', 'Night OT additional day', $errors),
            'workhrs' => $workhrs,
            'wot_full' => otc_select_value($_POST['wot_full'] ?? 0, [0, 1, 2], 'WOT calculation setting', $errors),
            'wot_onshift' => otc_select_value($_POST['wot_onshift'] ?? 0, [0, 1], 'WOT/PH OT half or full day setting', $errors),
        ];

        if (!$errors) {
            $con->begin_transaction();
            try {
                $savedId = otc_save_row($con, $id, $data);
                otc_insert_history($con, $savedId);
                $con->commit();
                $_SESSION['flash_overtime_configuration'] = $id > 0 ? 'Overtime Configuration updated successfully.' : 'Overtime Configuration added successfully.';
                redirect('/attendance/overtime-configuration.php');
            } catch (Throwable $e) {
                $con->rollback();
                $errors[] = 'Unable to save the overtime configuration. No changes were committed.';
            }
        }

        $isForm = true;
        $isHistory = false;
        $editId = $id;
        $editRow = $data + ['id' => $id];
    }
}

$filterQ = trim((string)($_GET['q'] ?? ''));
$filterMonth = max(0, (int)($_GET['month'] ?? 0));
$filterYear = max(0, (int)($_GET['year'] ?? 0));
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = 20;
$totalRows = 0;
$rows = [];
$pages = 1;

if (!$isForm && !$isHistory) {
    $where = ['1=1'];
    $types = '';
    $params = [];
    if ($filterQ !== '') { $where[] = 'c.policyname LIKE ?'; $types .= 's'; $params[] = '%' . $filterQ . '%'; }
    if ($filterMonth > 0) { $where[] = 'c.month=?'; $types .= 'i'; $params[] = $filterMonth; }
    if ($filterYear > 0) { $where[] = 'c.year=?'; $types .= 'i'; $params[] = $filterYear; }
    $whereSql = implode(' AND ', $where);

    $stmt = otc_stmt($con, 'SELECT COUNT(*) AS total FROM jos_app_ot_config c WHERE ' . $whereSql);
    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;

    $stmt = otc_stmt($con, 'SELECT c.*,m.month AS month_name,y.year AS year_name,(SELECT COUNT(*) FROM jos_app_ot_config_editlog e WHERE e.otconfigid=c.id) AS history_count FROM jos_app_ot_config c LEFT JOIN jos_app_mmonth m ON m.id=c.month LEFT JOIN jos_app_year y ON y.id=c.year WHERE ' . $whereSql . ' ORDER BY DATE(CONCAT(y.year, "-", c.month, "-01")) DESC,c.id DESC LIMIT ? OFFSET ?');
    $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();
}

$value = static function (string $key, $default = '') use (&$editRow) { return $editRow[$key] ?? $default; };
$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';

console_header('Overtime 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">Overtime Configuration</span></div><h1 class="text-2xl font-bold text-slate-900">Overtime Configuration</h1><p class="mt-1 text-sm text-slate-500">Configure OT, WOT, C WOT, approval, grace, rounding, and day/night OT rules.</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 ($isHistory): ?>
<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">Overtime Configuration History</h2><p class="mt-1 text-xs font-medium text-slate-400"><?= h($historyParent['policyname'] ?? '') ?> · <?= h($historyParent['month_name'] ?: ($monthMap[(int)($historyParent['month'] ?? 0)] ?? '')) ?> <?= h($historyParent['year_name'] ?: ($yearMap[(int)($historyParent['year'] ?? 0)] ?? '')) ?></p></div><a href="/attendance/overtime-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="overflow-x-auto"><table class="w-full min-w-[1320px] text-left text-sm"><thead class="bg-slate-50 text-[10px] uppercase tracking-wider text-slate-400"><tr><th class="px-5 py-4">Date</th><th class="px-5 py-4">Policy</th><th class="px-5 py-4">Month</th><th class="px-5 py-4">Min / Max</th><th class="px-5 py-4">Grace</th><th class="px-5 py-4">Rounding</th><th class="px-5 py-4">OT Types</th><th class="px-5 py-4">Day / Night</th></tr></thead><tbody class="divide-y divide-slate-100">
    <?php if(!$historyRows): ?><tr><td colspan="8" class="px-6 py-14 text-center font-semibold text-slate-400">No history found.</td></tr><?php endif; ?>
    <?php foreach($historyRows as $row): ?><tr class="align-top hover:bg-slate-50/70"><td class="px-5 py-4 font-semibold text-slate-700"><?= h((string)($row['date'] ?? '')) ?></td><td class="px-5 py-4 font-bold text-slate-800"><?= h((string)($row['policyname'] ?? '')) ?></td><td class="px-5 py-4"><?= h($monthMap[(int)($row['month'] ?? 0)] ?? (string)($row['month'] ?? '')) ?> <?= h($yearMap[(int)($row['year'] ?? 0)] ?? (string)($row['year'] ?? '')) ?></td><td class="px-5 py-4"><?= h((string)($row['minimumhrs'] ?? '')) ?> / <?= h((string)($row['maxhrs'] ?? '')) ?></td><td class="px-5 py-4">OT <?= h((string)($row['grace'] ?? '')) ?> min<br>Before shift <?= h((string)($row['grace_beforeshift'] ?? '')) ?> min</td><td class="px-5 py-4">Daily <?= h((string)($row['roundup_day'] ?? '')) ?><br>Monthly <?= h((string)($row['roundup_monthly'] ?? '')) ?></td><td class="px-5 py-4"><?= (int)($row['ot'] ?? 0) ? 'OT ' : '' ?><?= (int)($row['wot'] ?? 0) ? 'WOT ' : '' ?><?= (int)($row['cwot'] ?? 0) ? 'C WOT' : '' ?></td><td class="px-5 py-4">Day <?= (int)($row['dayot'] ?? 0) ? 'Yes' : 'No' ?><br>Night <?= (int)($row['nightot'] ?? 0) ? 'Yes' : 'No' ?></td></tr><?php endforeach; ?>
  </tbody></table></div>
</section>
<?php elseif ($isForm): ?>
<form method="post" id="overtime-configuration-form" class="space-y-4">
  <input type="hidden" name="_csrf" value="<?= h(csrf_token()) ?>"><input type="hidden" name="action" value="save"><input type="hidden" name="id" value="<?= (int)$value('id', 0) ?>">
  <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-clock"></i></span><div><h2 class="font-bold text-slate-800"><?= (int)$value('id',0)>0?'Edit Overtime Configuration':'New Overtime Configuration' ?></h2><p class="text-xs text-slate-400">Fields marked with * are required.</p></div></div><a href="/attendance/overtime-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-4">
      <label class="text-sm font-semibold text-slate-700">Policy Name *<input name="policyname" required value="<?= h((string)$value('policyname')) ?>" class="<?= $input ?>" placeholder="Policy Name"></label>
      <label class="text-sm font-semibold text-slate-700">Month *<select name="month" required class="<?= $input ?>"><option value="">Select Month</option><?php foreach($months as $option): ?><option value="<?= (int)$option['id'] ?>" <?= (int)$value('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 class="<?= $input ?>"><option value="">Select Year</option><?php foreach($years as $option): ?><option value="<?= (int)$option['id'] ?>" <?= (int)$value('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">OT Approval Configuration<select name="ot_approval" class="<?= $input ?>"><?php foreach($approvalLabels as $k=>$label): ?><option value="<?= $k ?>" <?= (int)$value('ot_approval',0)===$k?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></label>
    </div>
  </section>

  <section class="rounded-2xl border border-slate-100 bg-white p-4 shadow-sm">
    <h2 class="mb-3 font-bold text-slate-800">Timing Rules</h2>
    <div class="grid gap-3 md:grid-cols-4">
      <label class="text-sm font-semibold text-slate-700">Policy Apply Before Shift<select name="apply_before" class="<?= $input ?>"><?php foreach($applyBeforeLabels as $k=>$label): ?><option value="<?= $k ?>" <?= (int)$value('apply_before',0)===$k?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></label>
      <label class="text-sm font-semibold text-slate-700">Grace Before Shift (MM)<input name="grace_beforeshift" inputmode="numeric" value="<?= h((string)$value('grace_beforeshift')) ?>" class="<?= $input ?>" placeholder="MM"></label>
      <label class="text-sm font-semibold text-slate-700">Total Hrs For 1 Day<input name="workhrs" value="<?= h((string)$value('workhrs')) ?>" class="<?= $input ?>" placeholder="HH:MM"></label>
      <label class="text-sm font-semibold text-slate-700">Apply Half OT Grace<select name="halfot" class="<?= $input ?>"><?php foreach($yesNoLabels as $k=>$label): ?><option value="<?= $k ?>" <?= (int)$value('halfot',0)===$k?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></label>
      <label class="text-sm font-semibold text-slate-700">OT Grace Period (MM)<input name="grace" inputmode="numeric" value="<?= h((string)$value('grace')) ?>" class="<?= $input ?>" placeholder="MM"></label>
      <label class="text-sm font-semibold text-slate-700">Minimum Time<input name="minimumhrs" value="<?= h((string)$value('minimumhrs')) ?>" class="<?= $input ?> js-time-min" placeholder="HH:MM"></label>
      <label class="text-sm font-semibold text-slate-700">Minimum Min<input name="minimummin" readonly value="<?= h((string)$value('minimummin')) ?>" class="<?= $input ?> bg-slate-50" placeholder="MM"></label>
      <label class="text-sm font-semibold text-slate-700">Maximum Time<input name="maxhrs" value="<?= h((string)$value('maxhrs')) ?>" class="<?= $input ?> js-time-max" placeholder="HH:MM"></label>
      <label class="text-sm font-semibold text-slate-700">Maximum Min<input name="maxmin" readonly value="<?= h((string)$value('maxmin')) ?>" class="<?= $input ?> bg-slate-50" placeholder="MM"></label>
      <label class="text-sm font-semibold text-slate-700">Daily Roundup Log (MM)<input name="roundup_minutes" inputmode="numeric" value="<?= h((string)$value('roundup_minutes')) ?>" class="<?= $input ?>" placeholder="MM"></label>
      <label class="text-sm font-semibold text-slate-700">Daily Round To Next (MM)<input name="roundup_day" inputmode="numeric" value="<?= h((string)$value('roundup_day')) ?>" class="<?= $input ?>" placeholder="MM"></label>
      <label class="text-sm font-semibold text-slate-700">Monthly Round To Next (MM)<input name="roundup_monthly" inputmode="numeric" value="<?= h((string)$value('roundup_monthly')) ?>" class="<?= $input ?>" placeholder="MM"></label>
    </div>
  </section>

  <section class="rounded-2xl border border-slate-100 bg-white p-4 shadow-sm">
    <h2 class="mb-3 font-bold text-slate-800">OT Type Rules</h2>
    <div class="grid gap-3 md:grid-cols-4">
      <div class="text-sm font-semibold text-slate-700"><span>OT / WOT / C WOT</span><div class="mt-3 flex flex-wrap gap-3"><label class="inline-flex items-center gap-2 rounded-lg border border-slate-200 px-3 py-2"><input type="checkbox" name="ot" value="1" <?= (int)$value('ot')===1?'checked':'' ?>> OT</label><label class="inline-flex items-center gap-2 rounded-lg border border-slate-200 px-3 py-2"><input type="checkbox" name="wot" value="1" class="js-wot-toggle" <?= (int)$value('wot')===1?'checked':'' ?>> WOT</label><label class="inline-flex items-center gap-2 rounded-lg border border-slate-200 px-3 py-2"><input type="checkbox" name="cwot" value="1" class="js-wot-toggle" <?= (int)$value('cwot')===1?'checked':'' ?>> C WOT</label></div></div>
      <label class="text-sm font-semibold text-slate-700 js-wot-field">Full WOT / After Shift Hrs<select name="wot_full" class="<?= $input ?>"><?php foreach($wotFullLabels as $k=>$label): ?><option value="<?= $k ?>" <?= (int)$value('wot_full',0)===$k?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></label>
      <label class="text-sm font-semibold text-slate-700 js-wot-field">Calculate WOT / PH OT In Half Or Full Days<select name="wot_onshift" class="<?= $input ?>"><?php foreach($yesNoLabels as $k=>$label): ?><option value="<?= $k ?>" <?= (int)$value('wot_onshift',0)===$k?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></label>
      <label class="text-sm font-semibold text-slate-700">Double OT After Time (MM)<input name="doubleottime" inputmode="numeric" value="<?= h((string)$value('doubleottime')) ?>" class="<?= $input ?>" placeholder="MM"></label>
      <label class="text-sm font-semibold text-slate-700">Combin Shift For Total Hrs<select name="combin_shift" class="<?= $input ?> js-combin-shift"><?php foreach($yesNoLabels as $k=>$label): ?><option value="<?= $k ?>" <?= (int)$value('combin_shift',0)===$k?'selected':'' ?>><?= h($label) ?></option><?php endforeach; ?></select></label>
      <label class="text-sm font-semibold text-slate-700 js-combin-min">Combin Minimum Time<input name="combin_minimumhrs" value="<?= h((string)$value('combin_minimumhrs')) ?>" class="<?= $input ?>" placeholder="HH:MM"></label>
    </div>
  </section>

  <section class="rounded-2xl border border-slate-100 bg-white p-4 shadow-sm">
    <h2 class="mb-3 font-bold text-slate-800">Day / Night OT Days Configuration</h2>
    <div class="grid gap-3 md:grid-cols-4">
      <label class="inline-flex items-center gap-2 text-sm font-semibold text-slate-700"><input type="checkbox" name="dayot" value="1" <?= (int)$value('dayot')===1?'checked':'' ?>> Day OT</label>
      <label class="text-sm font-semibold text-slate-700">Day Deduction<input name="day_deduction" value="<?= h((string)$value('day_deduction')) ?>" class="<?= $input ?>" placeholder="Deduction"></label>
      <label class="text-sm font-semibold text-slate-700">Day Limit<input name="deduction_limit" value="<?= h((string)$value('deduction_limit')) ?>" class="<?= $input ?>" placeholder="Limit"></label>
      <label class="text-sm font-semibold text-slate-700">Day Additional<input name="day_additional" value="<?= h((string)$value('day_additional')) ?>" class="<?= $input ?>" placeholder="Additional"></label>
      <label class="inline-flex items-center gap-2 text-sm font-semibold text-slate-700"><input type="checkbox" name="nightot" value="1" <?= (int)$value('nightot')===1?'checked':'' ?>> Night OT</label>
      <label class="text-sm font-semibold text-slate-700">Night Deduction<input name="night_deduction" value="<?= h((string)$value('night_deduction')) ?>" class="<?= $input ?>" placeholder="Deduction"></label>
      <label class="text-sm font-semibold text-slate-700">Night Limit<input name="night_limit" value="<?= h((string)$value('night_limit')) ?>" class="<?= $input ?>" placeholder="Limit"></label>
      <label class="text-sm font-semibold text-slate-700">Night Additional<input name="night_additional" value="<?= h((string)$value('night_additional')) ?>" class="<?= $input ?>" placeholder="Additional"></label>
    </div>
  </section>
  <div class="flex flex-wrap justify-end gap-2"><a href="/attendance/overtime-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>
</form>
<script>
(()=>{const toMin=(v)=>{const m=/^(\d{1,4}):([0-5]\d)$/.exec((v||'').trim());return m?String((parseInt(m[1],10)*60)+parseInt(m[2],10)):'';};const min=document.querySelector('.js-time-min'),minOut=document.querySelector('input[name="minimummin"]'),max=document.querySelector('.js-time-max'),maxOut=document.querySelector('input[name="maxmin"]');const sync=()=>{if(min&&minOut)minOut.value=toMin(min.value);if(max&&maxOut)maxOut.value=toMin(max.value);};if(min)min.addEventListener('input',sync);if(max)max.addEventListener('input',sync);const shift=document.querySelector('.js-combin-shift'),box=document.querySelector('.js-combin-min'),comb=document.querySelector('input[name="combin_minimumhrs"]');const showComb=()=>{const on=shift&&shift.value==='1';if(box)box.style.display=on?'':'none';if(comb)comb.required=!!on;};if(shift)shift.addEventListener('change',showComb);const toggles=[...document.querySelectorAll('.js-wot-toggle')],wotFields=[...document.querySelectorAll('.js-wot-field')];const showWot=()=>{const on=toggles.some(el=>el.checked);wotFields.forEach(el=>el.style.display=on?'':'none');};toggles.forEach(el=>el.addEventListener('change',showWot));sync();showComb();showWot();})();
</script>
<?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">Overtime Configuration List</h2><p class="mt-1 text-xs font-medium text-slate-400">Policies are ordered by latest month and year.</p></div><?php if(!empty($acl['can_add'])): ?><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>
  <form method="get" class="grid gap-3 border-b border-slate-100 p-5 md:grid-cols-2 xl:grid-cols-6"><input name="q" value="<?= h($filterQ) ?>" class="<?= $selectSmall ?> xl:col-span-2" placeholder="Search policy name"><select name="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="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><div class="flex gap-2 xl:col-span-2"><button class="rounded-xl bg-slate-900 px-5 py-2.5 text-sm font-bold text-white"><i class="fa-solid fa-filter mr-2"></i>Filter</button><a href="/attendance/overtime-configuration.php" class="rounded-xl border border-slate-200 px-5 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-[1500px] 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">Policy</th><th class="px-5 py-4">Month</th><th class="px-5 py-4">Apply Before / Grace</th><th class="px-5 py-4">OT Grace / Half OT</th><th class="px-5 py-4">Min / Max</th><th class="px-5 py-4">Rounding</th><th class="px-5 py-4">Approval / Rate Hrs</th><th class="px-5 py-4">Combin Shift</th><th class="px-5 py-4">Day Config</th><th class="px-5 py-4">Night Config</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="12" class="px-6 py-14 text-center font-semibold text-slate-400">No overtime configurations found.</td></tr><?php endif; ?>
    <?php foreach($rows as $index=>$row): ?><tr class="align-top 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((string)$row['policyname']) ?></div><div class="mt-1 text-xs font-semibold text-brand-600"><?= (int)$row['ot']?'OT ':'' ?><?= (int)$row['wot']?'WOT ':'' ?><?= (int)$row['cwot']?'C WOT':'' ?></div><?php if((int)$row['history_count']>0): ?><div class="mt-1 text-xs font-semibold text-slate-400">History <?= (int)$row['history_count'] ?></div><?php endif; ?></td><td class="px-5 py-4 font-semibold"><?= h($row['month_name'] ?: ($monthMap[(int)$row['month']] ?? '')) ?><br><?= h($row['year_name'] ?: ($yearMap[(int)$row['year']] ?? '')) ?></td><td class="px-5 py-4"><?= h(otc_label($applyBeforeLabels, $row['apply_before'])) ?><br><span class="text-xs text-slate-400"><?= h((string)$row['grace_beforeshift']) ?> min</span></td><td class="px-5 py-4"><?= h((string)$row['grace']) ?> min<br><span class="text-xs text-slate-400"><?= h(otc_label($yesNoLabels, $row['halfot'])) ?></span></td><td class="px-5 py-4"><?= h((string)$row['minimumhrs']) ?> / <?= h((string)$row['maxhrs']) ?><br><span class="text-xs text-slate-400"><?= (int)$row['minimummin'] ?> / <?= (int)$row['maxmin'] ?> min</span></td><td class="px-5 py-4">Log <?= h((string)$row['roundup_minutes']) ?><br>Daily <?= h((string)$row['roundup_day']) ?><br>Monthly <?= h((string)$row['roundup_monthly']) ?></td><td class="px-5 py-4"><?= h(otc_label($approvalLabels, $row['ot_approval'])) ?><br><span class="text-xs text-slate-400"><?= h((string)$row['workhrs']) ?></span></td><td class="px-5 py-4"><?= (int)$row['combin_shift'] ? 'Yes' : 'No' ?><br><span class="text-xs text-slate-400"><?= h((string)$row['combin_minimumhrs']) ?></span></td><td class="px-5 py-4"><?= (int)$row['dayot'] ? h($row['day_deduction'] . ' / ' . $row['deduction_limit'] . ' / ' . $row['day_additional']) : 'No' ?></td><td class="px-5 py-4"><?= (int)$row['nightot'] ? h($row['night_deduction'] . ' / ' . $row['night_limit'] . ' / ' . $row['night_additional']) : 'No' ?></td><td class="px-5 py-4"><div class="flex justify-end gap-2"><?php if((int)$row['history_count']>0): ?><a href="?history=<?= (int)$row['id'] ?>" class="rounded-lg border border-slate-200 px-3 py-2 text-slate-600 hover:bg-brand-50 hover:text-brand-600" title="History"><i class="fa-solid fa-clock-rotate-left"></i></a><?php endif; ?><?php if(!empty($acl['can_edit'])): ?><a href="?edit=<?= (int)$row['id'] ?>" 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; ?></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 ?> policies</span><div class="flex gap-2"><?php $base=['q'=>$filterQ,'month'=>$filterMonth,'year'=>$filterYear]; 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; ?>
<?php console_footer(); ?>
