<?php
// CRITICAL: Suppress warnings from breaking JSON headers
error_reporting(0);
ini_set('display_errors', 0);

ob_start();
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

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

function outputJSON($data) {
    if (ob_get_length()) { ob_clean(); }
    echo json_encode($data);
    exit;
}

try {
    // =====================================
    // AUTO-HEALING DATABASE PROTOCOL
    // =====================================
    
    // 1. Ensure Service Types Table Exists
    $conn->query("CREATE TABLE IF NOT EXISTS `ipd_setup_service_types` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `type_name` varchar(150) NOT NULL,
      `is_active` tinyint(1) DEFAULT 1,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
    
    $chkType = $conn->query("SELECT id FROM ipd_setup_service_types LIMIT 1");
    if($chkType && $chkType->num_rows == 0) {
        $conn->query("INSERT INTO ipd_setup_service_types (type_name) VALUES ('Point of Care Test'), ('Ward Procedure'), ('Nursing Service'), ('Accommodation')");
    }

    // 2. Ensure Clinical Outcomes Table Exists
    $conn->query("CREATE TABLE IF NOT EXISTS `ipd_setup_round_outcomes` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `outcome_name` varchar(150) NOT NULL,
      `triggers_action` varchar(50) DEFAULT NULL,
      `is_active` tinyint(1) DEFAULT 1,
      PRIMARY KEY (`id`),
      UNIQUE KEY `idx_outcome_name_uniq` (`outcome_name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");

    $chkOut = $conn->query("SELECT id FROM ipd_setup_round_outcomes LIMIT 1");
    if($chkOut && $chkOut->num_rows == 0) {
        $conn->query("INSERT IGNORE INTO `ipd_setup_round_outcomes` (`outcome_name`, `triggers_action`, `is_active`) VALUES 
        ('Discharge Satisfactory', 'direct_discharge', 1),
        ('Recommended for Discharge', 'pending_discharge', 1),
        ('Transfer Out', 'transfer_workflow', 1),
        ('Refer Out to External Facility', 'pending_discharge', 1),
        ('Remain on Ward for Subsequent Review', 'remain_ward', 1)");
    }

    // 3. Ensure IPD Services Table has POC and Result columns
    $chkSvc = $conn->query("SHOW COLUMNS FROM `ipd_services` LIKE 'requires_result'");
    if($chkSvc && $chkSvc->num_rows == 0) {
        $conn->query("ALTER TABLE `ipd_services` ADD COLUMN `service_type_id` INT(11) DEFAULT NULL AFTER `service_name`");
        $conn->query("ALTER TABLE `ipd_services` ADD COLUMN `requires_result` TINYINT(1) DEFAULT 0 AFTER `service_type_id`");
        $conn->query("ALTER TABLE `ipd_services` ADD COLUMN `unit_of_measure` VARCHAR(50) DEFAULT NULL AFTER `requires_result`");
        $conn->query("ALTER TABLE `ipd_services` ADD COLUMN `result_type` VARCHAR(50) DEFAULT 'Numeric' AFTER `unit_of_measure`");
        $conn->query("ALTER TABLE `ipd_services` ADD COLUMN `options_csv` TEXT DEFAULT NULL AFTER `result_type`");
    }

    // 4. Ensure Corporate Tariffs Table has Adult/Child split
    $chkCorp = $conn->query("SHOW COLUMNS FROM `ipd_service_corporate_tariffs` LIKE 'tariff_amount_adult'");
    if($chkCorp && $chkCorp->num_rows == 0) {
        $conn->query("ALTER TABLE `ipd_service_corporate_tariffs` ADD COLUMN `tariff_amount_adult` decimal(10,2) DEFAULT 0.00 AFTER `insurance_type_id`");
        $conn->query("ALTER TABLE `ipd_service_corporate_tariffs` ADD COLUMN `tariff_amount_child` decimal(10,2) DEFAULT 0.00 AFTER `tariff_amount_adult`");
        $conn->query("ALTER TABLE `ipd_service_corporate_tariffs` ADD COLUMN `is_copay_required` TINYINT(1) DEFAULT 0 AFTER `tariff_amount_child`");
    }

    // 5. Reference Ranges Table
    $conn->query("CREATE TABLE IF NOT EXISTS `ipd_poc_reference_ranges` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `ipd_service_id` int(11) NOT NULL,
      `gender_target` varchar(20) DEFAULT 'All',
      `min_age_years` int(11) DEFAULT 0,
      `max_age_years` int(11) DEFAULT 150,
      `min_value` decimal(10,4) DEFAULT NULL,
      `max_value` decimal(10,4) DEFAULT NULL,
      `critical_low` decimal(10,4) DEFAULT NULL,
      `critical_high` decimal(10,4) DEFAULT NULL,
      `is_active` tinyint(1) DEFAULT 1,
      `created_at` timestamp NULL DEFAULT current_timestamp(),
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");

    // 6. Multi-Parameter Table for Complex POC Tests
    $conn->query("CREATE TABLE IF NOT EXISTS `ipd_poc_parameters` (
      `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
      `ipd_service_id` int(11) NOT NULL,
      `parameter_name` varchar(150) NOT NULL,
      `unit_of_measure` varchar(50) DEFAULT NULL,
      `result_type` varchar(50) DEFAULT 'Numeric',
      `options_csv` text DEFAULT NULL,
      `is_active` tinyint(1) DEFAULT 1,
      `created_at` timestamp NULL DEFAULT current_timestamp()
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");

    // 7. Auto-Seed the System Registry
    $chkDict = $conn->query("SELECT id FROM system_dictionaries_registry WHERE target_table='ipd_services'");
    if($chkDict && $chkDict->num_rows == 0) {
        $conn->query("INSERT INTO system_dictionaries_registry (dictionary_name, target_table, display_column, value_column, filter_condition) VALUES ('Ward Services & POC Tests', 'ipd_services', 'service_name', 'id', 'requires_result=1')");
    }

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $action = $_POST['action'] ?? '';

        // =====================================
        // DATATABLES FETCH
        // =====================================
        if ($action === 'fetch_dictionaries') {
            $type = $_POST['dict_type'] ?? '';
            $data = [];
            
            if ($type === 'diet') $res = $conn->query("SELECT id, diet_name as name, description, is_active FROM ipd_setup_diet_types ORDER BY id DESC");
            elseif ($type === 'fluid') $res = $conn->query("SELECT id, fluid_category, fluid_name as name, is_active FROM ipd_setup_fluid_types ORDER BY fluid_category, id DESC");
            elseif ($type === 'vital') $res = $conn->query("SELECT id, param_name as name, unit_of_measure, critical_low, critical_high, is_active FROM ipd_setup_vital_params ORDER BY id DESC");
            elseif ($type === 'obs_freq') $res = $conn->query("SELECT id, frequency_name as name, interval_minutes, is_active FROM ipd_setup_obs_frequencies ORDER BY interval_minutes ASC");
            elseif ($type === 'o2_mode') $res = $conn->query("SELECT id, mode_name as name, is_active FROM ipd_setup_oxygen_modes ORDER BY id DESC");
            elseif ($type === 'o2_flow') $res = $conn->query("SELECT id, flow_rate_name as name, value_lpm, is_active FROM ipd_setup_oxygen_flow_rates ORDER BY value_lpm ASC");
            elseif ($type === 'equipment') $res = $conn->query("SELECT id, equipment_name as name, is_active FROM ipd_setup_ward_equipment ORDER BY id DESC");
            elseif ($type === 'med_route') $res = $conn->query("SELECT id, route_name as name, is_active FROM ipd_setup_med_routes ORDER BY id DESC");
            elseif ($type === 'med_inst') $res = $conn->query("SELECT id, instruction_name as name, is_active FROM ipd_setup_med_instructions ORDER BY id DESC");
            elseif ($type === 'blood_prod') $res = $conn->query("SELECT id, product_name as name, is_active FROM ipd_setup_blood_products ORDER BY id DESC");
            elseif ($type === 'isolation') $res = $conn->query("SELECT id, isolation_name as name, is_active FROM ipd_setup_isolation_types ORDER BY id DESC");
            elseif ($type === 'outcome') $res = $conn->query("SELECT id, outcome_name as name, triggers_action, is_active FROM ipd_setup_round_outcomes ORDER BY id DESC");
            elseif ($type === 'registry') $res = $conn->query("SELECT * FROM system_dictionaries_registry ORDER BY id DESC");
            elseif ($type === 'svc_type') $res = $conn->query("SELECT id, type_name as name, is_active FROM ipd_setup_service_types ORDER BY id DESC");
            elseif ($type === 'ipd_services') {
                $currRes = $conn->query("SELECT system_currency FROM system_workflow_rules LIMIT 1");
                $sys_currency = ($currRes && $row = $currRes->fetch_assoc()) ? $row['system_currency'] : 'GHS';

                $res = $conn->query("SELECT s.id, s.service_name, st.type_name as service_type, 
                                     s.cash_price_adult, s.cash_price_child, s.is_nhis_covered, 
                                     s.nhis_tariff_adult, s.nhis_tariff_child, s.is_active, 
                                     s.requires_result, s.result_type, s.unit_of_measure,
                                     (SELECT COUNT(id) FROM ipd_service_corporate_tariffs WHERE ipd_service_id = s.id) as corp_count,
                                     (SELECT COUNT(id) FROM ipd_poc_parameters WHERE ipd_service_id = s.id) as param_count
                                     FROM ipd_services s 
                                     LEFT JOIN ipd_setup_service_types st ON s.service_type_id = st.id 
                                     ORDER BY s.id DESC");
                if(isset($res) && $res) while ($row = $res->fetch_assoc()) $data[] = $row;
                outputJSON(['data' => $data, 'currency' => $sys_currency]);
            }

            if(isset($res) && $res && $type !== 'ipd_services') {
                while ($row = $res->fetch_assoc()) {
                    $data[] = $row;
                }
            }
            outputJSON(['data' => $data]);
        }

        if ($action === 'fetch_service_types') {
            $types = []; $tRes = $conn->query("SELECT id, type_name FROM ipd_setup_service_types WHERE is_active=1 ORDER BY type_name");
            if($tRes) while($r = $tRes->fetch_assoc()) $types[] = $r;
            
            $ins = []; $iRes = $conn->query("SELECT id, insurance_name FROM insurance_type WHERE is_active=1 ORDER BY insurance_name");
            if($iRes) while($r = $iRes->fetch_assoc()) $ins[] = $r;

            outputJSON(['status' => 'success', 'types' => $types, 'insurance' => $ins]);
        }

        if ($action === 'fetch_corp_tariffs') {
            $service_id = (int)$_POST['service_id'];
            $res = $conn->query("SELECT t.*, i.insurance_name FROM ipd_service_corporate_tariffs t 
                                 JOIN insurance_type i ON t.insurance_type_id = i.id 
                                 WHERE t.ipd_service_id = $service_id ORDER BY i.insurance_name ASC");
            $data = []; if($res) while($r = $res->fetch_assoc()) $data[] = $r;
            outputJSON(['data' => $data]);
        }

        if ($action === 'fetch_poc_ranges') {
            $service_id = (int)$_POST['service_id'];
            $res = $conn->query("SELECT * FROM ipd_poc_reference_ranges WHERE ipd_service_id = $service_id ORDER BY min_age_years ASC, gender_target ASC");
            $data = []; if($res) while($r = $res->fetch_assoc()) $data[] = $r;
            outputJSON(['data' => $data]);
        }

        if ($action === 'fetch_poc_params') {
            $service_id = (int)$_POST['service_id'];
            $res = $conn->query("SELECT * FROM ipd_poc_parameters WHERE ipd_service_id = $service_id ORDER BY id ASC");
            $data = []; if($res) while($r = $res->fetch_assoc()) $data[] = $r;
            outputJSON(['data' => $data]);
        }

        if ($action === 'fetch_master_dicts') {
            $res = $conn->query("SELECT * FROM ipd_custom_dictionaries ORDER BY dict_name ASC");
            $data = []; if($res) while($r = $res->fetch_assoc()) $data[] = $r;
            outputJSON(['status' => 'success', 'data' => $data]);
        }

        if ($action === 'fetch_dict_items') {
            $dict_id = (int)$_POST['dict_id'];
            $res = $conn->query("SELECT * FROM ipd_custom_dict_items WHERE dict_id = $dict_id ORDER BY item_name ASC");
            $data = []; if($res) while($r = $res->fetch_assoc()) $data[] = $r;
            outputJSON(['data' => $data]);
        }

        // =====================================
        // GET SINGLE RECORD FOR EDITING
        // =====================================
        if ($action === 'get_record') {
            $table = $_POST['table']; $id = (int)$_POST['id'];
            $allowed = ['ipd_setup_diet_types', 'ipd_setup_fluid_types', 'ipd_setup_vital_params', 'ipd_setup_obs_frequencies', 'ipd_setup_oxygen_modes', 'ipd_setup_oxygen_flow_rates', 'ipd_setup_ward_equipment', 'ipd_setup_med_routes', 'ipd_setup_med_instructions', 'ipd_setup_blood_products', 'ipd_setup_isolation_types', 'ipd_custom_dict_items', 'system_dictionaries_registry', 'ipd_services', 'ipd_setup_service_types', 'ipd_poc_parameters', 'ipd_setup_round_outcomes'];
            if(!in_array($table, $allowed)) { outputJSON(['status' => 'error', 'message' => 'Unauthorized']); }
            
            $stmt = $conn->prepare("SELECT * FROM $table WHERE id = ?"); $stmt->bind_param("i", $id); $stmt->execute();
            $record = $stmt->get_result()->fetch_assoc();
            outputJSON(['status' => 'success', 'data' => $record]);
        }

        // =====================================
        // WARD SERVICES / POC TESTS SAVE
        // =====================================
        if ($action === 'save_ipd_service') {
            $id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
            $name = trim($_POST['service_name']);
            $type_id = (int)$_POST['service_type_id'];
            
            $cash_a = (float)$_POST['cash_price_adult'];
            $cash_c = (float)$_POST['cash_price_child'];
            $nhis_cov = isset($_POST['is_nhis_covered']) ? 1 : 0;
            $nhis_a = $nhis_cov ? (float)$_POST['nhis_tariff_adult'] : 0.00;
            $nhis_c = $nhis_cov ? (float)$_POST['nhis_tariff_child'] : 0.00;
            $copay_a = $nhis_cov ? (float)$_POST['nhis_copay_adult'] : 0.00;
            $copay_c = $nhis_cov ? (float)$_POST['nhis_copay_child'] : 0.00;

            $req_res = isset($_POST['requires_result']) ? 1 : 0;
            $unit = $req_res ? trim($_POST['unit_of_measure']) : null;
            $res_type = $req_res ? $_POST['result_type'] : 'Numeric';
            $opts = ($req_res && $res_type === 'Options') ? trim($_POST['options_csv']) : null;

            if ($id) { 
                $stmt = $conn->prepare("UPDATE ipd_services SET service_name=?, service_type_id=?, requires_result=?, unit_of_measure=?, result_type=?, options_csv=?, cash_price_adult=?, cash_price_child=?, is_nhis_covered=?, nhis_tariff_adult=?, nhis_tariff_child=?, nhis_copay_adult=?, nhis_copay_child=? WHERE id=?"); 
                $stmt->bind_param("siisssddiddddi", $name, $type_id, $req_res, $unit, $res_type, $opts, $cash_a, $cash_c, $nhis_cov, $nhis_a, $nhis_c, $copay_a, $copay_c, $id); 
            } else { 
                $stmt = $conn->prepare("INSERT INTO ipd_services (service_name, service_type_id, requires_result, unit_of_measure, result_type, options_csv, cash_price_adult, cash_price_child, is_nhis_covered, nhis_tariff_adult, nhis_tariff_child, nhis_copay_adult, nhis_copay_child) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); 
                $stmt->bind_param("siisssddidddd", $name, $type_id, $req_res, $unit, $res_type, $opts, $cash_a, $cash_c, $nhis_cov, $nhis_a, $nhis_c, $copay_a, $copay_c); 
            }
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        if ($action === 'save_corp_tariff') {
            $svc_id = (int)$_POST['ipd_service_id'];
            $ins_id = (int)$_POST['insurance_type_id'];
            $tariff_a = (float)$_POST['tariff_amount_adult'];
            $tariff_c = (float)$_POST['tariff_amount_child'];
            $req_copay = isset($_POST['is_copay_required']) ? 1 : 0;
            $copay_a = $req_copay ? (float)$_POST['copay_amount_adult'] : 0.00;
            $copay_c = $req_copay ? (float)$_POST['copay_amount_child'] : 0.00;

            $check = $conn->query("SELECT id FROM ipd_service_corporate_tariffs WHERE ipd_service_id=$svc_id AND insurance_type_id=$ins_id");
            if ($check && $check->num_rows > 0) {
                $row = $check->fetch_assoc();
                $stmt = $conn->prepare("UPDATE ipd_service_corporate_tariffs SET tariff_amount_adult=?, tariff_amount_child=?, is_copay_required=?, copay_amount_adult=?, copay_amount_child=? WHERE id=?");
                $stmt->bind_param("ddiddi", $tariff_a, $tariff_c, $req_copay, $copay_a, $copay_c, $row['id']);
            } else {
                $stmt = $conn->prepare("INSERT INTO ipd_service_corporate_tariffs (ipd_service_id, insurance_type_id, tariff_amount_adult, tariff_amount_child, is_copay_required, copay_amount_adult, copay_amount_child) VALUES (?, ?, ?, ?, ?, ?, ?)");
                $stmt->bind_param("iididdd", $svc_id, $ins_id, $tariff_a, $tariff_c, $req_copay, $copay_a, $copay_c);
            }
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        if ($action === 'save_poc_range') {
            $svc_id = (int)$_POST['ipd_service_id'];
            $gender = $_POST['gender_target'];
            $min_age = (int)$_POST['min_age_years'];
            $max_age = (int)$_POST['max_age_years'];
            $min_val = (float)$_POST['min_value'];
            $max_val = (float)$_POST['max_value'];
            $crit_low = empty($_POST['critical_low']) ? null : (float)$_POST['critical_low'];
            $crit_high = empty($_POST['critical_high']) ? null : (float)$_POST['critical_high'];

            $stmt = $conn->prepare("INSERT INTO ipd_poc_reference_ranges (ipd_service_id, gender_target, min_age_years, max_age_years, min_value, max_value, critical_low, critical_high) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
            $stmt->bind_param("isiidddd", $svc_id, $gender, $min_age, $max_age, $min_val, $max_val, $crit_low, $crit_high);
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        if ($action === 'save_poc_param') {
            $id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
            $svc_id = (int)$_POST['ipd_service_id'];
            $name = trim($_POST['parameter_name']);
            $unit = trim($_POST['unit_of_measure']);
            $res_type = $_POST['result_type'];
            $opts = ($res_type === 'Options') ? trim($_POST['options_csv']) : null;

            if ($id) {
                $stmt = $conn->prepare("UPDATE ipd_poc_parameters SET parameter_name=?, unit_of_measure=?, result_type=?, options_csv=? WHERE id=?");
                $stmt->bind_param("ssssi", $name, $unit, $res_type, $opts, $id);
            } else {
                $stmt = $conn->prepare("INSERT INTO ipd_poc_parameters (ipd_service_id, parameter_name, unit_of_measure, result_type, options_csv) VALUES (?, ?, ?, ?, ?)");
                $stmt->bind_param("issss", $svc_id, $name, $unit, $res_type, $opts);
            }
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        // =====================================
        // STANDARD DICTIONARIES SAVES
        // =====================================
        if ($action === 'save_dictionary') {
            $id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
            $type = $_POST['dict_type'];
            
            if ($type === 'diet') {
                $name = trim($_POST['dict_name']); $desc = trim($_POST['description']);
                if($id) { $stmt = $conn->prepare("UPDATE ipd_setup_diet_types SET diet_name=?, description=? WHERE id=?"); $stmt->bind_param("ssi", $name, $desc, $id); } 
                else { $stmt = $conn->prepare("INSERT INTO ipd_setup_diet_types (diet_name, description) VALUES (?, ?)"); $stmt->bind_param("ss", $name, $desc); }
            } 
            elseif ($type === 'fluid') {
                $name = trim($_POST['dict_name']); $cat = $_POST['fluid_category'];
                if($id) { $stmt = $conn->prepare("UPDATE ipd_setup_fluid_types SET fluid_category=?, fluid_name=? WHERE id=?"); $stmt->bind_param("ssi", $cat, $name, $id); } 
                else { $stmt = $conn->prepare("INSERT INTO ipd_setup_fluid_types (fluid_category, fluid_name) VALUES (?, ?)"); $stmt->bind_param("ss", $cat, $name); }
            }
            elseif ($type === 'vital') {
                $name = trim($_POST['dict_name']); $unit = trim($_POST['unit_of_measure']);
                $min = empty($_POST['critical_low']) ? null : (float)$_POST['critical_low']; $max = empty($_POST['critical_high']) ? null : (float)$_POST['critical_high'];
                if($id) { $stmt = $conn->prepare("UPDATE ipd_setup_vital_params SET param_name=?, unit_of_measure=?, critical_low=?, critical_high=? WHERE id=?"); $stmt->bind_param("ssddi", $name, $unit, $min, $max, $id); } 
                else { $stmt = $conn->prepare("INSERT INTO ipd_setup_vital_params (param_name, unit_of_measure, critical_low, critical_high) VALUES (?, ?, ?, ?)"); $stmt->bind_param("ssdd", $name, $unit, $min, $max); }
            }
            elseif ($type === 'obs_freq') {
                $name = trim($_POST['dict_name']); $mins = (int)$_POST['interval_minutes'];
                if($id) { $stmt = $conn->prepare("UPDATE ipd_setup_obs_frequencies SET frequency_name=?, interval_minutes=? WHERE id=?"); $stmt->bind_param("sii", $name, $mins, $id); } 
                else { $stmt = $conn->prepare("INSERT INTO ipd_setup_obs_frequencies (frequency_name, interval_minutes) VALUES (?, ?)"); $stmt->bind_param("si", $name, $mins); }
            }
            elseif ($type === 'o2_flow') {
                $name = trim($_POST['dict_name']); $lpm = (float)$_POST['value_lpm'];
                if($id) { $stmt = $conn->prepare("UPDATE ipd_setup_oxygen_flow_rates SET flow_rate_name=?, value_lpm=? WHERE id=?"); $stmt->bind_param("sdi", $name, $lpm, $id); } 
                else { $stmt = $conn->prepare("INSERT INTO ipd_setup_oxygen_flow_rates (flow_rate_name, value_lpm) VALUES (?, ?)"); $stmt->bind_param("sd", $name, $lpm); }
            }
            elseif ($type === 'outcome') {
                $name = trim($_POST['dict_name']); $action_trigger = trim($_POST['triggers_action']);
                if($id) { $stmt = $conn->prepare("UPDATE ipd_setup_round_outcomes SET outcome_name=?, triggers_action=? WHERE id=?"); $stmt->bind_param("ssi", $name, $action_trigger, $id); } 
                else { $stmt = $conn->prepare("INSERT INTO ipd_setup_round_outcomes (outcome_name, triggers_action) VALUES (?, ?)"); $stmt->bind_param("ss", $name, $action_trigger); }
            }
            else {
                $name = trim($_POST['dict_name']);
                if($type === 'o2_mode') { $table = 'ipd_setup_oxygen_modes'; $col = 'mode_name'; }
                elseif($type === 'equipment') { $table = 'ipd_setup_ward_equipment'; $col = 'equipment_name'; }
                elseif($type === 'med_route') { $table = 'ipd_setup_med_routes'; $col = 'route_name'; }
                elseif($type === 'med_inst') { $table = 'ipd_setup_med_instructions'; $col = 'instruction_name'; }
                elseif($type === 'blood_prod') { $table = 'ipd_setup_blood_products'; $col = 'product_name'; }
                elseif($type === 'isolation') { $table = 'ipd_setup_isolation_types'; $col = 'isolation_name'; }
                elseif($type === 'svc_type') { $table = 'ipd_setup_service_types'; $col = 'type_name'; }
                else { outputJSON(['status' => 'error']); }

                if($id) { $stmt = $conn->prepare("UPDATE $table SET $col=? WHERE id=?"); $stmt->bind_param("si", $name, $id); } 
                else { $stmt = $conn->prepare("INSERT INTO $table ($col) VALUES (?)"); $stmt->bind_param("s", $name); }
            }
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        if ($action === 'save_master_dict') {
            $id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
            $name = trim($_POST['dict_name']); $desc = trim($_POST['description']);
            if($id) { $stmt = $conn->prepare("UPDATE ipd_custom_dictionaries SET dict_name=?, description=? WHERE id=?"); $stmt->bind_param("ssi", $name, $desc, $id); } 
            else { $stmt = $conn->prepare("INSERT INTO ipd_custom_dictionaries (dict_name, description) VALUES (?, ?)"); $stmt->bind_param("ss", $name, $desc); }
            $status = $stmt->execute(); $new_id = $id ? $id : $stmt->insert_id;
            outputJSON(['status' => $status ? 'success' : 'error', 'insert_id' => $new_id]);
        }

        if ($action === 'save_dict_item') {
            $id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
            $dict_id = (int)$_POST['dict_id'];
            $name = trim($_POST['item_name']);
            $input_type = $_POST['input_type'] ?? 'Standard Option / Text';
            $options_csv = trim($_POST['options_csv'] ?? '');
            if($id) { $stmt = $conn->prepare("UPDATE ipd_custom_dict_items SET item_name=?, input_type=?, options_csv=? WHERE id=?"); $stmt->bind_param("sssi", $name, $input_type, $options_csv, $id); } 
            else { $stmt = $conn->prepare("INSERT INTO ipd_custom_dict_items (dict_id, item_name, input_type, options_csv) VALUES (?, ?, ?, ?)"); $stmt->bind_param("isss", $dict_id, $name, $input_type, $options_csv); }
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        if ($action === 'save_registry') {
            $id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
            $name = trim($_POST['dictionary_name']); $table = trim($_POST['target_table']); $disp = trim($_POST['display_column']); $val = trim($_POST['value_column']); $filter = !empty($_POST['filter_condition']) ? trim($_POST['filter_condition']) : null;
            if($id) { $stmt = $conn->prepare("UPDATE system_dictionaries_registry SET dictionary_name=?, target_table=?, display_column=?, value_column=?, filter_condition=? WHERE id=?"); $stmt->bind_param("sssssi", $name, $table, $disp, $val, $filter, $id); } 
            else { $stmt = $conn->prepare("INSERT INTO system_dictionaries_registry (dictionary_name, target_table, display_column, value_column, filter_condition) VALUES (?, ?, ?, ?, ?)"); $stmt->bind_param("sssss", $name, $table, $disp, $val, $filter); }
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        if ($action === 'delete_record') {
            $table = $_POST['table']; $id = (int)$_POST['id'];
            $allowed = ['ipd_setup_diet_types', 'ipd_setup_fluid_types', 'ipd_setup_vital_params', 'ipd_setup_obs_frequencies', 'ipd_setup_oxygen_modes', 'ipd_setup_oxygen_flow_rates', 'ipd_setup_ward_equipment', 'ipd_setup_med_routes', 'ipd_setup_med_instructions', 'ipd_setup_blood_products', 'ipd_setup_isolation_types', 'ipd_custom_dictionaries', 'ipd_custom_dict_items', 'system_dictionaries_registry', 'ipd_services', 'ipd_service_corporate_tariffs', 'ipd_setup_service_types', 'ipd_poc_reference_ranges', 'ipd_poc_parameters', 'ipd_setup_round_outcomes'];
            if(in_array($table, $allowed)) { $conn->query("DELETE FROM $table WHERE id = $id"); }
            outputJSON(['status' => 'success']);
        }

        if ($action === 'toggle_status') {
            $table = $_POST['table']; $id = (int)$_POST['id']; $status = (int)$_POST['status'];
            $allowed = ['ipd_setup_diet_types', 'ipd_setup_fluid_types', 'ipd_setup_vital_params', 'ipd_setup_obs_frequencies', 'ipd_setup_oxygen_modes', 'ipd_setup_oxygen_flow_rates', 'ipd_setup_ward_equipment', 'ipd_setup_med_routes', 'ipd_setup_med_instructions', 'ipd_setup_blood_products', 'ipd_setup_isolation_types', 'ipd_custom_dictionaries', 'ipd_custom_dict_items', 'system_dictionaries_registry', 'ipd_services', 'ipd_setup_service_types', 'ipd_poc_reference_ranges', 'ipd_poc_parameters', 'ipd_setup_round_outcomes'];
            if(in_array($table, $allowed)) { $conn->query("UPDATE $table SET is_active = $status WHERE id = $id"); }
            outputJSON(['status' => 'success']);
        }
    }
} catch (Exception $e) {
    outputJSON(['status' => 'error', 'message' => $e->getMessage()]);
}
?>