<?php
session_start();
ini_set('display_errors', 0); // Pentest: Hide raw errors to prevent JSON corruption
error_reporting(E_ALL);
ob_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 {
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $action = $_POST['action'] ?? '';
        
        $staff_id = $_SESSION['staff_id'] ?? null;
        if (!$staff_id) {
            $fallback = $conn->query("SELECT staff_id FROM staff WHERE status_id = 1 LIMIT 1")->fetch_assoc();
            $staff_id = $fallback ? (int)$fallback['staff_id'] : 1;
        }

        // =====================================
        // AUTO-HEALING & PATCHING (STRICTLY DATABASE RESPONSIVE)
        // =====================================
        $checkCol1 = $conn->query("SHOW COLUMNS FROM ipd_forms LIKE 'target_module'");
        if ($checkCol1 && $checkCol1->num_rows == 0) {
            $conn->query("ALTER TABLE `ipd_forms` ADD COLUMN `target_module` varchar(50) NOT NULL DEFAULT 'Global Application' AFTER `category_id`");
        }

        $checkCol2 = $conn->query("SHOW COLUMNS FROM ipd_form_fields LIKE 'native_module_key'");
        if ($checkCol2 && $checkCol2->num_rows == 0) {
            $conn->query("ALTER TABLE `ipd_form_fields` ADD COLUMN `native_module_key` varchar(100) DEFAULT NULL AFTER `dictionary_reference`");
            $conn->query("ALTER TABLE `ipd_form_fields` ADD COLUMN `embedded_form_id` int(11) DEFAULT NULL AFTER `native_module_key`");
        }

        // Auto-heal: 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)");
        }
        
        // Auto-heal: Register Clinical Outcomes into Dictionaries Registry for global dynamic mapping
        $chkDictOut = $conn->query("SELECT id FROM system_dictionaries_registry WHERE target_table='ipd_setup_round_outcomes'");
        if($chkDictOut && $chkDictOut->num_rows == 0) {
            $conn->query("INSERT INTO system_dictionaries_registry (dictionary_name, target_table, display_column, value_column, filter_condition) VALUES ('Clinical Outcomes (Patient Disposition)', 'ipd_setup_round_outcomes', 'outcome_name', 'outcome_name', 'is_active=1')");
        }

        // =====================================
        // FETCHING DATA (ZERO HARDCODING)
        // =====================================
        if ($action === 'fetch_forms') {
            $res = $conn->query("SELECT f.*, c.category_name, w.ward_name, r.room_number_or_name, p.name as role_name 
                                 FROM ipd_forms f 
                                 LEFT JOIN ipd_form_categories c ON f.category_id = c.id
                                 LEFT JOIN ipd_wards w ON f.ward_id = w.id 
                                 LEFT JOIN ipd_rooms r ON f.room_id = r.id 
                                 LEFT JOIN staff_positions p ON f.target_role_id = p.id
                                 ORDER BY f.id DESC");
            $data = []; if ($res) while ($row = $res->fetch_assoc()) $data[] = $row;
            outputJSON(['data' => $data]);
        }
        
        if ($action === 'fetch_categories') {
            $res = $conn->query("SELECT * FROM ipd_form_categories ORDER BY category_name ASC");
            $data = []; if ($res) while ($row = $res->fetch_assoc()) $data[] = $row;
            outputJSON(['data' => $data]);
        }

        if ($action === 'fetch_dropdowns') {
            $wards = []; $rooms = []; $cats = []; $dicts = []; $roles = []; $formsList = []; $depts = [];
            
            $wRes = $conn->query("SELECT id, ward_name FROM ipd_wards WHERE is_active=1 ORDER BY ward_name");
            if ($wRes) while ($row = $wRes->fetch_assoc()) $wards[] = $row;
            
            $rRes = $conn->query("SELECT id, ward_id, room_number_or_name FROM ipd_rooms WHERE is_active=1 ORDER BY room_number_or_name");
            if ($rRes) while ($row = $rRes->fetch_assoc()) $rooms[] = $row;
            
            $cRes = $conn->query("SELECT id, category_name FROM ipd_form_categories WHERE is_active=1 ORDER BY category_name");
            if ($cRes) while ($row = $cRes->fetch_assoc()) $cats[] = $row;

            $roleRes = $conn->query("SELECT id, name FROM staff_positions ORDER BY name");
            if ($roleRes) while ($row = $roleRes->fetch_assoc()) $roles[] = $row;

            $frmRes = $conn->query("SELECT id, form_name FROM ipd_forms WHERE is_active=1 ORDER BY form_name");
            if ($frmRes) while ($row = $frmRes->fetch_assoc()) $formsList[] = $row;

            // DYNAMIC DEPARTMENTS FETCH
            $deptRes = $conn->query("SELECT id, department_name FROM departments WHERE is_active=1 ORDER BY department_name");
            if ($deptRes) while ($row = $deptRes->fetch_assoc()) $depts[] = $row;
            
            $regRes = $conn->query("SELECT id, dictionary_name FROM system_dictionaries_registry WHERE is_active=1 ORDER BY dictionary_name");
            if ($regRes) while ($row = $regRes->fetch_assoc()) $dicts[] = ['id' => 'reg_' . $row['id'], 'name' => $row['dictionary_name'], 'type' => 'Core Database'];

            $custRes = $conn->query("SELECT id, dict_name FROM ipd_custom_dictionaries WHERE is_active=1 ORDER BY dict_name");
            if ($custRes) while ($row = $custRes->fetch_assoc()) $dicts[] = ['id' => 'custom_' . $row['id'], 'name' => $row['dict_name'], 'type' => 'Custom Dictionary'];

            outputJSON(['status' => 'success', 'wards' => $wards, 'rooms' => $rooms, 'categories' => $cats, 'dictionaries' => $dicts, 'roles' => $roles, 'forms_list' => $formsList, 'departments' => $depts]);
        }

        if ($action === 'fetch_form_structure') {
            $form_id = (int)$_POST['form_id'];
            $formRes = $conn->query("SELECT * FROM ipd_forms WHERE id = $form_id");
            $form = $formRes->fetch_assoc();
            if (!$form) { outputJSON(['status' => 'error', 'message' => 'Form not found']); }

            $sections = [];
            $secRes = $conn->query("SELECT * FROM ipd_form_sections WHERE form_id = $form_id ORDER BY display_order ASC, id ASC");
            if ($secRes) {
                while ($sec = $secRes->fetch_assoc()) {
                    $fields = [];
                    $fldRes = $conn->query("SELECT * FROM ipd_form_fields WHERE section_id = {$sec['id']} ORDER BY display_order ASC, id ASC");
                    if ($fldRes) {
                        while ($fld = $fldRes->fetch_assoc()) {
                            $fld['dictionary_name'] = '';
                            $fld['embedded_form_name'] = '';
                            
                            if ($fld['field_type'] === 'Dictionary Reference' && !empty($fld['dictionary_reference'])) {
                                $ref = $fld['dictionary_reference'];
                                if (strpos($ref, 'reg_') === 0) {
                                    $rid = (int)str_replace('reg_', '', $ref);
                                    $nRes = $conn->query("SELECT dictionary_name FROM system_dictionaries_registry WHERE id=$rid");
                                    if ($nRes && $n = $nRes->fetch_assoc()) $fld['dictionary_name'] = $n['dictionary_name'] . ' (Core Database)';
                                } elseif (strpos($ref, 'custom_') === 0) {
                                    $cid = (int)str_replace('custom_', '', $ref);
                                    $nRes = $conn->query("SELECT dict_name FROM ipd_custom_dictionaries WHERE id=$cid");
                                    if ($nRes && $n = $nRes->fetch_assoc()) $fld['dictionary_name'] = $n['dict_name'] . ' (Custom)';
                                }
                            } 
                            elseif ($fld['field_type'] === 'Embed Custom Form' && !empty($fld['embedded_form_id'])) {
                                $subFormId = (int)$fld['embedded_form_id'];
                                $nRes = $conn->query("SELECT form_name FROM ipd_forms WHERE id=$subFormId");
                                if ($nRes && $n = $nRes->fetch_assoc()) $fld['embedded_form_name'] = $n['form_name'];
                            }

                            $fields[] = $fld;
                        }
                    }
                    $sec['fields'] = $fields;
                    $sections[] = $sec;
                }
            }
            $form['sections'] = $sections;

            outputJSON(['status' => 'success', 'data' => $form]);
        }

        // =====================================
        // CRUD: CATEGORIES & FORMS
        // =====================================
        if ($action === 'save_category') {
            $id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
            $name = trim($_POST['category_name']);
            if ($id) { $stmt = $conn->prepare("UPDATE ipd_form_categories SET category_name=? WHERE id=?"); $stmt->bind_param("si", $name, $id); } 
            else { $stmt = $conn->prepare("INSERT INTO ipd_form_categories (category_name) VALUES (?)"); $stmt->bind_param("s", $name); }
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        if ($action === 'save_form') {
            $id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
            $name = trim($_POST['form_name']);
            $cat_id = (int)$_POST['category_id'];
            $target_module = $_POST['target_module'] ?? 'Global Application'; 
            
            $ward_id = empty($_POST['ward_id']) ? null : (int)$_POST['ward_id'];
            $room_id = empty($_POST['room_id']) ? null : (int)$_POST['room_id'];
            $target_role = empty($_POST['target_role_id']) ? null : (int)$_POST['target_role_id'];
            $req_sig = isset($_POST['requires_signature']) ? 1 : 0;

            if ($id) { 
                $stmt = $conn->prepare("UPDATE ipd_forms SET form_name=?, category_id=?, target_module=?, ward_id=?, room_id=?, target_role_id=?, requires_signature=? WHERE id=?"); 
                $stmt->bind_param("sisiiiii", $name, $cat_id, $target_module, $ward_id, $room_id, $target_role, $req_sig, $id); 
            } else { 
                $stmt = $conn->prepare("INSERT INTO ipd_forms (form_name, category_id, target_module, ward_id, room_id, target_role_id, requires_signature, created_by) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); 
                $stmt->bind_param("sisiiiii", $name, $cat_id, $target_module, $ward_id, $room_id, $target_role, $req_sig, $staff_id); 
            }
            if(!$stmt->execute()) { outputJSON(['status' => 'error', 'message' => $stmt->error]); }
            outputJSON(['status' => 'success']);
        }

        // =====================================
        // CRUD: SECTIONS & FIELDS
        // =====================================
        if ($action === 'save_section') {
            $id = !empty($_POST['section_id']) ? (int)$_POST['section_id'] : null;
            $form_id = (int)$_POST['form_id'];
            $title = trim($_POST['section_title']);
            $order = (int)$_POST['display_order'];

            if ($id) { $stmt = $conn->prepare("UPDATE ipd_form_sections SET section_title=?, display_order=? WHERE id=?"); $stmt->bind_param("sii", $title, $order, $id); } 
            else { $stmt = $conn->prepare("INSERT INTO ipd_form_sections (form_id, section_title, display_order) VALUES (?, ?, ?)"); $stmt->bind_param("isi", $form_id, $title, $order); }
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }

        if ($action === 'save_field') {
            $id = !empty($_POST['field_id']) ? (int)$_POST['field_id'] : null;
            $sec_id = (int)$_POST['section_id'];
            $label = trim($_POST['field_label']);
            $type = $_POST['field_type'];
            
            $dict_ref = null;
            $native_mod = null;
            $embed_id = null;

            if ($type === 'Dictionary Reference') $dict_ref = $_POST['dictionary_reference'] ?? null;
            if (strpos($type, 'Native:') === 0 || strpos($type, 'Report:') === 0) $native_mod = $_POST['native_module_key'] ?? null;
            if ($type === 'Embed Custom Form') $embed_id = !empty($_POST['embedded_form_id']) ? (int)$_POST['embedded_form_id'] : null;
            
            // Handle Dynamic Departments saving into options_csv
            $opts = trim($_POST['options_csv'] ?? '');
            if ($type === 'Native: Service Order') {
                $opts = isset($_POST['service_departments']) ? implode(',', $_POST['service_departments']) : '';
            }

            $mand = isset($_POST['is_mandatory']) ? 1 : 0;
            $order = (int)$_POST['field_display_order'];

            if ($id) { 
                $stmt = $conn->prepare("UPDATE ipd_form_fields SET field_label=?, field_type=?, dictionary_reference=?, native_module_key=?, embedded_form_id=?, options_csv=?, is_mandatory=?, display_order=? WHERE id=?"); 
                $stmt->bind_param("sssssisii", $label, $type, $dict_ref, $native_mod, $embed_id, $opts, $mand, $order, $id); 
            } else { 
                $stmt = $conn->prepare("INSERT INTO ipd_form_fields (section_id, field_label, field_type, dictionary_reference, native_module_key, embedded_form_id, options_csv, is_mandatory, display_order) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); 
                $stmt->bind_param("issssisii", $sec_id, $label, $type, $dict_ref, $native_mod, $embed_id, $opts, $mand, $order); 
            }
            if(!$stmt->execute()) { outputJSON(['status' => 'error', 'message' => $stmt->error]); }
            outputJSON(['status' => 'success']);
        }

        if ($action === 'delete_node') {
            $type = $_POST['node_type']; $id = (int)$_POST['id'];
            $table = ($type === 'form') ? 'ipd_forms' : (($type === 'section') ? 'ipd_form_sections' : (($type === 'field') ? 'ipd_form_fields' : 'ipd_form_categories'));
            $stmt = $conn->prepare("DELETE FROM $table WHERE id = ?"); $stmt->bind_param("i", $id);
            outputJSON(['status' => $stmt->execute() ? 'success' : 'error']);
        }
    }
} catch (Exception $e) {
    outputJSON(['status' => 'error', 'message' => $e->getMessage()]);
}
?>