<?php
// =========================================================================
// ENTERPRISE MEDICATION CALCULATION ENGINE
// Decouples Clinical Dosing from Physical Inventory Multipliers
// =========================================================================
session_start();
ini_set('display_errors', 0);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
ob_start();

require_once '../../includes/db.php';
header('Content-Type: application/json');

$staff_id = (int)($_SESSION['staff_id'] ?? 1);
$action = $_POST['action'] ?? $_GET['action'] ?? '';

try {
    // ---------------------------------------------------------
    // 1. FETCH DEPENDENCIES (FOR DROPDOWNS)
    // ---------------------------------------------------------
    if ($action === 'fetch_dependencies') {
        $data = ['modes' => [], 'formulas' => [], 'rounding' => []];
        
        $qM = $conn->query("SELECT * FROM med_calc_modes"); 
        if($qM) while($r = $qM->fetch_assoc()) $data['modes'][] = $r;
        
        $qF = $conn->query("SELECT * FROM med_calc_formulas"); 
        if($qF) while($r = $qF->fetch_assoc()) $data['formulas'][] = $r;
        
        $qR = $conn->query("SELECT * FROM med_calc_rounding_rules"); 
        if($qR) while($r = $qR->fetch_assoc()) $data['rounding'][] = $r;
        
        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $data]); exit;
    }

    // ---------------------------------------------------------
    // 2. DATATABLES FETCH: CALCULATION RULES
    // ---------------------------------------------------------
    if ($action === 'fetch_calc_rules') {
        $sql = "SELECT r.*, m.mode_name, f.formula_name, f.math_expression, rnd.rule_name as rounding_name 
                FROM med_calc_rules r 
                JOIN med_calc_modes m ON r.mode_id = m.id 
                JOIN med_calc_formulas f ON r.formula_id = f.id 
                JOIN med_calc_rounding_rules rnd ON r.rounding_id = rnd.id 
                ORDER BY r.id ASC";
        $res = $conn->query($sql);
        $data = [];
        if ($res) while ($row = $res->fetch_assoc()) $data[] = $row;
        
        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $data]); exit;
    }

    // ---------------------------------------------------------
    // 3. DATATABLES FETCH: DRUG FREQUENCIES
    // ---------------------------------------------------------
    if ($action === 'fetch_frequencies') {
        $sql = "SELECT * FROM drug_frequency ORDER BY multiplier DESC, freq_code ASC";
        $res = $conn->query($sql);
        $data = [];
        if ($res) while ($row = $res->fetch_assoc()) $data[] = $row;
        
        ob_end_clean(); echo json_encode(['status' => 'success', 'data' => $data]); exit;
    }

    // ---------------------------------------------------------
    // 4. SAVE / UPDATE CALCULATION RULE
    // ---------------------------------------------------------
    if ($action === 'save_rule') {
        $id = (int)($_POST['rule_id'] ?? 0);
        $name = trim($_POST['rule_name']);
        $mode = (int)$_POST['mode_id'];
        $formula = (int)$_POST['formula_id'];
        $round = (int)$_POST['rounding_id'];
        $unit = trim($_POST['base_inventory_unit']);

        if (!$name || !$mode || !$formula || !$round) throw new Exception("All rule configuration parameters are required.");

        if ($id > 0) {
            $stmt = $conn->prepare("UPDATE med_calc_rules SET rule_name=?, mode_id=?, formula_id=?, rounding_id=?, base_inventory_unit=? WHERE id=?");
            $stmt->bind_param("siiisi", $name, $mode, $formula, $round, $unit, $id);
        } else {
            $stmt = $conn->prepare("INSERT INTO med_calc_rules (rule_name, mode_id, formula_id, rounding_id, base_inventory_unit) VALUES (?, ?, ?, ?, ?)");
            $stmt->bind_param("siiis", $name, $mode, $formula, $round, $unit);
        }
        $stmt->execute();
        
        ob_end_clean(); echo json_encode(['status' => 'success', 'message' => 'Medication Calculation Rule saved successfully.']); exit;
    }

    // ---------------------------------------------------------
    // 5. SAVE / UPDATE FREQUENCY MULTIPLIER
    // ---------------------------------------------------------
    if ($action === 'save_freq') {
        $id = (int)($_POST['freq_id'] ?? 0);
        $code = strtoupper(trim($_POST['freq_code']));
        $desc = trim($_POST['description']);
        $mult = (float)$_POST['multiplier'];

        if (!$code || !$desc) throw new Exception("Code and description are required.");

        if ($id > 0) {
            $stmt = $conn->prepare("UPDATE drug_frequency SET freq_code=?, description=?, multiplier=? WHERE id=?");
            $stmt->bind_param("ssdi", $code, $desc, $mult, $id);
        } else {
            $stmt = $conn->prepare("INSERT INTO drug_frequency (freq_code, description, multiplier) VALUES (?, ?, ?)");
            $stmt->bind_param("ssd", $code, $desc, $mult);
        }
        $stmt->execute();
        
        ob_end_clean(); echo json_encode(['status' => 'success', 'message' => 'Frequency Multiplier updated successfully.']); exit;
    }

    // ---------------------------------------------------------
    // 6. SANDBOX: TEST ENGINE ALGORITHM (SAFE EVAL MATH)
    // ---------------------------------------------------------
    if ($action === 'test_engine') {
        $rule_id = (int)$_POST['test_rule_id'];
        $dose = (float)$_POST['test_dose'];
        $strength = (float)$_POST['test_strength'];
        $freq_mult = (float)$_POST['test_freq'];
        $duration = (float)$_POST['test_duration'];
        $pack_size = (float)($_POST['test_pack_size'] ?? 1);

        if (!$rule_id) throw new Exception("Please select a calculation rule.");
        if ($strength <= 0) $strength = 1; // Prevent Div/0
        if ($pack_size <= 0) $pack_size = 1; // Prevent Div/0

        $sql = "SELECT r.*, m.mode_name, f.math_expression, rnd.php_logic 
                FROM med_calc_rules r 
                JOIN med_calc_modes m ON r.mode_id = m.id 
                JOIN med_calc_formulas f ON r.formula_id = f.id 
                JOIN med_calc_rounding_rules rnd ON r.rounding_id = rnd.id 
                WHERE r.id = $rule_id";
        $rule = $conn->query($sql)->fetch_assoc();

        if (!$rule) throw new Exception("Calculation rule not found.");

        // 1. Math Substitution
        $math = $rule['math_expression'];
        $eval_string = str_replace(
            ['[DOSE]', '[STRENGTH]', '[FREQ_MULT]', '[DURATION_DAYS]', '[PACK_SIZE]'], 
            [$dose, $strength, $freq_mult, $duration, $pack_size], 
            $math
        );

        // 2. Evaluate Expression Safely
        try {
            $calc_raw = 0;
            // The string must be evaluated as a return statement in PHP
            $calc_raw = eval("return ($eval_string);");
        } catch (Throwable $e) {
            throw new Exception("Mathematical evaluation error. Please check formula syntax.");
        }

        // 3. Apply Rounding Logic
        $final_qty = $calc_raw;
        $logic = $rule['php_logic'];

        if ($logic === 'CEIL') $final_qty = ceil($calc_raw);
        elseif ($logic === 'FLOOR') $final_qty = floor($calc_raw);
        elseif ($logic === 'ROUND') $final_qty = round($calc_raw);
        elseif ($logic === 'HALF') $final_qty = ceil($calc_raw * 2) / 2;
        elseif ($logic === 'QUARTER') $final_qty = ceil($calc_raw * 4) / 4;

        // Force a minimum of 1 if the calculation yields less than 1 (unless it's EXACT decimal)
        if ($final_qty < 1 && $calc_raw > 0 && $logic !== 'EXACT') {
            $final_qty = 1;
        }

        ob_end_clean();
        echo json_encode([
            'status' => 'success', 
            'expression' => $eval_string,
            'raw_result' => round($calc_raw, 4),
            'final_dispense_qty' => $final_qty,
            'unit' => $rule['base_inventory_unit'],
            'mode' => $rule['mode_name']
        ]);
        exit;
    }

} catch (Exception $e) {
    ob_end_clean(); echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); exit;
}
?>