<?php
/**
 * Payroll Management API
 * Handles salary structures, advances, payroll processing, EPF/ETF
 */

require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/db.php';

require_login();
header('Content-Type: application/json');

$mysqli = db();
$action = $_GET['action'] ?? $_POST['action'] ?? 'list';

// Permission helpers
function can_manage_payroll() {
    return has_role(['admin', 'super_admin', 'accountant', 'finance_manager']);
}

function can_view_payroll() {
    return has_role(['admin', 'super_admin', 'accountant', 'finance_manager', 'hr_manager']);
}

// Ensure schema exists
function ensure_payroll_schema($db) {
    // employee_salary_structure
    $exists = $db->query("SHOW TABLES LIKE 'employee_salary_structure'");
    if (!$exists || $exists->num_rows === 0) {
        $sql = file_get_contents(__DIR__ . '/../database/payroll_schema.sql');
        // Execute each CREATE TABLE statement separately
        $statements = array_filter(array_map('trim', explode(';', $sql)));
        foreach ($statements as $stmt) {
            if (stripos($stmt, 'CREATE TABLE') !== false) {
                @$db->query($stmt);
            }
        }
    }
    
    // Check and add missing columns to employees table
    $cols = ['epf_no', 'etf_no', 'tax_no', 'bank_name', 'bank_account', 'payment_method'];
    foreach ($cols as $col) {
        $check = $db->query("SHOW COLUMNS FROM employees LIKE '$col'");
        if (!$check || $check->num_rows === 0) {
            @$db->query("ALTER TABLE employees ADD COLUMN $col VARCHAR(100) NULL");
        }
    }
}

ensure_payroll_schema($mysqli);

// Get payroll settings
function get_payroll_setting($key, $default = null) {
    global $mysqli;
    $stmt = $mysqli->prepare("SELECT setting_value FROM payroll_settings WHERE setting_key = ?");
    $stmt->bind_param('s', $key);
    $stmt->execute();
    $res = $stmt->get_result();
    if ($row = $res->fetch_assoc()) {
        return $row['setting_value'];
    }
    return $default;
}

// Calculate EPF/ETF
function calculate_epf_etf($basic_salary, $settings = null) {
    if (!$settings) {
        $settings = [
            'epf_employee' => (float)get_payroll_setting('epf_employee_rate', 8),
            'epf_employer' => (float)get_payroll_setting('epf_employer_rate', 12),
            'etf_employer' => (float)get_payroll_setting('etf_employer_rate', 3)
        ];
    }
    
    return [
        'epf_employee' => round($basic_salary * $settings['epf_employee'] / 100, 2),
        'epf_employer' => round($basic_salary * $settings['epf_employer'] / 100, 2),
        'etf_employer' => round($basic_salary * $settings['etf_employer'] / 100, 2)
    ];
}

// Get employee salary structure
function get_employee_salary_structure($employee_id, $date = null) {
    global $mysqli;
    if (!$date) $date = date('Y-m-d');
    
    $stmt = $mysqli->prepare("SELECT * FROM employee_salary_structure 
        WHERE employee_id = ? AND effective_date <= ? AND is_active = 1 
        ORDER BY effective_date DESC LIMIT 1");
    $stmt->bind_param('is', $employee_id, $date);
    $stmt->execute();
    $res = $stmt->get_result();
    return $res->fetch_assoc();
}

// Get attendance summary for month
function get_attendance_summary($employee_id, $year, $month) {
    global $mysqli;
    $start = sprintf('%04d-%02d-01', $year, $month);
    $end = date('Y-m-t', strtotime($start));
    
    $stmt = $mysqli->prepare("SELECT 
        COUNT(*) as total_days,
        SUM(CASE WHEN status = 'present' THEN 1 ELSE 0 END) as present_days,
        SUM(CASE WHEN status = 'absent' THEN 1 ELSE 0 END) as absent_days,
        SUM(CASE WHEN status = 'half_day' THEN 0.5 ELSE 0 END) as half_days,
        SUM(CASE WHEN status = 'leave' THEN 1 ELSE 0 END) as leave_days,
        SUM(CASE WHEN status = 'holiday' THEN 1 ELSE 0 END) as holiday_days,
        COALESCE(SUM(hours_worked), 0) as total_hours,
        COALESCE(SUM(ot_minutes)/60, 0) as overtime_hours,
        COALESCE(SUM(late_minutes)/60, 0) as late_hours
        FROM employees_attendance 
        WHERE employee_id = ? AND att_date BETWEEN ? AND ?");
    $stmt->bind_param('iss', $employee_id, $start, $end);
    $stmt->execute();
    return $stmt->get_result()->fetch_assoc();
}

// Get pending advances for employee
function get_pending_advances($employee_id) {
    global $mysqli;
    $stmt = $mysqli->prepare("SELECT * FROM employee_advances 
        WHERE employee_id = ? AND status = 'approved' 
        AND (repayment_method = 'lump_sum' OR installments_paid < total_installments)
        ORDER BY advance_date ASC");
    $stmt->bind_param('i', $employee_id);
    $stmt->execute();
    $res = $stmt->get_result();
    $advances = [];
    while ($row = $res->fetch_assoc()) {
        // Calculate remaining amount
        if ($row['repayment_method'] === 'installments') {
            $row['remaining_amount'] = $row['amount'] - ($row['installments_paid'] * $row['installment_amount']);
        } else {
            $row['remaining_amount'] = $row['amount'];
        }
        $advances[] = $row;
    }
    return $advances;
}

// Get active loans for employee
function get_active_loans($employee_id) {
    global $mysqli;
    $stmt = $mysqli->prepare("SELECT * FROM employee_loans 
        WHERE employee_id = ? AND status = 'active' AND remaining_amount > 0
        ORDER BY loan_date ASC");
    $stmt->bind_param('i', $employee_id);
    $stmt->execute();
    $res = $stmt->get_result();
    $loans = [];
    while ($row = $res->fetch_assoc()) {
        $loans[] = $row;
    }
    return $loans;
}

// Get recurring deductions for employee
// For monthly payroll, pass the last day of month
function get_recurring_deductions($employee_id, $calculation_date = null) {
    global $mysqli;
    // Use provided date or default to today
    $check_date = $calculation_date ?: date('Y-m-d');
    
    // For monthly payroll calculation, we want deductions that are active
    // at ANY point during the month containing the check_date
    $month_start = date('Y-m-01', strtotime($check_date));
    $month_end = date('Y-m-t', strtotime($check_date));
    
    $stmt = $mysqli->prepare("SELECT ed.*, dt.code, dt.name, dt.is_statutory 
        FROM employee_deductions ed 
        JOIN deduction_types dt ON dt.id = ed.deduction_type_id
        WHERE ed.employee_id = ? AND ed.is_active = 1 
        AND ed.start_date <= ? AND (ed.end_date IS NULL OR ed.end_date >= ?)
        ORDER BY dt.is_statutory DESC, dt.name");
    $stmt->bind_param('iss', $employee_id, $month_end, $month_start);
    $stmt->execute();
    $res = $stmt->get_result();
    $deductions = [];
    while ($row = $res->fetch_assoc()) {
        $deductions[] = $row;
    }
    return $deductions;
}

// Calculate Overtime
function calculate_overtime($ot_hours, $basic_salary, $work_days = 22) {
    global $mysqli;
    
    // Get OT settings
    $settings = $mysqli->query("SELECT * FROM overtime_settings WHERE is_active = 1 ORDER BY effective_date DESC LIMIT 1")->fetch_assoc();
    if (!$settings) {
        $settings = ['hours_threshold' => 8, 'normal_rate' => 1, 'ot_rate' => 1.5, 'holiday_rate' => 2];
    }
    
    // Calculate hourly rate (Basic / (work_days * 8))
    $hourly_rate = $basic_salary / ($work_days * 8);
    
    // OT amount = OT hours × hourly rate × OT rate
    $ot_amount = round($ot_hours * $hourly_rate * $settings['ot_rate'], 2);
    
    return [
        'hours' => $ot_hours,
        'hourly_rate' => round($hourly_rate, 2),
        'ot_rate' => $settings['ot_rate'],
        'amount' => $ot_amount
    ];
}

// Calculate Tax (Sri Lanka PAYE)
function calculate_tax($taxable_income, $year = null) {
    global $mysqli;
    if (!$year) $year = date('Y');
    
    // Get tax slabs for the year
    $stmt = $mysqli->prepare("SELECT * FROM tax_slabs 
        WHERE effective_year = ? AND is_active = 1 
        AND min_income <= ? AND (max_income >= ? OR max_income IS NULL)
        ORDER BY min_income ASC LIMIT 1");
    $stmt->bind_param('idd', $year, $taxable_income, $taxable_income);
    $stmt->execute();
    $slab = $stmt->get_result()->fetch_assoc();
    
    if (!$slab || $slab['tax_rate'] == 0) {
        return ['tax' => 0, 'slab' => 'No Tax', 'rate' => 0, 'taxable_income' => $taxable_income];
    }
    
    // Calculate tax: (Taxable Income - Min Income) × Rate + Fixed Amount
    $excess = $taxable_income - $slab['min_income'];
    $variable_tax = round($excess * ($slab['tax_rate'] / 100), 2);
    $total_tax = $slab['fixed_amount'] + $variable_tax;
    
    return [
        'tax' => $total_tax,
        'slab' => $slab['slab_name'],
        'rate' => $slab['tax_rate'],
        'fixed_amount' => $slab['fixed_amount'],
        'variable_tax' => $variable_tax,
        'taxable_income' => $taxable_income
    ];
}

// Calculate No-Pay Deduction
function calculate_nopay_deduction($absent_days, $half_days, $basic_salary, $work_days = 22) {
    // Daily rate
    $daily_rate = $basic_salary / $work_days;
    
    // No-pay amount
    $nopay_amount = round(($absent_days * $daily_rate) + ($half_days * $daily_rate * 0.5), 2);
    
    return [
        'daily_rate' => round($daily_rate, 2),
        'absent_days' => $absent_days,
        'half_days' => $half_days,
        'amount' => $nopay_amount
    ];
}

// Only execute switch if file is called directly (not included)
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) {
switch ($action) {
    // === SALARY STRUCTURE ===
    case 'get_salary_structure':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $employee_id = (int)($_GET['employee_id'] ?? 0);
        if (!$employee_id) json_response(['message' => 'Employee ID required'], 400);
        
        $structure = get_employee_salary_structure($employee_id);
        if (!$structure) {
            // Get employee basic info
            $emp = $mysqli->query("SELECT base_salary FROM employees WHERE id = $employee_id LIMIT 1")->fetch_assoc();
            $structure = [
                'employee_id' => $employee_id,
                'basic_salary' => $emp['base_salary'] ?? 0,
                'is_daily_wage' => 0,
                'day_pay_rate' => 0
            ];
        }
        json_response(['data' => $structure]);
        break;
        
    case 'save_salary_structure':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $employee_id = (int)($_POST['employee_id'] ?? 0);
        if (!$employee_id) json_response(['message' => 'Employee ID required'], 400);
        
        $data = [
            'basic_salary' => (float)($_POST['basic_salary'] ?? 0),
            'transport_allowance' => (float)($_POST['transport_allowance'] ?? 0),
            'meal_allowance' => (float)($_POST['meal_allowance'] ?? 0),
            'other_allowance' => (float)($_POST['other_allowance'] ?? 0),
            'is_daily_wage' => isset($_POST['is_daily_wage']) ? 1 : 0,
            'day_pay_rate' => (float)($_POST['day_pay_rate'] ?? 0),
            'effective_date' => $_POST['effective_date'] ?? date('Y-m-d')
        ];
        
        // Deactivate old structure
        $mysqli->query("UPDATE employee_salary_structure SET is_active = 0 WHERE employee_id = $employee_id");
        
        // Insert new structure
        $stmt = $mysqli->prepare("INSERT INTO employee_salary_structure 
            (employee_id, effective_date, basic_salary, transport_allowance, meal_allowance, other_allowance, is_daily_wage, day_pay_rate) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param('isddddid', $employee_id, $data['effective_date'], $data['basic_salary'], 
            $data['transport_allowance'], $data['meal_allowance'], $data['other_allowance'], 
            $data['is_daily_wage'], $data['day_pay_rate']);
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        
        // Update employee base_salary
        $mysqli->query("UPDATE employees SET base_salary = {$data['basic_salary']} WHERE id = $employee_id");
        
        json_response(['message' => 'Salary structure saved']);
        break;
        
    // === ADVANCE SALARY ===
    case 'list_advances':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $employee_id = isset($_GET['employee_id']) ? (int)$_GET['employee_id'] : 0;
        $status = $_GET['status'] ?? '';
        
        $where = ' WHERE 1=1';
        $params = [];
        $types = '';
        if ($employee_id) { $where .= ' AND a.employee_id = ?'; $params[] = $employee_id; $types .= 'i'; }
        if ($status) { $where .= ' AND a.status = ?'; $params[] = $status; $types .= 's'; }
        
        $sql = "SELECT a.*, e.full_name, e.emp_code, u.username as approved_by_name 
            FROM employee_advances a 
            JOIN employees e ON e.id = a.employee_id 
            LEFT JOIN users u ON u.id = a.approved_by 
            $where ORDER BY a.advance_date DESC";
        
        if ($params) {
            $stmt = $mysqli->prepare($sql);
            $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $res = $stmt->get_result();
        } else {
            $res = $mysqli->query($sql);
        }
        
        $data = [];
        while ($row = $res->fetch_assoc()) $data[] = $row;
        json_response(['data' => $data]);
        break;
        
    case 'request_advance':
        $employee_id = (int)($_POST['employee_id'] ?? 0);
        $amount = (float)($_POST['amount'] ?? 0);
        $reason = trim($_POST['reason'] ?? '');
        $repayment_method = $_POST['repayment_method'] ?? 'lump_sum';
        $total_installments = (int)($_POST['total_installments'] ?? 1);
        
        if (!$employee_id) json_response(['message' => 'Employee required'], 400);
        if ($amount <= 0) json_response(['message' => 'Valid amount required'], 400);
        
        // Calculate installment amount
        $installment_amount = $repayment_method === 'installments' ? round($amount / $total_installments, 2) : $amount;
        
        // Start transaction
        $mysqli->begin_transaction();
        
        try {
            // Insert into master table
            $stmt = $mysqli->prepare("INSERT INTO employee_advances 
                (employee_id, advance_date, amount, reason, repayment_method, total_installments, installment_amount, status) 
                VALUES (?, CURDATE(), ?, ?, ?, ?, ?, 'pending')");
            $stmt->bind_param('idssid', $employee_id, $amount, $reason, $repayment_method, $total_installments, $installment_amount);
            
            if (!$stmt->execute()) {
                throw new Exception($stmt->error);
            }
            
            $advance_id = $stmt->insert_id;
            $user_id = $_SESSION['user']['id'] ?? null;
            
            // Insert into history table
            $histStmt = $mysqli->prepare("INSERT INTO employee_advance_history 
                (advance_id, employee_id, action, amount, reason, repayment_method, total_installments, 
                installment_amount, status, created_by, created_at) 
                VALUES (?, ?, 'created', ?, ?, ?, ?, ?, 'pending', ?, NOW())");
            $histStmt->bind_param('iidssidi', $advance_id, $employee_id, $amount, $reason, $repayment_method, $total_installments, $installment_amount, $user_id);
            
            if (!$histStmt->execute()) {
                throw new Exception($histStmt->error);
            }
            
            $mysqli->commit();
            json_response(['message' => 'Advance request submitted successfully']);
            
        } catch (Exception $e) {
            $mysqli->rollback();
            json_response(['message' => 'Error: ' . $e->getMessage()], 500);
        }
        break;
        
    case 'approve_advance':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $id = (int)($_POST['id'] ?? 0);
        $status = $_POST['status'] ?? 'approved'; // approved or rejected
        
        $user_id = $_SESSION['user']['id'] ?? null;
        
        // Get advance details for history
        $advRes = $mysqli->query("SELECT * FROM employee_advances WHERE id = $id LIMIT 1");
        $advance = $advRes->fetch_assoc();
        
        $mysqli->begin_transaction();
        try {
            // Update master table
            $stmt = $mysqli->prepare("UPDATE employee_advances SET status = ?, approved_by = ?, approved_at = NOW() WHERE id = ?");
            $stmt->bind_param('sii', $status, $user_id, $id);
            if (!$stmt->execute()) throw new Exception($stmt->error);
            
            // Record in history
            if ($advance) {
                $action = $status === 'approved' ? 'approved' : 'rejected';
                $histStmt = $mysqli->prepare("INSERT INTO employee_advance_history 
                    (advance_id, employee_id, action, amount, reason, repayment_method, total_installments, 
                    installment_amount, status, created_by, created_at) 
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())");
                $histStmt->bind_param('iisdssddsi', $id, $advance['employee_id'], $action, $advance['amount'], 
                    $advance['reason'], $advance['repayment_method'], $advance['total_installments'], 
                    $advance['installment_amount'], $status, $user_id);
                if (!$histStmt->execute()) throw new Exception($histStmt->error);
            }
            
            $mysqli->commit();
            json_response(['message' => 'Advance ' . $status]);
        } catch (Exception $e) {
            $mysqli->rollback();
            json_response(['message' => 'Error: ' . $e->getMessage()], 500);
        }
        break;
        
    // === DAY PAY MANAGEMENT ===
    case 'update_day_pay':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $employee_id = (int)($_POST['employee_id'] ?? 0);
        $new_rate = (float)($_POST['day_pay_rate'] ?? 0);
        $change_reason = trim($_POST['change_reason'] ?? '');
        $effective_date = $_POST['effective_date'] ?? date('Y-m-d');
        
        if (!$employee_id || $new_rate <= 0) json_response(['message' => 'Invalid data'], 400);
        
        // Get current rate
        $current = get_employee_salary_structure($employee_id);
        $old_rate = $current['day_pay_rate'] ?? 0;
        
        // Record history
        $user_id = $_SESSION['user']['id'] ?? null;
        $stmt = $mysqli->prepare("INSERT INTO employee_day_pay_history 
            (employee_id, old_rate, new_rate, change_reason, effective_date, changed_by) 
            VALUES (?, ?, ?, ?, ?, ?)");
        $stmt->bind_param('iddssi', $employee_id, $old_rate, $new_rate, $change_reason, $effective_date, $user_id);
        $stmt->execute();
        
        // Update salary structure
        $mysqli->query("UPDATE employee_salary_structure SET day_pay_rate = $new_rate, is_daily_wage = 1 WHERE employee_id = $employee_id");
        
        json_response(['message' => 'Day pay rate updated']);
        break;
        
    case 'get_day_pay_history':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $employee_id = (int)($_GET['employee_id'] ?? 0);
        
        $res = $mysqli->query("SELECT h.*, u.username as changed_by_name 
            FROM employee_day_pay_history h 
            LEFT JOIN users u ON u.id = h.changed_by 
            WHERE h.employee_id = $employee_id ORDER BY h.effective_date DESC");
        
        $data = [];
        while ($row = $res->fetch_assoc()) $data[] = $row;
        json_response(['data' => $data]);
        break;
        
    // === PAYROLL PROCESSING ===
    case 'calculate_payroll':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        
        $month = (int)($_GET['month'] ?? date('n'));
        $year = (int)($_GET['year'] ?? date('Y'));
        $employee_id = isset($_GET['employee_id']) ? (int)$_GET['employee_id'] : 0;
        $branch_id = isset($_GET['branch_id']) ? (int)$_GET['branch_id'] : 0;
        
        // Get employees
        $where = ' WHERE e.is_active = 1';
        if ($employee_id) $where .= " AND e.id = $employee_id";
        if ($branch_id) $where .= " AND e.branch_id = $branch_id";
        
        $emps = $mysqli->query("SELECT e.id, e.full_name, e.emp_code, e.base_salary, e.bank_name, e.bank_account FROM employees e $where");
        
        $payroll_data = [];
        while ($emp = $emps->fetch_assoc()) {
            // Get salary structure
            $structure = get_employee_salary_structure($emp['id']);
            if (!$structure) {
                $structure = ['basic_salary' => $emp['base_salary'], 'is_daily_wage' => 0, 'day_pay_rate' => 0];
            }
            
            // Get attendance
            $attendance = get_attendance_summary($emp['id'], $year, $month);
            
            // Calculate earnings
            if ($structure['is_daily_wage']) {
                $days_worked = ($attendance['present_days'] ?? 0) + ($attendance['half_days'] ?? 0);
                $total_monthly_salary = round($days_worked * $structure['day_pay_rate'], 2);
                
                // Get fixed basic salary from structure
                $fixed_basic_salary = $structure['basic_salary'] ?? 0;
                
                // Compare total monthly salary with basic salary
                if ($total_monthly_salary > $fixed_basic_salary && $fixed_basic_salary > 0) {
                    // Total exceeds basic: EPF/ETF on basic salary, rest as allowance
                    $basic = $fixed_basic_salary;
                    $allowance = round($total_monthly_salary - $fixed_basic_salary, 2);
                } else {
                    // Total <= basic: EPF/ETF on total salary, no allowance
                    $basic = $total_monthly_salary;
                    $allowance = 0;
                }
                
                $transport = 0;
                $meal = 0;
                $other = $allowance;
                $gross = $basic + $allowance;
            } else {
                $basic = $structure['basic_salary'];
                $transport = $structure['transport_allowance'] ?? 0;
                $meal = $structure['meal_allowance'] ?? 0;
                $other = $structure['other_allowance'] ?? 0;
                $gross = $basic + $transport + $meal + $other;
                // Calculate days worked including half days for tracking
                $days_worked = ($attendance['present_days'] ?? 0) + ($attendance['half_days'] ?? 0);
            }
            
            // Calculate Overtime
            $ot_hours = $attendance['overtime_hours'] ?? 0;
            $ot_calculation = calculate_overtime($ot_hours, $basic);
            $ot_amount = $ot_calculation['amount'];
            
            // Total gross with OT
            $total_gross = $gross + $ot_amount;
            
            // Calculate No-Pay Deduction
            $absent_days = $attendance['absent_days'] ?? 0;
            $half_days = $attendance['half_days'] ?? 0;
            $nopay_calc = calculate_nopay_deduction($absent_days, $half_days, $basic);
            $nopay_deduction = $nopay_calc['amount'];
            
            // Taxable income (after no-pay deduction)
            $taxable_income = max(0, $total_gross - $nopay_deduction);
            
            // Calculate Tax (PAYE)
            $tax_calc = calculate_tax($taxable_income, $year);
            $tax_deduction = $tax_calc['tax'];
            
            // Calculate EPF/ETF (on basic salary - already set correctly above)
            $epf_etf = calculate_epf_etf($basic);
            
            // Get pending advances
            $advances = get_pending_advances($emp['id']);
            $advance_deduction = 0;
            foreach ($advances as $adv) {
                if ($adv['repayment_method'] === 'lump_sum') {
                    $advance_deduction += $adv['remaining_amount'];
                } else {
                    $advance_deduction += min($adv['installment_amount'], $adv['remaining_amount']);
                }
            }
            
            // Get active loans
            $loans = get_active_loans($emp['id']);
            $loan_deduction = 0;
            foreach ($loans as $loan) {
                $loan_deduction += $loan['monthly_installment'];
            }
            
            // Get recurring deductions for specific payroll month (use last day of month)
            $last_day = date("Y-m-t", strtotime("$year-$month-01"));
            $recurring_deductions = get_recurring_deductions($emp['id'], $last_day);
            $recurring_total = 0;
            $deduction_details = []; // Track individual deductions
            foreach ($recurring_deductions as $ded) {
                if (!in_array($ded['code'], ['EPF', 'TAX', 'NOPAY', 'SALARY_ADV', 'LOAN'])) {
                    $recurring_total += $ded['amount'];
                    $deduction_details[] = [
                        'type' => $ded['name'],
                        'code' => $ded['code'],
                        'amount' => $ded['amount']
                    ];
                }
            }
            
            // Total deductions
            $total_deductions = $epf_etf['epf_employee'] + $tax_deduction + $nopay_deduction + 
                               $advance_deduction + $loan_deduction + $recurring_total;
            
            // Net salary
            $net = $total_gross - $total_deductions;
            
            $payroll_data[] = [
                'employee_id' => $emp['id'],
                'emp_code' => $emp['emp_code'],
                'full_name' => $emp['full_name'],
                'bank_name' => $emp['bank_name'],
                'bank_account' => $emp['bank_account'],
                'basic_salary' => $basic,
                'transport' => $transport,
                'meal' => $meal,
                'other' => $other,
                'allowance' => $allowance ?? 0,
                'gross_salary' => $gross,
                'overtime_hours' => $ot_hours,
                'overtime_amount' => $ot_amount,
                'total_gross' => $total_gross,
                'taxable_income' => $taxable_income,
                'tax_deduction' => $tax_deduction,
                'tax_slab' => $tax_calc['slab'],
                'tax_rate' => $tax_calc['rate'],
                'epf_employee' => $epf_etf['epf_employee'],
                'epf_employer' => $epf_etf['epf_employer'],
                'etf_employer' => $epf_etf['etf_employer'],
                'nopay_deduction' => $nopay_deduction,
                'advance_deduction' => $advance_deduction,
                'loan_deduction' => $loan_deduction,
                'recurring_deductions' => $recurring_total,
                'total_deductions' => $total_deductions,
                'net_salary' => $net,
                'days_worked' => $days_worked ?? ($attendance['present_days'] + $attendance['half_days'] ?? 0),
                'attendance' => $attendance,
                'advances' => $advances,
                'loans' => $loans,
                'recurring_list' => $recurring_deductions
            ];
        }
        
        json_response(['data' => $payroll_data, 'month' => $month, 'year' => $year]);
        break;
        
    case 'process_payroll':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $month = (int)($_POST['month'] ?? date('n'));
        $year = (int)($_POST['year'] ?? date('Y'));
        $payroll_data = json_decode($_POST['payroll_data'] ?? '[]', true);
        
        $mysqli->begin_transaction();
        try {
            foreach ($payroll_data as $emp) {
                $employee_id = $emp['employee_id'];
                
                // Check if record exists
                $check = $mysqli->prepare("SELECT id FROM payroll_records 
                    WHERE employee_id = ? AND payroll_year = ? AND payroll_month = ?");
                $check->bind_param('iii', $employee_id, $year, $month);
                $check->execute();
                $existing = $check->get_result()->fetch_assoc();
                
                $att = $emp['attendance'] ?? [];
                
                if ($existing) {
                    // Update
                    $stmt = $mysqli->prepare("UPDATE payroll_records SET 
                        present_days = ?, absent_days = ?, half_days = ?, leave_days = ?, days_worked = ?,
                        basic_salary = ?, gross_salary = ?, epf_employee = ?, epf_employer = ?, etf_employer = ?,
                        advance_deduction = ?, net_salary = ?, updated_at = NOW()
                        WHERE id = ?");
                    $stmt->bind_param('iiiiidddddddi',
                        $att['present_days'], $att['absent_days'], $att['half_days'], $att['leave_days'], $emp['days_worked'] ?? ($att['present_days'] + $att['half_days']),
                        $emp['basic_salary'], $emp['gross_salary'], $emp['epf_employee'], $emp['epf_employer'], $emp['etf_employer'],
                        $emp['advance_deduction'], $emp['net_salary'], $existing['id']
                    );
                } else {
                    // Insert
                    $stmt = $mysqli->prepare("INSERT INTO payroll_records 
                        (employee_id, payroll_month, payroll_year, present_days, absent_days, half_days, leave_days, days_worked,
                        basic_salary, gross_salary, epf_employee, epf_employer, etf_employer, advance_deduction, net_salary)
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
                    $days_worked = $emp['days_worked'] ?? ($att['present_days'] + $att['half_days']);
                    $stmt->bind_param('iiiiiiidddddddd',
                        $employee_id, $month, $year,
                        $att['present_days'], $att['absent_days'], $att['half_days'], $att['leave_days'], $days_worked,
                        $emp['basic_salary'], $emp['gross_salary'], $emp['epf_employee'], $emp['epf_employer'], $emp['etf_employer'],
                        $emp['advance_deduction'], $emp['net_salary']
                    );
                }
                $stmt->execute();
                $payroll_id = $existing ? $existing['id'] : $mysqli->insert_id;
                
                // Link advance deductions
                foreach ($emp['advances'] ?? [] as $adv) {
                    $deduct_amount = $adv['repayment_method'] === 'lump_sum' 
                        ? $adv['remaining_amount'] 
                        : min($adv['installment_amount'], $adv['remaining_amount']);
                    
                    $mysqli->query("INSERT INTO payroll_advance_deductions (payroll_id, advance_id, amount_deducted) 
                        VALUES ($payroll_id, {$adv['id']}, $deduct_amount)");
                    
                    // Update advance record
                    if ($adv['repayment_method'] === 'installments') {
                        $mysqli->query("UPDATE employee_advances SET installments_paid = installments_paid + 1 
                            WHERE id = {$adv['id']}");
                    } else {
                        $mysqli->query("UPDATE employee_advances SET status = 'repaid' WHERE id = {$adv['id']}");
                    }
                }
            }
            
            $mysqli->commit();
            json_response(['message' => 'Payroll processed successfully']);
        } catch (Exception $e) {
            $mysqli->rollback();
            json_response(['message' => 'Error: ' . $e->getMessage()], 500);
        }
        break;
        
    case 'list_payroll':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        
        $month = (int)($_GET['month'] ?? date('n'));
        $year = (int)($_GET['year'] ?? date('Y'));
        $status = $_GET['status'] ?? '';
        
        $where = ' WHERE p.payroll_year = ? AND p.payroll_month = ?';
        $params = [$year, $month];
        $types = 'ii';
        
        if ($status) { $where .= ' AND p.payment_status = ?'; $params[] = $status; $types .= 's'; }
        
        $sql = "SELECT p.*, e.full_name, e.emp_code 
            FROM payroll_records p 
            JOIN employees e ON e.id = p.employee_id 
            $where ORDER BY e.emp_code";
        
        $stmt = $mysqli->prepare($sql);
        $stmt->bind_param($types, ...$params);
        $stmt->execute();
        $res = $stmt->get_result();
        
        $data = [];
        while ($row = $res->fetch_assoc()) $data[] = $row;
        json_response(['data' => $data, 'month' => $month, 'year' => $year]);
        break;
        
    case 'get_payroll_history':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        
        $month = (int)($_GET['month'] ?? 0);
        $year = (int)($_GET['year'] ?? 0);
        
        $where = ' WHERE 1=1';
        $params = [];
        $types = '';
        
        if ($month) { $where .= ' AND p.payroll_month = ?'; $params[] = $month; $types .= 'i'; }
        if ($year) { $where .= ' AND p.payroll_year = ?'; $params[] = $year; $types .= 'i'; }
        
        $sql = "SELECT p.*, e.full_name as employee_name, e.emp_code, e.designation, b.name as branch_name, p.created_at
            FROM payroll_records p 
            JOIN employees e ON e.id = p.employee_id 
            LEFT JOIN branches b ON b.id = e.branch_id 
            $where ORDER BY p.payroll_year DESC, p.payroll_month DESC, e.emp_code";
        
        if ($params) {
            $stmt = $mysqli->prepare($sql);
            $stmt->bind_param($types, ...$params);
            $stmt->execute();
            $res = $stmt->get_result();
        } else {
            $res = $mysqli->query($sql);
        }
        
        $data = [];
        while ($row = $res->fetch_assoc()) $data[] = $row;
        json_response(['data' => $data]);
        break;
        
    case 'get_payslip_details':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        
        $payroll_id = (int)($_GET['payroll_id'] ?? 0);
        if (!$payroll_id) json_response(['message' => 'Payroll ID required'], 400);
        
        $sql = "SELECT p.*, e.full_name as employee_name, e.emp_code, e.designation, b.name as branch_name, p.created_at
            FROM payroll_records p 
            JOIN employees e ON e.id = p.employee_id 
            LEFT JOIN branches b ON b.id = e.branch_id 
            WHERE p.id = ?";
        
        $stmt = $mysqli->prepare($sql);
        $stmt->bind_param('i', $payroll_id);
        $stmt->execute();
        $res = $stmt->get_result();
        $data = $res->fetch_assoc();
        
        if (!$data) json_response(['message' => 'Payroll record not found'], 404);
        
        json_response(['data' => $data]);
        break;
        
    case 'get_payslip':
        $payroll_id = (int)($_GET['id'] ?? 0);
        if (!$payroll_id) json_response(['message' => 'Payroll ID required'], 400);
        
        $res = $mysqli->query("SELECT p.*, e.full_name, e.emp_code, e.designation 
            FROM payroll_records p 
            JOIN employees e ON e.id = p.employee_id 
            WHERE p.id = $payroll_id");
        $payroll = $res->fetch_assoc();
        
        if (!$payroll) json_response(['message' => 'Not found'], 404);
        
        // Get advance deductions
        $advances = [];
        $adv_res = $mysqli->query("SELECT pad.*, a.advance_date, a.reason 
            FROM payroll_advance_deductions pad 
            JOIN employee_advances a ON a.id = pad.advance_id 
            WHERE pad.payroll_id = $payroll_id");
        while ($a = $adv_res->fetch_assoc()) $advances[] = $a;
        
        $payroll['advances'] = $advances;
        json_response(['data' => $payroll]);
        break;
        
    case 'mark_paid':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $id = (int)($_POST['id'] ?? 0);
        $payment_method = $_POST['payment_method'] ?? 'bank_transfer';
        $payment_reference = trim($_POST['payment_reference'] ?? '');
        $paid_by = $_SESSION['user']['id'] ?? null;
        
        $stmt = $mysqli->prepare("UPDATE payroll_records 
            SET payment_status = 'paid', paid_date = CURDATE(), paid_by = ?, payment_method = ?, payment_reference = ? 
            WHERE id = ?");
        $stmt->bind_param('issi', $paid_by, $payment_method, $payment_reference, $id);
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        json_response(['message' => 'Payment recorded']);
        break;
        
    case 'get_settings':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $res = $mysqli->query("SELECT * FROM payroll_settings");
        $settings = [];
        while ($row = $res->fetch_assoc()) $settings[$row['setting_key']] = $row['setting_value'];
        json_response(['data' => $settings]);
        break;
        
    case 'save_settings':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        foreach ($_POST['settings'] ?? [] as $key => $value) {
            $stmt = $mysqli->prepare("INSERT INTO payroll_settings (setting_key, setting_value) VALUES (?, ?) 
                ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)");
            $stmt->bind_param('ss', $key, $value);
            $stmt->execute();
        }
        json_response(['message' => 'Settings saved']);
        break;
        
    // === LOAN MANAGEMENT ===
    case 'list_loans':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $employee_id = isset($_GET['employee_id']) ? (int)$_GET['employee_id'] : 0;
        
        $where = $employee_id ? "WHERE l.employee_id = $employee_id" : '';
        $res = $mysqli->query("SELECT l.*, e.full_name, e.emp_code 
            FROM employee_loans l 
            JOIN employees e ON e.id = l.employee_id 
            $where ORDER BY l.loan_date DESC");
        
        $data = [];
        while ($row = $res->fetch_assoc()) $data[] = $row;
        json_response(['data' => $data]);
        break;
        
    case 'create_loan':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $employee_id = (int)($_POST['employee_id'] ?? 0);
        $loan_amount = (float)($_POST['loan_amount'] ?? 0);
        $interest_rate = (float)($_POST['interest_rate'] ?? 0);
        $total_installments = (int)($_POST['total_installments'] ?? 1);
        $purpose = trim($_POST['purpose'] ?? '');
        
        // Calculate monthly installment
        $total_payable = $loan_amount * (1 + ($interest_rate / 100));
        $monthly_installment = round($total_payable / $total_installments, 2);
        
        $approved_by = $_SESSION['user']['id'] ?? null;
        $stmt = $mysqli->prepare("INSERT INTO employee_loans 
            (employee_id, loan_date, loan_amount, interest_rate, total_payable, monthly_installment, total_installments, remaining_amount, purpose, approved_by) 
            VALUES (?, CURDATE(), ?, ?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param('iddddidsi', $employee_id, $loan_amount, $interest_rate, $total_payable, $monthly_installment, $total_installments, $total_payable, $purpose, $approved_by);
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        json_response(['message' => 'Loan created successfully']);
        break;
        
    case 'close_loan':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $loan_id = (int)($_POST['loan_id'] ?? 0);
        if (!$loan_id) json_response(['message' => 'Loan ID required'], 400);
        
        // Update loan status to completed and clear remaining amount
        $stmt = $mysqli->prepare("UPDATE employee_loans SET status = 'completed', remaining_amount = 0 WHERE id = ?");
        $stmt->bind_param('i', $loan_id);
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        json_response(['message' => 'Loan closed successfully']);
        break;
        
    // === DEDUCTION MANAGEMENT ===
    case 'list_deductions':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $employee_id = isset($_GET['employee_id']) ? (int)$_GET['employee_id'] : 0;
        $month = $_GET['month'] ?? ''; // Format: YYYY-MM
        
        $conditions = [];
        if ($employee_id) $conditions[] = "ed.employee_id = $employee_id";
        
        // Filter by month - show only deductions applicable to that month
        if ($month && preg_match('/^\d{4}-\d{2}$/', $month)) {
            $year = (int)substr($month, 0, 4);
            $mon = (int)substr($month, 5, 2);
            $firstDay = sprintf("%04d-%02d-01", $year, $mon);
            $lastDay = date("Y-m-t", strtotime($firstDay));
            
            // Deduction applies if:
            // - start_date <= last_day_of_month AND
            // - (end_date IS NULL OR end_date >= first_day_of_month)
            $conditions[] = "ed.start_date <= '$lastDay'";
            $conditions[] = "(ed.end_date IS NULL OR ed.end_date >= '$firstDay')";
            $conditions[] = "ed.is_active = 1";
        }
        
        $where = $conditions ? 'WHERE ' . implode(' AND ', $conditions) : '';
        $res = $mysqli->query("SELECT ed.*, e.full_name, e.emp_code, dt.name as deduction_name, dt.code 
            FROM employee_deductions ed 
            JOIN employees e ON e.id = ed.employee_id 
            JOIN deduction_types dt ON dt.id = ed.deduction_type_id 
            $where ORDER BY ed.start_date DESC");
        
        $data = [];
        while ($row = $res->fetch_assoc()) $data[] = $row;
        json_response(['data' => $data]);
        break;
        
    case 'list_deduction_types':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $res = $mysqli->query("SELECT * FROM deduction_types WHERE is_active = 1 ORDER BY name");
        $data = [];
        while ($row = $res->fetch_assoc()) $data[] = $row;
        json_response(['data' => $data]);
        break;
        
    case 'create_deduction':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $employee_id = (int)($_POST['employee_id'] ?? 0);
        $deduction_type_id = (int)($_POST['deduction_type_id'] ?? 0);
        $amount = (float)($_POST['amount'] ?? 0);
        $start_date = $_POST['start_date'] ?? date('Y-m-d');
        $end_date = ($_POST['end_date'] ?? '') !== '' ? $_POST['end_date'] : null;
        $reference_no = trim($_POST['reference_no'] ?? '');
        $remarks = trim($_POST['remarks'] ?? '');
        
        $stmt = $mysqli->prepare("INSERT INTO employee_deductions 
            (employee_id, deduction_type_id, amount, start_date, end_date, reference_no, remarks) 
            VALUES (?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param('iidssss', $employee_id, $deduction_type_id, $amount, $start_date, $end_date, $reference_no, $remarks);
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        json_response(['message' => 'Deduction added successfully']);
        break;
        
    case 'get_deduction':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $id = (int)($_GET['id'] ?? 0);
        if (!$id) json_response(['message' => 'Missing id'], 400);
        
        $stmt = $mysqli->prepare("SELECT ed.*, e.full_name, e.emp_code, dt.name as deduction_name 
            FROM employee_deductions ed 
            JOIN employees e ON e.id = ed.employee_id 
            JOIN deduction_types dt ON dt.id = ed.deduction_type_id 
            WHERE ed.id = ? LIMIT 1");
        $stmt->bind_param('i', $id);
        $stmt->execute();
        $result = $stmt->get_result();
        $data = $result->fetch_assoc();
        if (!$data) json_response(['message' => 'Deduction not found'], 404);
        json_response(['data' => $data]);
        break;
        
    case 'update_deduction':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $id = (int)($_POST['id'] ?? 0);
        if (!$id) json_response(['message' => 'Missing id'], 400);
        
        $employee_id = (int)($_POST['employee_id'] ?? 0);
        $deduction_type_id = (int)($_POST['deduction_type_id'] ?? 0);
        $amount = (float)($_POST['amount'] ?? 0);
        $start_date = $_POST['start_date'] ?? date('Y-m-d');
        $end_date = ($_POST['end_date'] ?? '') !== '' ? $_POST['end_date'] : null;
        $reference_no = trim($_POST['reference_no'] ?? '');
        $remarks = trim($_POST['remarks'] ?? '');
        $is_active = (int)($_POST['is_active'] ?? 1);
        
        $stmt = $mysqli->prepare("UPDATE employee_deductions 
            SET employee_id=?, deduction_type_id=?, amount=?, start_date=?, end_date=?, reference_no=?, remarks=?, is_active=? 
            WHERE id=?");
        $stmt->bind_param('iiddssiii', $employee_id, $deduction_type_id, $amount, $start_date, $end_date, $reference_no, $remarks, $is_active, $id);
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        json_response(['message' => 'Deduction updated successfully']);
        break;
        
    case 'delete_deduction':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $id = (int)($_POST['id'] ?? 0);
        if (!$id) json_response(['message' => 'Missing id'], 400);
        
        $stmt = $mysqli->prepare("DELETE FROM employee_deductions WHERE id=?");
        $stmt->bind_param('i', $id);
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        json_response(['message' => 'Deduction deleted successfully']);
        break;
        
    // === OT & TAX SETTINGS ===
    case 'get_overtime_settings':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $res = $mysqli->query("SELECT * FROM overtime_settings WHERE is_active = 1 ORDER BY effective_date DESC LIMIT 1");
        $settings = $res->fetch_assoc();
        json_response(['data' => $settings]);
        break;
        
    case 'save_overtime_settings':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $hours_threshold = (float)($_POST['hours_threshold'] ?? 8);
        $normal_rate = (float)($_POST['normal_rate'] ?? 1);
        $ot_rate = (float)($_POST['ot_rate'] ?? 1.5);
        $holiday_rate = (float)($_POST['holiday_rate'] ?? 2);
        
        $stmt = $mysqli->prepare("INSERT INTO overtime_settings 
            (hours_threshold, normal_rate, ot_rate, holiday_rate, effective_date) 
            VALUES (?, ?, ?, ?, CURDATE())");
        $stmt->bind_param('dddd', $hours_threshold, $normal_rate, $ot_rate, $holiday_rate);
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        json_response(['message' => 'Overtime settings saved']);
        break;
        
    case 'get_tax_slabs':
        if (!can_view_payroll()) json_response(['message' => 'Access denied'], 403);
        $year = (int)($_GET['year'] ?? date('Y'));
        $res = $mysqli->query("SELECT * FROM tax_slabs WHERE effective_year = $year AND is_active = 1 ORDER BY min_income");
        $data = [];
        while ($row = $res->fetch_assoc()) $data[] = $row;
        json_response(['data' => $data, 'year' => $year]);
        break;
        
    case 'save_tax_slab':
        if (!can_manage_payroll()) json_response(['message' => 'Access denied'], 403);
        if (!validate_csrf($_POST['csrf'] ?? '')) json_response(['message' => 'Invalid CSRF'], 400);
        
        $slab_name = trim($_POST['slab_name'] ?? '');
        $min_income = (float)($_POST['min_income'] ?? 0);
        $max_income = ($_POST['max_income'] ?? '') !== '' ? (float)$_POST['max_income'] : null;
        $tax_rate = (float)($_POST['tax_rate'] ?? 0);
        $fixed_amount = (float)($_POST['fixed_amount'] ?? 0);
        $effective_year = (int)($_POST['effective_year'] ?? date('Y'));
        
        $stmt = $mysqli->prepare("INSERT INTO tax_slabs 
            (slab_name, min_income, max_income, tax_rate, fixed_amount, effective_year) 
            VALUES (?, ?, ?, ?, ?, ?)");
        if ($max_income === null) {
            $stmt->bind_param('sdddii', $slab_name, $min_income, $max_income, $tax_rate, $fixed_amount, $effective_year);
        } else {
            $stmt->bind_param('sdddii', $slab_name, $min_income, $max_income, $tax_rate, $fixed_amount, $effective_year);
        }
        
        if (!$stmt->execute()) json_response(['message' => $stmt->error], 500);
        json_response(['message' => 'Tax slab added']);
        break;
        
    default:
        json_response(['message' => 'Invalid action'], 400);
}
}
