<?php
// edit_payroll_entry.php (EPF/ESI flexible + manual override amounts + outstanding)
// Updated: automatic components (Basic/DA/HRA/Medical/Conveyance) from Total Wages,
// automatic EPF & ESI calculation (server + live JS preview)
// Changed outstanding handling: outstanding_amt is now ADDED to the payable (carryforward owed to employee).
// Added: manual EPF and manual ESI entry options (per-payroll override)
// NOTE: EPF % and EPF Fixed Amount options removed from UI;
//       EPF uses fixed 12% of (Basic + DA + HRA) unless manual EPF enabled.

session_start();
include 'config.php';

if (!isset($_SESSION['username']) || !in_array($_SESSION['role'], ['admin','superadmin','manager'])) {
    header("Location: index.php");
    exit;
}
$is_admin = in_array($_SESSION['role'], ['admin','superadmin']);

// ensure utf8
if (method_exists($conn, 'set_charset')) $conn->set_charset('utf8mb4');

// ---------- detect users table columns (now includes basic_salary & epf/esi candidates) ----------
$dbname = '';
$db_res = $conn->query("SELECT DATABASE() AS dbname");
if ($db_res) {
    $row_db = $db_res->fetch_assoc();
    $dbname = $row_db['dbname'] ?? '';
}

$found = [];
if ($dbname) {
    // include basic, basic_salary, division candidates too + epf/esi candidate column names
    $candidates = [
        'emp_code','empid','emp_id','name','full_name',
        'basic_salary','basic','division','dept',
        // EPF/ESI related user table candidates (if you keep these in users table)
        'epf_applicable','esi_applicable','epf_amount','epf_percent'
    ];
    $in = "'" . implode("','", array_map('addslashes', $candidates)) . "'";
    $sqlCols = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = 'users' AND COLUMN_NAME IN ($in)";
    $stmtCols = $conn->prepare($sqlCols);
    if ($stmtCols) {
        $stmtCols->bind_param("s", $dbname);
        $stmtCols->execute();
        $resCols = $stmtCols->get_result();
        while ($r = $resCols->fetch_assoc()) {
            $found[strtolower($r['COLUMN_NAME'])] = $r['COLUMN_NAME'];
        }
        $stmtCols->close();
    }
}

// map discovered columns
$user_emp_code_col = $found['emp_code'] ?? $found['empid'] ?? $found['emp_id'] ?? null;
$user_name_col     = $found['name'] ?? $found['full_name'] ?? null;
$user_empid_col    = $found['empid'] ?? $found['emp_id'] ?? null;
$user_basic_col    = $found['basic_salary'] ?? $found['basic'] ?? null;
$user_div_col      = $found['division'] ?? $found['dept'] ?? null;
$user_epf_app_col  = $found['epf_applicable'] ?? null;
$user_esi_app_col  = $found['esi_applicable'] ?? null;
$user_epf_amount_col = $found['epf_amount'] ?? null; // fixed EPF amount in users table (optional)
$user_epf_percent_col = $found['epf_percent'] ?? null; // EPF percent in users table (optional)

// Build emp_code and name expressions (prefer users columns when present)
$emp_code_expr_parts = [];
if ($user_emp_code_col) $emp_code_expr_parts[] = "u.`{$user_emp_code_col}`";
if ($user_empid_col)   $emp_code_expr_parts[] = "u.`{$user_empid_col}`";
$emp_code_expr_parts[] = "CAST(p.emp_id AS CHAR)";
$emp_code_expr = "COALESCE(" . implode(", ", $emp_code_expr_parts) . ") AS user_emp_code";

$name_expr_parts = [];
if ($user_name_col) $name_expr_parts[] = "u.`{$user_name_col}`";
$name_expr_parts[] = "COALESCE(p.name, CAST(p.emp_id AS CHAR))";
$name_expr = "COALESCE(" . implode(", ", $name_expr_parts) . ") AS user_name";

// basic expr: if users has basic column, select it, otherwise select p.basic as user_basic_salary
if ($user_basic_col) {
    $basic_expr = "u.`{$user_basic_col}` AS user_basic_salary";
} else {
    $basic_expr = "p.basic AS user_basic_salary";
}

// optionally select epf/esi fields from users if present
$extra_selects = [];
if ($user_epf_app_col) $extra_selects[] = "u.`{$user_epf_app_col}` AS user_epf_applicable";
if ($user_esi_app_col) $extra_selects[] = "u.`{$user_esi_app_col}` AS user_esi_applicable";
if ($user_epf_amount_col) $extra_selects[] = "u.`{$user_epf_amount_col}` AS user_epf_amount";
if ($user_epf_percent_col) $extra_selects[] = "u.`{$user_epf_percent_col}` AS user_epf_percent";

$extra_select_sql = $extra_selects ? ", " . implode(", ", $extra_selects) : "";

// redirect / preserve
$redirect_base = 'payroll.php';
$preserve_month = $_GET['month'] ?? ($_POST['month'] ?? '');
$preserve_division = $_GET['division'] ?? ($_POST['division'] ?? '');

$errors = [];

/**
 * Compute EPF (employee share) and ESI (employee share) given basic, da, hra and gross.
 * Accepts optional parameters:
 *   $epf_enabled (bool) - whether EPF applies for this employee/payroll
 *   $epf_percent (float) - percent (e.g. 12) to apply to (basic+da+hra) if no fixed amount provided
 *   $epf_fixed_amount (float|null) - fixed employee EPF amount to use (overrides percent if > 0)
 *
 * - ESI employee deduction = 0.75% of gross if gross <= 21000 and $esi_enabled true; otherwise 0.
 *
 * Returns array: [employee_epf, employee_esi, employer_esi]
 */
function compute_epf_esi($basic, $da, $hra, $gross_salary, $opts = []) {
    // options and defaults
    $epf_enabled = array_key_exists('epf_enabled', $opts) ? (bool)$opts['epf_enabled'] : true;
    $epf_percent = array_key_exists('epf_percent', $opts) ? (float)$opts['epf_percent'] : 12.0;
    $epf_fixed_amount = array_key_exists('epf_fixed_amount', $opts) ? (float)$opts['epf_fixed_amount'] : 0.0;
    $EPF_MAX_CONTRIBUTION = array_key_exists('epf_max_cap', $opts) ? (float)$opts['epf_max_cap'] : 1800.00; // default cap

    // default ESI enabled true unless specified
    $esi_enabled = array_key_exists('esi_enabled', $opts) ? (bool)$opts['esi_enabled'] : true;

    // Start with zeros
    $employee_epf = 0.00;
    $employee_esi = 0.00;
    $employer_esi = 0.00;

    // EPF (now on Basic + DA + HRA)
    if ($epf_enabled) {
        $pf_base = (float)$basic + (float)$da + (float)$hra;
        // If fixed amount provided and > 0, prefer it
        if ($epf_fixed_amount > 0) {
            $raw_epf = round($epf_fixed_amount, 2);
        } else {
            $raw_epf = round($pf_base * ($epf_percent / 100.0), 2);
        }

        if ($EPF_MAX_CONTRIBUTION && $EPF_MAX_CONTRIBUTION > 0) {
            $employee_epf = round(min($raw_epf, (float)$EPF_MAX_CONTRIBUTION), 2);
        } else {
            $employee_epf = $raw_epf;
        }
    }

    // ESI
    $esi_threshold = 21000.00;
    if ($esi_enabled && $gross_salary <= $esi_threshold) {
        $employee_esi = round($gross_salary * 0.0075, 2); // 0.75%
        $employer_esi = round($gross_salary * 0.0325, 2); // 3.25%
    }

    return [$employee_epf, $employee_esi, $employer_esi];
}

/**
 * Compute pay components from gross (total_wages) using percentages.
 * Default percentages:
 *   basic: 40%, da: 20%, hra: 20%, medical_allow:10%, conveyance_allow:10%
 *
 * Returns array: [basic, da, hra, medical_allow, conveyance_allow]
 */
function compute_components_from_gross($gross, $percentages = null) {
    if ($percentages === null) {
        $percentages = [
            'basic' => 40.0,
            'da' => 20.0,
            'hra' => 20.0,
            'medical_allow' => 10.0,
            'conveyance_allow' => 10.0
        ];
    }
    $g = (float)$gross;
    $basic = round($g * ($percentages['basic'] / 100.0), 2);
    $da = round($g * ($percentages['da'] / 100.0), 2);
    $hra = round($g * ($percentages['hra'] / 100.0), 2);
    $medical_allow = round($g * ($percentages['medical_allow'] / 100.0), 2);
    $conveyance_allow = round($g * ($percentages['conveyance_allow'] / 100.0), 2);

    // Adjust for rounding diffs: ensure sum equals gross by correcting basic
    $sum = $basic + $da + $hra + $medical_allow + $conveyance_allow;
    $diff = round($g - $sum, 2);
    if (abs($diff) >= 0.01) {
        // put remainder into basic to keep things consistent
        $basic = round($basic + $diff, 2);
    }

    return [$basic, $da, $hra, $medical_allow, $conveyance_allow];
}

// ---------- handle POST (save) ----------
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_payroll'])) {
    if (!$is_admin) $errors[] = "Permission denied.";
    $id = (int)($_POST['id'] ?? 0);
    if ($id <= 0) $errors[] = "Invalid record id.";

    $division = trim($_POST['division'] ?? 'Total');
    $salary            = isset($_POST['salary']) ? (float)$_POST['salary'] : 0.0;
    $working_days      = isset($_POST['working_days']) ? (float)$_POST['working_days'] : 0.0;
    $absent_days       = isset($_POST['absent_days']) ? (float)$_POST['absent_days'] : 0.0;
    $paid_days         = isset($_POST['paid_days']) ? (float)$_POST['paid_days'] : 0.0;
    $basic             = isset($_POST['basic']) ? (float)$_POST['basic'] : 0.0;
    $da                = isset($_POST['da']) ? (float)$_POST['da'] : 0.0;
    $hra               = isset($_POST['hra']) ? (float)$_POST['hra'] : 0.0;
    $medical_allow     = isset($_POST['medical_allow']) ? (float)$_POST['medical_allow'] : 0.0;
    $conveyance_allow  = isset($_POST['conveyance_allow']) ? (float)$_POST['conveyance_allow'] : 0.0;
    // ignore posted epf/esi display fields — we compute server-side (or accept manual override)
    $travel_allow      = isset($_POST['travel_allow']) ? (float)$_POST['travel_allow'] : 0.0;
    $two_wheeler_maint = isset($_POST['two_wheeler_maint']) ? (float)$_POST['two_wheeler_maint'] : 0.0;
    $tds               = isset($_POST['tds']) ? (float)$_POST['tds'] : 0.0;
    $advance           = isset($_POST['advance']) ? (float)$_POST['advance'] : 0.0;
    $outstanding_amt   = isset($_POST['outstanding_amt']) ? (float)$_POST['outstanding_amt'] : 0.0;

    $auto_calc_components = isset($_POST['auto_calc_components']) && $_POST['auto_calc_components'] ? true : false;

    // EPF/ESI overrides (from form)
    $epf_applicable_post = isset($_POST['epf_applicable']) && $_POST['epf_applicable'] ? true : false;
    $esi_applicable_post = isset($_POST['esi_applicable']) && $_POST['esi_applicable'] ? true : false;

    // EPF % and fixed amount options REMOVED: always use 12% and no fixed amount here
    $epf_percent_post = 12.0;
    $epf_fixed_amount_post = 0.0;

    // Manual override fields for EPF and ESI
    $manual_epf_enabled = isset($_POST['manual_epf']) && $_POST['manual_epf'] ? true : false;
    $manual_epf_amount = isset($_POST['manual_epf_amount']) ? (float)$_POST['manual_epf_amount'] : 0.0;
    $manual_esi_enabled = isset($_POST['manual_esi']) && $_POST['manual_esi'] ? true : false;
    $manual_esi_amount = isset($_POST['manual_esi_amount']) ? (float)$_POST['manual_esi_amount'] : 0.0;

    if ($working_days <= 0) {
        $working_days = $paid_days + $absent_days;
        if ($working_days <= 0) $working_days = 30;
    }

    $per_day_salary = $working_days > 0 ? round($salary / $working_days, 2) : 0.0;
    $total_wages    = round($per_day_salary * $paid_days, 2);

    // If basic is zero or other components not provided OR auto-calc checkbox is checked,
    // compute components from total_wages (treated as Gross)
    if ($auto_calc_components || $basic <= 0 || ($da == 0 && $hra == 0 && $medical_allow == 0 && $conveyance_allow == 0)) {
        list($cbasic, $cda, $chra, $cmedical, $cconvey) = compute_components_from_gross($total_wages);
        $basic = $cbasic;
        $da = $cda;
        $hra = $chra;
        $medical_allow = $cmedical;
        $conveyance_allow = $cconvey;
    }

    $gross_salary = round($basic + $da + $hra + $medical_allow + $conveyance_allow, 2);
    $total = round($gross_salary + $travel_allow + $two_wheeler_maint, 2);

    // compute EPF and ESI server-side (authoritative), using overrides
    $compute_opts = [
        'epf_enabled' => $epf_applicable_post,
        'epf_percent' => $epf_percent_post,      // always 12
        'epf_fixed_amount' => $epf_fixed_amount_post, // always 0
        'epf_max_cap' => 1800.00, // keep same cap default; change if you need configurable cap
        'esi_enabled' => $esi_applicable_post
    ];
    list($computed_epf, $computed_esi, $computed_employer_esi) = compute_epf_esi($basic, $da, $hra, $gross_salary, $compute_opts);

    // Apply manual overrides if checked by admin (server-authoritative choice)
    if ($manual_epf_enabled) {
        // Use manual amount (you may want to validate bounds here)
        $epf = round($manual_epf_amount, 2);
    } else {
        $epf = $computed_epf;
    }

    if ($manual_esi_enabled) {
        $esi = round($manual_esi_amount, 2);
    } else {
        $esi = $computed_esi;
    }

    // IMPORTANT CHANGE:
    // OUTSTANDING_AMOUNT is now treated as an AMOUNT OWED TO THE EMPLOYEE FROM PREVIOUS PERIODS,
    // so we ADD it to the total payable before subtracting deductions.
    // old: $pending_amt = round($total - $epf - $esi - $tds - $advance - $outstanding_amt, 2);
    $pending_amt = round($total + $outstanding_amt - $epf - $esi - $tds - $advance, 2);
    $grand_total = $pending_amt;

    if (empty($errors)) {
        $upd_sql = "
            UPDATE payroll SET
                division = ?,
                salary = ?,
                working_days = ?,
                absent_days = ?,
                paid_days = ?,
                per_day_salary = ?,
                total_wages = ?,
                basic = ?,
                da = ?,
                hra = ?,
                medical_allow = ?,
                conveyance_allow = ?,
                gross_salary = ?,
                epf = ?,
                esi = ?,
                travel_allow = ?,
                two_wheeler_maint = ?,
                total = ?,
                tds = ?,
                advance = ?,
                outstanding_amt = ?,
                pending_amt = ?,
                grand_total = ?
            WHERE id = ?
        ";

        $upd = $conn->prepare($upd_sql);
        if ($upd === false) {
            $errors[] = "Prepare failed: " . htmlspecialchars($conn->error);
        } else {
            // there are 1 string + 22 numeric + 1 int = 24 params (types string 's' + 22 'd' + 'i')
            $num_numeric = 22;
            $types = 's' . str_repeat('d', $num_numeric) . 'i';
            $values = [
                $division,
                $salary,
                $working_days,
                $absent_days,
                $paid_days,
                $per_day_salary,
                $total_wages,
                $basic,
                $da,
                $hra,
                $medical_allow,
                $conveyance_allow,
                $gross_salary,
                $epf,
                $esi,
                $travel_allow,
                $two_wheeler_maint,
                $total,
                $tds,
                $advance,
                $outstanding_amt,
                $pending_amt,
                $grand_total,
                $id
            ];
            if (strlen($types) !== count($values)) {
                $errors[] = "Internal error: bind types length (" . strlen($types) . ") does not match values count (" . count($values) . ").";
                $upd->close();
            } else {
                // bind dynamically
                $bind_names = [];
                $bind_names[] = $types;
                for ($i = 0; $i < count($values); $i++) {
                    $bind_names[] = &$values[$i];
                }
                call_user_func_array([$upd, 'bind_param'], $bind_names);

                if ($upd->execute()) {
                    $upd->close();
                    $query = [];
                    if (!empty($preserve_month)) $query['month'] = $preserve_month;
                    if (!empty($preserve_division)) $query['division'] = $preserve_division;
                    $query['updated'] = 1;
                    header("Location: {$redirect_base}?" . http_build_query($query));
                    exit;
                } else {
                    $errors[] = "Execute failed: " . htmlspecialchars($upd->error);
                    $upd->close();
                }
            }
        }
    }
}

// ---------- load row ----------
$id = isset($_GET['id']) ? (int)$_GET['id'] : (isset($_POST['id']) ? (int)$_POST['id'] : 0);
if ($id <= 0) {
    echo "Invalid payroll id.";
    exit;
}

$select_sql = "SELECT p.*, {$emp_code_expr}, {$name_expr}, {$basic_expr} {$extra_select_sql} FROM payroll p LEFT JOIN users u ON p.emp_id = u.id WHERE p.id = ?";
$stmt = $conn->prepare($select_sql);
if ($stmt === false) {
    die("Prepare failed: " . htmlspecialchars($conn->error) . " -- SQL: " . htmlspecialchars($select_sql));
}
$stmt->bind_param("i", $id);
$stmt->execute();
$res = $stmt->get_result();
$row = $res->fetch_assoc();
$stmt->close();

if (!$row) {
    echo "Payroll record not found.";
    exit;
}

function old_val($key, $row, $default = '') {
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && array_key_exists($key, $_POST)) return $_POST[$key];
    return $row[$key] ?? $default;
}

// Prefill form values: prefer posted values, else use user_basic_salary (if present) -> then payroll values
$form = [
    'id' => (int)$row['id'],
    'emp_id' => $row['emp_id'] ?? '',
    'emp_code' => $row['user_emp_code'] ?? ($row['emp_id'] ?? ''),
    'name' => $row['user_name'] ?? ($row['name'] ?? ''),
];

// Basic default: prefer user_basic_salary (if not empty) else payroll basic
$basic_default = null;
if (isset($row['user_basic_salary']) && $row['user_basic_salary'] !== null && $row['user_basic_salary'] !== '') {
    $ub_raw = $row['user_basic_salary'];
    $ub_sanit = preg_replace('/[^\d\.\-]/', '', (string)$ub_raw);
    $ub = $ub_sanit === '' ? 0.0 : (float)$ub_sanit;
    if ($ub > 0) $basic_default = $ub;
}
if ($basic_default === null) {
    $basic_default = $row['basic'] ?? 0;
}

// Salary default: use payroll salary if present, else basic_default
$salary_default = $row['salary'] ?? $basic_default ?? 0;

$form['division'] = old_val('division', $row, $row['division'] ?? ($row['user_division'] ?? 'Total'));
$form['salary'] = old_val('salary', $row, $salary_default);
$form['working_days'] = old_val('working_days', $row, $row['working_days'] ?? 30);
$form['absent_days'] = old_val('absent_days', $row, $row['absent_days'] ?? 0);
$form['paid_days'] = old_val('paid_days', $row, $row['paid_days'] ?? ($row['present_days'] ?? 0));
$form['basic'] = old_val('basic', $row, $basic_default);
$form['da'] = old_val('da', $row, $row['da'] ?? 0);
$form['hra'] = old_val('hra', $row, $row['hra'] ?? 0);
$form['medical_allow'] = old_val('medical_allow', $row, $row['medical_allow'] ?? 0);
$form['conveyance_allow'] = old_val('conveyance_allow', $row, $row['conveyance_allow'] ?? 0);
// epf & esi inputs will be replaced server-side on save; still prefill for display
$form['epf'] = old_val('epf', $row, $row['epf'] ?? 0);
$form['esi'] = old_val('esi', $row, $row['esi'] ?? 0);
$form['travel_allow'] = old_val('travel_allow', $row, $row['travel_allow'] ?? 0);
$form['two_wheeler_maint'] = old_val('two_wheeler_maint', $row, $row['two_wheeler_maint'] ?? 0);
$form['tds'] = old_val('tds', $row, $row['tds'] ?? 0);
$form['advance'] = old_val('advance', $row, $row['advance'] ?? 0);
$form['outstanding_amt'] = old_val('outstanding_amt', $row, $row['outstanding_amt'] ?? 0);
// pending & grand (for display only) — server authoritative on save
$form['pending_amt'] = old_val('pending_amt', $row, $row['pending_amt'] ?? 0);
$form['grand_total'] = old_val('grand_total', $row, $row['grand_total'] ?? ($row['pending_amt'] ?? 0));

// if POST had auto_calc_components, reflect it back to form (so checkbox stays checked when redisplaying)
$form['auto_calc_components'] = ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['auto_calc_components']) && $_POST['auto_calc_components']) ? true : false;

// EPF/ESI defaults from user columns (if available) or from payroll row
$user_epf_applicable = null;
$user_esi_applicable = null;

if (isset($row['user_epf_applicable'])) {
    $v = $row['user_epf_applicable'];
    $user_epf_applicable = ($v === null) ? null : (bool)($v == 1 || strtolower($v) === 'yes' || strtolower($v) === 'true');
}
if (isset($row['user_esi_applicable'])) {
    $v = $row['user_esi_applicable'];
    $user_esi_applicable = ($v === null) ? null : (bool)($v == 1 || strtolower($v) === 'yes' || strtolower($v) === 'true');
}

// Now form-specific EPF/ESI override fields: use posted if present, else user values, else fallback defaults
$form['epf_applicable'] = ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['epf_applicable'])) ? true : ( ($user_epf_applicable !== null) ? $user_epf_applicable : true );
$form['esi_applicable'] = ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['esi_applicable'])) ? true : ( ($user_esi_applicable !== null) ? $user_esi_applicable : true );

// Manual overrides defaults (reflect posted or defaults)
$form['manual_epf'] = ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['manual_epf'])) ? true : false;
$form['manual_epf_amount'] = old_val('manual_epf_amount', $row, 0.00);
$form['manual_esi'] = ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['manual_esi'])) ? true : false;
$form['manual_esi_amount'] = old_val('manual_esi_amount', $row, 0.00);

?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Edit Payroll Entry</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
<style>.container{max-width:980px} .summary-table td{padding:.35rem .5rem}</style>
</head>
<body class="bg-light">
<div class="container py-4">
    <div class="d-flex justify-content-between align-items-center mb-3">
        <h4><i class="bi bi-pencil-square"></i> Edit Payroll Entry</h4>
        <div>
            <a href="payroll.php?<?= htmlspecialchars(http_build_query(['month'=>$preserve_month,'division'=>$preserve_division])) ?>" class="btn btn-outline-secondary btn-sm">
                <i class="bi bi-arrow-left"></i> Back to Payroll
            </a>
        </div>
    </div>

    <?php if (!empty($errors)): ?>
        <div class="alert alert-danger">
            <ul class="mb-0">
                <?php foreach ($errors as $e) echo "<li>".htmlspecialchars($e)."</li>"; ?>
            </ul>
        </div>
    <?php endif; ?>

    <div class="card mb-4">
        <div class="card-body">
            <form method="post" id="payForm">
                <input type="hidden" name="id" value="<?= (int)$form['id'] ?>">
                <input type="hidden" name="month" value="<?= htmlspecialchars($preserve_month) ?>">
                <input type="hidden" name="division" value="<?= htmlspecialchars($preserve_division) ?>">
                <input type="hidden" name="save_payroll" value="1">

                <!-- Hidden copies of pending/grand for display/posting (server is authoritative) -->
                <input type="hidden" name="pending_amt" id="pending_amt_input" value="<?= htmlspecialchars($form['pending_amt']) ?>">
                <input type="hidden" name="grand_total" id="grand_total_input" value="<?= htmlspecialchars($form['grand_total']) ?>">

                <div class="row g-3">
                    <!-- Employee basic info -->
                    <div class="col-md-3">
                        <label class="form-label">Emp Code</label>
                        <input type="text" class="form-control form-control-sm" value="<?= htmlspecialchars($form['emp_code']) ?>" disabled>
                    </div>
                    <div class="col-md-5">
                        <label class="form-label">Name</label>
                        <input type="text" class="form-control form-control-sm" value="<?= htmlspecialchars($form['name']) ?>" disabled>
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Division</label>
                        <select name="division" class="form-select form-select-sm">
                            <?php
                            $divs = ['Electrical','TAB','AC-Service','Ac-Project','Automation','Admin','Directors','Total'];
                            foreach ($divs as $d) {
                                $sel = $form['division'] === $d ? 'selected' : '';
                                echo "<option value=\"" . htmlspecialchars($d) . "\" $sel>" . htmlspecialchars($d) . "</option>";
                            }
                            ?>
                        </select>
                    </div>

                    <hr class="mt-3 mb-1">

                    <!-- Attendance / salary base -->
                    <div class="col-md-4">
                        <label class="form-label">Salary (Monthly)</label>
                        <input id="salary" type="number" step="0.01" name="salary" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['salary']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Working Days</label>
                        <input id="working_days" type="number" step="0.01" name="working_days" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['working_days']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Absent Days</label>
                        <input id="absent_days" type="number" step="0.01" name="absent_days" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['absent_days']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Paid Days</label>
                        <input id="paid_days" type="number" step="0.01" name="paid_days" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['paid_days']) ?>">
                    </div>

                    <hr class="mt-3 mb-1">

                    <!-- Components auto-calc toggle -->
                    <div class="col-md-12 mb-2">
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" value="1" id="auto_calc_components" name="auto_calc_components" <?= $form['auto_calc_components'] ? 'checked' : '' ?>>
                            <label class="form-check-label" for="auto_calc_components">
                                Auto-calc components from Total Wages (Basic 40%, DA 20%, HRA 20%, Medical 10%, Conveyance 10%)
                            </label>
                        </div>
                    </div>

                    <!-- Earnings components -->
                    <div class="col-md-4">
                        <label class="form-label">Basic</label>
                        <input id="basic" type="number" step="0.01" name="basic" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['basic']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">DA</label>
                        <input id="da" type="number" step="0.01" name="da" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['da']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">HRA</label>
                        <input id="hra" type="number" step="0.01" name="hra" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['hra']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Medical Allow</label>
                        <input id="medical_allow" type="number" step="0.01" name="medical_allow" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['medical_allow']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Conveyance Allow</label>
                        <input id="conveyance_allow" type="number" step="0.01" name="conveyance_allow" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['conveyance_allow']) ?>">
                    </div>

                    <hr class="mt-3 mb-1">

                    <!-- EPF / ESI applicability -->
                    <div class="col-md-3">
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" id="epf_applicable" name="epf_applicable" value="1" <?= $form['epf_applicable'] ? 'checked' : '' ?>>
                            <label class="form-check-label" for="epf_applicable">EPF Applicable</label>
                        </div>
                    </div>

                    <div class="col-md-3">
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" id="esi_applicable" name="esi_applicable" value="1" <?= $form['esi_applicable'] ? 'checked' : '' ?>>
                            <label class="form-check-label" for="esi_applicable">ESI Applicable</label>
                        </div>
                    </div>

                    <!-- Manual override controls (EPF & ESI) -->
                    <div class="col-md-3">
                        <div class="form-check mt-2">
                            <input class="form-check-input" type="checkbox" id="manual_epf" name="manual_epf" value="1" <?= $form['manual_epf'] ? 'checked' : '' ?>>
                            <label class="form-check-label" for="manual_epf">Manual EPF Amount</label>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <label class="form-label">Manual EPF</label>
                        <input id="manual_epf_amount" name="manual_epf_amount" type="number" step="0.01" class="form-control form-control-sm calc" value="<?= htmlspecialchars(number_format((float)$form['manual_epf_amount'],2,'.','')) ?>">
                    </div>

                    <div class="col-md-3">
                        <div class="form-check mt-2">
                            <input class="form-check-input" type="checkbox" id="manual_esi" name="manual_esi" value="1" <?= $form['manual_esi'] ? 'checked' : '' ?>>
                            <label class="form-check-label" for="manual_esi">Manual ESI Amount</label>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <label class="form-label">Manual ESI</label>
                        <input id="manual_esi_amount" name="manual_esi_amount" type="number" step="0.01" class="form-control form-control-sm calc" value="<?= htmlspecialchars(number_format((float)$form['manual_esi_amount'],2,'.','')) ?>">
                    </div>

                    <!-- Outstanding Amount -->
                    <div class="col-md-3">
                        <label class="form-label">Outstanding Amount (carryforward owed to employee)</label>
                        <input id="outstanding_amt" name="outstanding_amt" type="number" step="0.01" class="form-control form-control-sm calc" value="<?= htmlspecialchars(number_format((float)$form['outstanding_amt'],2,'.','')) ?>">
                    </div>

                    <!-- EPF/ESI calculated (readonly) -->
                    <div class="col-md-4">
                        <label class="form-label">EPF (employee)</label>
                        <input id="epf" type="number" step="0.01" name="epf_display" class="form-control form-control-sm" value="<?= htmlspecialchars($form['epf']) ?>" readonly>
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">ESI (employee)</label>
                        <input id="esi" type="number" step="0.01" name="esi_display" class="form-control form-control-sm" value="<?= htmlspecialchars($form['esi']) ?>" readonly>
                    </div>

                    <!-- Other allowances / deductions -->
                    <div class="col-md-4">
                        <label class="form-label">Travel Allowance</label>
                        <input id="travel_allow" type="number" step="0.01" name="travel_allow" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['travel_allow']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Two Wheeler Maintenance</label>
                        <input id="two_wheeler_maint" type="number" step="0.01" name="two_wheeler_maint" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['two_wheeler_maint']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">TDS</label>
                        <input id="tds" type="number" step="0.01" name="tds" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['tds']) ?>">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label">Advance</label>
                        <input id="advance" type="number" step="0.01" name="advance" class="form-control form-control-sm calc" value="<?= htmlspecialchars($form['advance']) ?>">
                    </div>

                    <!-- Pending amount summary table (placed after Advance input) -->
                    <div class="col-12 mt-3">
                        <table class="table table-sm table-bordered summary-table">
                            <tbody>
                                <tr>
                                    <td><strong>Per Day Salary</strong></td>
                                    <td class="text-end" id="per_day_salary_table">0.00</td>
                                    <td><strong>Total Wages</strong></td>
                                    <td class="text-end" id="total_wages_table">0.00</td>
                                </tr>
                                <tr>
                                    <td><strong>Gross Salary</strong></td>
                                    <td class="text-end" id="gross_salary_table">0.00</td>
                                    <td><strong>Total (Gross + Other)</strong></td>
                                    <td class="text-end" id="total_table">0.00</td>
                                </tr>
                                <tr>
                                    <td><strong>EPF (Employee)</strong></td>
                                    <td class="text-end" id="epf_table">0.00</td>
                                    <td><strong>ESI (Employee)</strong></td>
                                    <td class="text-end" id="esi_table">0.00</td>
                                </tr>
                                <tr>
                                    <td><strong>TDS</strong></td>
                                    <td class="text-end" id="tds_table"><?= htmlspecialchars(number_format((float)$form['tds'],2,'.','')) ?></td>
                                    <td><strong>Advance</strong></td>
                                    <td class="text-end" id="advance_table"><?= htmlspecialchars(number_format((float)$form['advance'],2,'.','')) ?></td>
                                </tr>
                                <tr>
                                    <td><strong>Outstanding (added to payable)</strong></td>
                                    <td class="text-end" id="outstanding_table"><?= htmlspecialchars(number_format((float)$form['outstanding_amt'],2,'.','')) ?></td>
                                    <td></td><td></td>
                                </tr>
                                <tr class="table-secondary">
                                    <td><strong>Pending Amount</strong></td>
                                    <td class="text-end" id="pending_amt_table">0.00</td>
                                    <td><strong>Grand Total</strong></td>
                                    <td class="text-end" id="grand_total_table">0.00</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>

                    <!-- Inline summary text -->
                    <div class="col-12 mt-2">
                        <small class="text-muted">
                            Per Day Salary: <span id="per_day_salary_display">0.00</span> |
                            Total Wages: <span id="total_wages_display">0.00</span> |
                            Gross Salary: <span id="gross_salary_display">0.00</span> |
                            Total (Gross + other): <span id="total_display">0.00</span> |
                            TDS: <span id="tds_display"><?= htmlspecialchars(number_format((float)$form['tds'],2,'.','')) ?></span> |
                            Advance: <span id="advance_display"><?= htmlspecialchars(number_format((float)$form['advance'],2,'.','')) ?></span> |
                            Outstanding: <span id="outstanding_display"><?= htmlspecialchars(number_format((float)$form['outstanding_amt'],2,'.','')) ?></span> |
                            Pending Amt: <span id="pending_amt_display">0.00</span> |
                            Grand Total: <span id="grand_total_display">0.00</span>
                        </small>
                    </div>

                </div>

                <div class="mt-4 d-flex justify-content-between">
                    <div class="text-muted small">
                        ID: <?= (int)$form['id'] ?> &nbsp; | &nbsp; Emp: <?= htmlspecialchars($form['emp_id']) ?>
                    </div>
                    <div>
                        <a href="payroll.php?<?= htmlspecialchars(http_build_query(['month'=>$preserve_month,'division'=>$preserve_division])) ?>" class="btn btn-outline-secondary btn-sm">Cancel</a>
                        <button type="submit" class="btn btn-primary btn-sm">Save changes</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

<script>
// Live client-side preview calculator (non-authoritative; server will recalc on save)
// EPF calculation here mirrors server logic: fixed 12% of (Basic+DA+HRA) with optional cap
// Includes manual EPF/ESI override preview and Outstanding amount
// NOTE: outstanding_amt is treated as an AMOUNT OWED TO THE EMPLOYEE and is ADDED to the payable.
(function(){
    const EPF_MAX_CONTRIBUTION = 1800.00; // change to 0 or null to disable cap
    const ESI_THRESHOLD = 21000.00;

    const els = {
        salary: document.getElementById('salary'),
        working_days: document.getElementById('working_days'),
        absent_days: document.getElementById('absent_days'),
        paid_days: document.getElementById('paid_days'),
        basic: document.getElementById('basic'),
        da: document.getElementById('da'),
        hra: document.getElementById('hra'),
        medical_allow: document.getElementById('medical_allow'),
        conveyance_allow: document.getElementById('conveyance_allow'),
        travel_allow: document.getElementById('travel_allow'),
        two_wheeler_maint: document.getElementById('two_wheeler_maint'),
        tds: document.getElementById('tds'),
        advance: document.getElementById('advance'),
        outstanding_amt: document.getElementById('outstanding_amt'),
        epf: document.getElementById('epf'),
        esi: document.getElementById('esi'),
        per_day_salary_display: document.getElementById('per_day_salary_display'),
        total_wages_display: document.getElementById('total_wages_display'),
        gross_salary_display: document.getElementById('gross_salary_display'),
        total_display: document.getElementById('total_display'),
        tds_display: document.getElementById('tds_display'),
        advance_display: document.getElementById('advance_display'),
        outstanding_display: document.getElementById('outstanding_display'),
        pending_amt_display: document.getElementById('pending_amt_display'),
        grand_total_display: document.getElementById('grand_total_display'),
        auto_calc_components: document.getElementById('auto_calc_components'),
        epf_applicable: document.getElementById('epf_applicable'),
        esi_applicable: document.getElementById('esi_applicable'),
        manual_epf: document.getElementById('manual_epf'),
        manual_epf_amount: document.getElementById('manual_epf_amount'),
        manual_esi: document.getElementById('manual_esi'),
        manual_esi_amount: document.getElementById('manual_esi_amount'),
        // table elements
        per_day_salary_table: document.getElementById('per_day_salary_table'),
        total_wages_table: document.getElementById('total_wages_table'),
        gross_salary_table: document.getElementById('gross_salary_table'),
        total_table: document.getElementById('total_table'),
        epf_table: document.getElementById('epf_table'),
        esi_table: document.getElementById('esi_table'),
        tds_table: document.getElementById('tds_table'),
        advance_table: document.getElementById('advance_table'),
        outstanding_table: document.getElementById('outstanding_table'),
        pending_amt_table: document.getElementById('pending_amt_table'),
        grand_total_table: document.getElementById('grand_total_table'),
        // hidden inputs for posting (optional)
        pending_amt_input: document.getElementById('pending_amt_input'),
        grand_total_input: document.getElementById('grand_total_input')
    };

    function num(v){ v = parseFloat(v); return isNaN(v) ? 0.00 : v; }

    function computeAndDisplay(){
        const salary = num(els.salary.value);
        let working_days = num(els.working_days.value);
        const absent_days = num(els.absent_days.value);
        const paid_days = num(els.paid_days.value);

        if (working_days <= 0) {
            working_days = paid_days + absent_days;
            if (working_days <= 0) working_days = 30;
        }

        const per_day_salary = working_days > 0 ? +(salary / working_days).toFixed(2) : 0.00;
        const total_wages = +((per_day_salary * paid_days).toFixed(2));

        let basic = num(els.basic.value);
        const da_val = num(els.da.value);
        const hra_val = num(els.hra.value);
        const medical_val = num(els.medical_allow.value);
        const convey_val = num(els.conveyance_allow.value);

        // If auto-calc checkbox is checked OR basic is empty OR all others zero -> compute components from total_wages
        const shouldAutoCalc = els.auto_calc_components && els.auto_calc_components.checked;
        if (shouldAutoCalc || basic <= 0 || (da_val === 0 && hra_val === 0 && medical_val === 0 && convey_val === 0)) {
            // percentages: basic 40, da 20, hra 20, medical 10, convey 10
            let basic_calc = +(total_wages * 0.40).toFixed(2);
            let da_calc = +(total_wages * 0.20).toFixed(2);
            let hra_calc = +(total_wages * 0.20).toFixed(2);
            let medical_calc = +(total_wages * 0.10).toFixed(2);
            let convey_calc = +(total_wages * 0.10).toFixed(2);
            // rounding correction to match total_wages -> apply remainder to basic
            const sum = basic_calc + da_calc + hra_calc + medical_calc + convey_calc;
            const diff = +(total_wages - sum).toFixed(2);
            if (Math.abs(diff) >= 0.01) basic_calc = +(basic_calc + diff).toFixed(2);

            // fill inputs (visible to admin), but do not alter salary/per_day/wages
            els.basic.value = basic_calc.toFixed(2);
            els.da.value = da_calc.toFixed(2);
            els.hra.value = hra_calc.toFixed(2);
            els.medical_allow.value = medical_calc.toFixed(2);
            els.conveyance_allow.value = convey_calc.toFixed(2);

            basic = basic_calc;
        }

        const da = num(els.da.value);
        const hra = num(els.hra.value);
        const medical_allow = num(els.medical_allow.value);
        const conveyance_allow = num(els.conveyance_allow.value);
        const travel_allow = num(els.travel_allow.value);
        const two_wheeler_maint = num(els.two_wheeler_maint.value);
        const tds = num(els.tds.value);
        const advance = num(els.advance.value);
        const outstanding_amt = num(els.outstanding_amt.value);

        const gross_salary = +(basic + da + hra + medical_allow + conveyance_allow).toFixed(2);
        const total = +(gross_salary + travel_allow + two_wheeler_maint).toFixed(2);

        // client-side EPF/ESI preview (server will overwrite on save)
        const epf_enabled = !!(els.epf_applicable && els.epf_applicable.checked);
        const esi_enabled = !!(els.esi_applicable && els.esi_applicable.checked);

        // EPF % and Fixed amount removed: always use 12% on (Basic+DA+HRA)
        const epf_percent = 12.0;
        const epf_fixed = 0.0;

        // compute EPF as per rules
        let raw_epf = 0.00;
        if (epf_enabled) {
            if (epf_fixed > 0) {
                raw_epf = epf_fixed;
            } else {
                raw_epf = +((basic + da + hra) * (epf_percent / 100.0)).toFixed(2);
            }
        }

        let epf = raw_epf;
        if (EPF_MAX_CONTRIBUTION && EPF_MAX_CONTRIBUTION > 0) {
            epf = Math.min(raw_epf, EPF_MAX_CONTRIBUTION);
            epf = +epf.toFixed(2);
        }

        // compute ESI
        let esi = 0.00;
        if (esi_enabled && gross_salary <= ESI_THRESHOLD) esi = +(gross_salary * 0.0075).toFixed(2);

        // Manual overrides (client preview; server will also apply)
        const manualEpfenabled = !!(els.manual_epf && els.manual_epf.checked);
        const manualEpfAmt = num(els.manual_epf_amount ? els.manual_epf_amount.value : 0.0);
        const manualEsiEnabled = !!(els.manual_esi && els.manual_esi.checked);
        const manualEsiAmt = num(els.manual_esi_amount ? els.manual_esi_amount.value : 0.0);

        if (manualEpfenabled) {
            epf = manualEpfAmt;
        }
        if (manualEsiEnabled) {
            esi = manualEsiAmt;
        }

        // IMPORTANT CHANGE: outstanding is ADDED to total (carryforward owed)
        const pending_amt = +(total + outstanding_amt - epf - esi - tds - advance).toFixed(2);
        const grand_total = pending_amt;

        // update displays & fields
        els.per_day_salary_display.textContent = per_day_salary.toFixed(2);
        els.total_wages_display.textContent = total_wages.toFixed(2);
        els.gross_salary_display.textContent = gross_salary.toFixed(2);
        els.total_display.textContent = total.toFixed(2);
        els.pending_amt_display.textContent = pending_amt.toFixed(2);
        els.grand_total_display.textContent = grand_total.toFixed(2);
        if (els.tds_display) els.tds_display.textContent = tds.toFixed(2);
        if (els.advance_display) els.advance_display.textContent = advance.toFixed(2);
        if (els.outstanding_display) els.outstanding_display.textContent = outstanding_amt.toFixed(2);

        // update table cells
        if (els.per_day_salary_table) els.per_day_salary_table.textContent = per_day_salary.toFixed(2);
        if (els.total_wages_table) els.total_wages_table.textContent = total_wages.toFixed(2);
        if (els.gross_salary_table) els.gross_salary_table.textContent = gross_salary.toFixed(2);
        if (els.total_table) els.total_table.textContent = total.toFixed(2);
        if (els.epf_table) els.epf_table.textContent = epf.toFixed(2);
        if (els.esi_table) els.esi_table.textContent = esi.toFixed(2);
        if (els.tds_table) els.tds_table.textContent = tds.toFixed(2);
        if (els.advance_table) els.advance_table.textContent = advance.toFixed(2);
        if (els.outstanding_table) els.outstanding_table.textContent = outstanding_amt.toFixed(2);
        if (els.pending_amt_table) els.pending_amt_table.textContent = pending_amt.toFixed(2);
        if (els.grand_total_table) els.grand_total_table.textContent = grand_total.toFixed(2);

        // set read-only inputs for preview
        if (els.epf) els.epf.value = epf.toFixed(2);
        if (els.esi) els.esi.value = esi.toFixed(2);

        // update hidden inputs (optional, server will recompute on save)
        if (els.pending_amt_input) els.pending_amt_input.value = pending_amt.toFixed(2);
        if (els.grand_total_input) els.grand_total_input.value = grand_total.toFixed(2);
    }

    // bind to inputs with class 'calc'
    document.querySelectorAll('.calc').forEach(el => {
        el.addEventListener('input', computeAndDisplay);
    });
    // bind to checkboxes
    const autoChk = document.getElementById('auto_calc_components');
    if (autoChk) autoChk.addEventListener('change', computeAndDisplay);
    const epfChk = document.getElementById('epf_applicable');
    if (epfChk) epfChk.addEventListener('change', computeAndDisplay);
    const esiChk = document.getElementById('esi_applicable');
    if (esiChk) esiChk.addEventListener('change', computeAndDisplay);
    const manualEpfChk = document.getElementById('manual_epf');
    if (manualEpfChk) manualEpfChk.addEventListener('change', computeAndDisplay);
    const manualEpfAmt = document.getElementById('manual_epf_amount');
    if (manualEpfAmt) manualEpfAmt.addEventListener('input', computeAndDisplay);
    const manualEsiChk = document.getElementById('manual_esi');
    if (manualEsiChk) manualEsiChk.addEventListener('change', computeAndDisplay);
    const manualEsiAmt = document.getElementById('manual_esi_amount');
    if (manualEsiAmt) manualEsiAmt.addEventListener('input', computeAndDisplay);

    const outstandingInput = document.getElementById('outstanding_amt');
    if (outstandingInput) outstandingInput.addEventListener('input', computeAndDisplay);

    // compute initially
    computeAndDisplay();

    // ensure server-side computation on submit: server ignores posted epf/esi display fields and enforces its own calculation or manual override.
})();
</script>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
