let all_devices_in_command_center = [];
let request_pending_flags = {};
let all_schedules_command = [];
let signalWireCredentials = null;
let allItemsOfCommandCenter = null;
let allSchedulePayloads = null;
let allSMSIOschedulePayloads = null;
let backendUrl = null;
let all_hardwares_settings_events = [];
let payloads = [];
let isCardViewForCommandCenter = false;
let commandCenterDebounceTimer = null;
let modalActiveCameraId = null;
let activeWebSocketConnections = {};
let preferencesObj =  null;
let all_inputs_automations = [];

$(document).ready(async function () {
  const sessionPreferences = sessionStorage.getItem("preferences");
  if(sessionPreferences){
    const preferencesData = await parseJSONData(sessionPreferences);
    preferencesData?.is_card_view==1? isCardViewForCommandCenter = true:isCardViewForCommandCenter = false;
    preferencesObj=preferencesData;
  }else {
    const preferences = await asyncGetPreferencesRequestForView({
      get_preferences_for_property_user: true,
      property_id: sessionStorage.getItem("propertyId"),
    });
    if(preferences?.length>0){
      preferencesObj=preferences[0];
      sessionStorage.setItem("preferences",JSON.stringify(preferencesObj));
    }
    if(preferences?.length>0 && preferences[0]?.is_card_view==1) isCardViewForCommandCenter = true;
  }
  $("#is_dont_disturb").bootstrapSwitch();
  $("#is_dont_disturb").on(
    "switchChange.bootstrapSwitch",
    function (event, state) {
      handle_dont_disturb_change();
    }
  );

  $("#show_image_modal").on("hidden.bs.modal", function() {
    modalActiveCameraId = null;
    const modalContainer = document.getElementById("show_image_in_modal");
    if (modalContainer) {
      modalContainer.innerHTML = "";
    }
  });

  const fullUrl = window.location.href;
  window.scrollTo({
    top: 0,
    behavior: "smooth",
  });
  isLoadingCommandCenter(true);
  setTimeout(async () => {
    let property_id = sessionStorage.getItem("propertyId");
    await send_hardware_request({
      getScheduleRequest: true,
      property_id: sessionStorage.getItem("propertyId"),
      type:'door'
    });
    await send_hardware_request({
      all_hardwares_settings_events: true,
      property_id: sessionStorage.getItem("propertyId"),
    });
    await send_hardware_request({get_inputs_automation_request: true, property_id: sessionStorage.getItem("propertyId")});
    await send_hardware_request({
      get_signal_wire_credentials: true,
      property_id: sessionStorage.getItem("propertyId"),
    });
    send_command_center_request({
      get_loggedIn_property_user_request: true,
      property_id: sessionStorage.getItem("propertyId"),
    });
    send_command_center_request({
      get_command_center_data_request: true,
      property_id,
    });
  }, 500);
});

function send_hardware_request(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/hardwares/hardwares_request.php",
      type: "post",
      timeout: 10000, // 10 seconds delay
      data,
      success: function (resp) {
        if (data?.getScheduleRequest) {
          all_schedules_command = resp.data;
          resolve(resp.data);
        }
        if (data?.get_signal_wire_credentials) {
          if (resp?.data?.length) {
            signalWireCredentials = resp?.data[0];
          } else signalWireCredentials = null;
          resolve(signalWireCredentials);
        }
        if (data?.all_hardwares_settings_events) {
          all_hardwares_settings_events = resp.data;
          resolve(resp.data);
        }
        if (data?.get_inputs_automation_request) {
          all_inputs_automations = resp.data;
          resolve(resp.data);
        }
      },
      error: function (xhr, status, error) {
        if (xhr?.responseJSON?.error)
          show_command_center_toast_message(xhr?.responseJSON?.error);
        else show_command_center_toast_message(error);
        resolve();
      },
    });
  });
}

function send_command_center_request(data) {
  $.ajax({
    url: "/include/property_builder/command_center/command_center_requests.php",
    type: "post",
    timeout: 10000, // 10 seconds delay
    data,
    success: function (resp) {
      if (data?.get_command_center_data_request) {
        allItemsOfCommandCenter = resp;
        const command_center_search_container = document.getElementById(
          "door_controls_container"
        );
        if (window.innerWidth <= 600 || isCardViewForCommandCenter){
          if(command_center_search_container) command_center_search_container.style.display="flex"
          create_command_center_mobile(allItemsOfCommandCenter.data,allItemsOfCommandCenter?.all_permissions,allItemsOfCommandCenter?.onlyOpenCommand);
          return;
        }else{
          if(command_center_search_container) command_center_search_container.style.display="block"
          create_command_center(allItemsOfCommandCenter.data,allItemsOfCommandCenter?.all_permissions,allItemsOfCommandCenter?.onlyOpenCommand);
        } 
      }
      if (data?.get_loggedIn_property_user_request) {
        update_toggle_disturb(resp.data, resp?.is_property_user);
      }
    },
    error: function (xhr, status, error) {
      isLoadingCommandCenter(false);
      if (xhr?.responseJSON?.error)
        show_command_center_toast_message(xhr?.responseJSON?.error);
      else show_command_center_toast_message(error);
    },
  });
}

function update_toggle_disturb(data, is_property_user) {
  if (is_property_user) {
    document.getElementById("disturb_input_visibility").style.display = "block";
    if (data?.isDontDisturb) {
      const doNotDisturbState = data?.isDontDisturb == "1" ? true : false;
      $("#is_dont_disturb").bootstrapSwitch("state", doNotDisturbState, true);
    }
  } else {
    document.getElementById("disturb_input_visibility").style.display = "none";
  }
}

function isLoadingCommandCenter(isLoading) {
  let ele = document.getElementById("command_center_loading_indicator");
  let container = document.getElementById("command_center_card_wrapper");

  if (isLoading) {
    ele.style.display = "flex";
    if (container) container.style.display = "none";
  } else {
    ele.style.display = "none";
    if (container) container.style.display = "block";
  }
}

function redirect_playback(id) {
  if (!id) return;
  const url = `/playback.php?id=${id}`;
  window.location.href = url;
}

$("#door_controls_container").on("click", ".redirect-playback", function () {
  const id = $(this).data("id");
  redirect_playback(id);
});

async function create_command_center(
  dataArray,
  isAllPermissions = false,
  onlyOpenCommand = false
) {
  // Clear payloads to prevent duplicates on view change
  payloads = [];
  allSMSIOschedulePayloads = [];
  try {
    let data = dataArray;
    all_devices_in_command_center = data;
    let allCommands;
    if (onlyOpenCommand) {
      allCommands = JSON.stringify({
        Release: false,
        Open: false,
        Holdopen: false,
      });
      isAllPermissions = true;
    } else {
      allCommands = JSON.stringify({
        Release: true,
        Open: true,
        Holdopen: true,
      });
    }

    const container = document.getElementById("door_controls_container");
    container.innerHTML="";
    let html = "";

    html += `<div class="">`;

    if (data?.length === 0) {
      html += `<table class="table table-bordered" id="command_center_complete_data_table" style="width:100%;">
          <thead>
            <tr>
              <th>Name</th>
              <th>Live Door Preview</th>
              <th>Schedule</th>
              <th>Commands</th>
              <th>Events</th>
            </tr>
          </thead>
          <tbody>
           
          </tbody>
        </table>
         
          `;
    } else {
      html += `
        <table id="command_center_complete_data_table" data-dt-order="disable" class="table table-bordered table-responsive-lg" style="width:100%;">
          <thead>
            <tr>
              <th>Name</th>
              <th>Live Door Preview</th>
              <th>Schedule</th>
              <th>Commands</th>
              <th>Events</th>
            </tr>
          </thead>
          <tbody>
      `;

      for (const item of data) {
        if (item?.calendar_event_id) {
          const command = all_schedules_command.find(
            (ele) => ele.id == item?.calendar_event_id
          );
          try {
            const scheduleDays = await get_events_doors_request({
              getCommandDays: true,
              id: command?.id,
            });
            setScheduleCommand(scheduleDays, item);
          } catch (error) {
            console.log("scheduleDays", error);
          }
        }

        let trueCommands = createPropertyCommandCenterButtons(
          isAllPermissions ? allCommands : item.actions_to_perform
        );
        let commandButtons = Commands_Buttons(
          trueCommands,
          item.hardware_setting_id
        );

        await is_current_date_in_range(item.start, item.end, item);
        const startDate = get_formatted_date_time(new Date(item?.start));
        let endDateIfAllDay;
        if (item.allDay == "true") {
          const lastMomentOfDay = new Date(item?.start);
          lastMomentOfDay.setHours(23, 59, 59, 999);
          endDateIfAllDay = lastMomentOfDay;
        }
        const endDate = item.end
          ? get_formatted_date_time(new Date(item.end))
          : endDateIfAllDay
          ? get_formatted_date_time(endDateIfAllDay)
          : "";

        const nestedRowId = `nested_row_${item.hardware_setting_id}`;

        // Fetch event data for this specific door item
        let event_resp = await get_events_doors_request({
          event_of: item?.door_id ? item?.door_id : item.hardware_setting_id,
          get_device_events_request: true,
        }).catch((err) => console.log("got error in fetching", err));

        let all_cameras = await get_events_doors_request({
          door_id: item.assigned_door,
          get_all_cameras_of_door_request: true,
        }).catch((err) => console.log("got error in fetching", err));

        const event_data = event_resp?.reverse()?.slice(0, 10);

        let timerValue = "";
        if (item?.title == "24/7") {
          timerValue = "Every time";
        }
        let show_command_buttons = true;
        if(item?.device_type == "web_Relay"){
          show_command_buttons = get_inputs_automations_for_command_center(item);
        }

        html += `
          <!-- Main Row -->
          <tr>
            <td style="vertical-align: middle;">${
              item.door_name || "N/A"
            }</td>
            <td style="vertical-align: middle;">
              
            ${
              all_cameras?.length > 1
                ? `
              <div>
              
              <select class="form-control" required id="change_preview_value_${
                item?.hardware_setting_id
              }" onchange="handle_camera_preview_change(${
                    item?.hardware_setting_id
                  },${item?.assigned_door})">
                <option value="" disabled>Camera preview</option>
                  ${all_cameras
                    ?.map(
                      (camera) =>
                        `<option value="${camera.camera_id}" ${
                          item?.camera_id == camera.camera_id ? "selected" : ""
                        }>${camera.cameraName}</option>`
                    )
                    .join("")}
              </select>
              
              </div>
            `
                : ""
            } 
              <div class="image_section cursor-pointer" style="cursor: pointer;" onclick="showImageInModal(${
                item?.hardware_setting_id
              })" id="streaming_Id_${item?.hardware_setting_id}">
                <!-- Image or stream content will go here -->
              </div>
            </td>
  
            
            <td style="vertical-align: middle; min-width: 213px;">
              ${
                 item?.is_keep_open_to == 0 || onlyOpenCommand
                        ? ""
                        : `<select class="form-control" required id="command_timer_value_${
                            item?.hardware_setting_id
                          }" onchange="handleTimerChange(${
                            item?.hardware_setting_id
                          },${isAllPermissions})">
                  <option value="">Select Schedule</option>
                    ${all_schedules_command
                      ?.map(
                        (schedule) =>
                          `<option value="${schedule.id}" ${
                            item?.timer == schedule.id ? "selected" : ""
                          }>${schedule.title}</option>`
                      )
                      .join("")}
                </select>` 
              }
              ${timerValue}
            </td>
            <td style="vertical-align: middle;">
              <div class="command_buttons">
                ${show_command_buttons?commandButtons:""}
              </div>
            </td>
            <td style="vertical-align: middle;">
              ${item?.ftp_host?`<i style="padding-right: 4%; align-content: center; vertical-align: middle;" class="fa-solid fa-video fa-2x mr-2 text-success cursor_pointer redirect-playback" data-id="${item?.camera_id}"></i><i style="padding-right: 2%; align-content: center; vertical-align: middle;" class="fa-solid fa-maximize fa-2x mr-2 text-black cursor_pointer camera-fullscreen" title="Fullscreen Preview" data-hsid="${item?.hardware_setting_id}"></i>`:''}
            <!-- Toggle Button with Icon for Nested Table -->
              <button style="align-content: center;" class="btn btn-link" data-toggle="collapse" data-target="#${nestedRowId}" aria-expanded="false" aria-controls="${nestedRowId}" onclick="toggleIcon(this)">
                <i style="align-content: center;" class="fas fa-chevron-right fa-2x"></i>
              </button>
            </td>
          </tr>
  
          <!-- Nested Table Row (collapsible) -->
          <tr id="${nestedRowId}" class="collapse ">
            <td colspan="6">
              <table class="table table-bordered table-head-fixed text-nowrap table-hover datatable-exclude">
                <thead>
                  <tr>
                    <th>Snap</th>
                    <th>Name</th>
                    <th>Type</th>
                    <th>Detail</th>
                    <th>Date</th>
                  </tr>
                </thead>
                <tbody id="nested_table_row_${item.hardware_setting_id}">
        `;

        // Populate the nested table with event data rows
        if (event_data && event_data.length > 0) {
          for (const event of event_data) {
            const timeStamp = formatDateTimeInCommandCenter(event.timestamp);
            var camera_snap = event.camera_snap;
            var property_id = event.property_id;
            var file_name = event.file_name;
            var camera_cell = "";
            if (file_name && file_name.trim() !== "" && file_name.toLowerCase() !== "null" && file_name.toLowerCase() !== "undefined") {
                var camera_snap = `/shared/snapshot_image.php?property_id=${property_id}&image_name=${file_name}`;
                camera_cell = `
                  <div onclick="show_image_modal('snapImageModal', 'snapshotImage', '${camera_snap}')"> 
                    <img src="${camera_snap}" alt="Snap" class="camera-snap-clickable" style="width: 90px; height: 90px; cursor: pointer;" title="Click to view larger image" data-image='${camera_snap}' data-name='Camera Snap'>
              .    </div>
                `;
            } else if (camera_snap && camera_snap.trim() !== "" && camera_snap.toLowerCase() !== "null" && camera_snap.toLowerCase() !== "undefined") {
              camera_cell = `<span class="badge badge-danger">${camera_snap}</span>`;
            }
            else{
              camera_cell = `<span class="badge badge-danger">No Image</span>`; 
            }
            var event_detail = event.eventDetail;
            if (event_detail.includes("Error:")) {
                event_detail = "Could not get status.";
            }
            html += `
              <tr>
                <td>${camera_cell}</td>
                <td>${event.eventName || "N/A"}</td>
                <td>${event.eventType || "N/A"}</td>
                <td>${event_detail || "N/A"}</td>
                <td>${timeStamp || "N/A"}</td>
              </tr>
            `;
          }
        } else {
          // Display a row indicating no events if event_data is empty
          html += `
            <tr>
              <td colspan="4" class="text-center">No event data available</td>
            </tr>
          `;
        }

        // Close nested table and row
        html += `
                </tbody>
              </table>
            </td>
            <td class="hidden_td" style="display:none !important"></td>
            <td class="hidden_td"></td>
            <td class="hidden_td"></td>
            <td class="hidden_td"></td>
            <td class="hidden_td"></td>
          </tr>
        `;
      }

      // Close main table body and container
      html += `
          </tbody>
        </table>
      `;
      html += `</div>`;
    }

    // Append the generated HTML to the container
    container.innerHTML = html;
    isLoadingCommandCenter(false);
    for (const item of data) {
      get_image_url_and_stream(item);
    }
    if ($.fn.DataTable.isDataTable("#command_center_complete_data_table")) {
        $("#command_center_complete_data_table").DataTable().destroy();
    }
    $("#command_center_complete_data_table").DataTable({
        "responsive": true,
        
        "order": [],
        
        "paging": true,
        
        "pageLength": 10,
        // "lengthMenu": [ [10, 25, 50, 100], [10, 25, 50, 100] ],
        "searching": false,
        "createdRow": function(row, data, dataIndex) {
            if (data[4] === "High") {
                $(row).addClass('highlight');
            }
        },
        createdRow: function (row, data, dataIndex) {
          if (data[4] === "High") {
            $(row).addClass('highlight');
          }
        },
    });
    sendSchedulePayloadRequests();
  } catch (error) {
    console.error("Error creating command center table", error);
  }
}

function get_inputs_automations_for_command_center(item) {
  const inputAutomation = all_inputs_automations.find(automation => automation.input_device_id == item.hardware_setting_id);
  if(inputAutomation){
    if(inputAutomation.triggered_by == "APP")return false;
    else return true;
  }else {
    return true;
  }
}

async function create_command_center_mobile(
  dataArray,
  isAllPermissions = false,
  onlyOpenCommand = false
) {
  // Clear payloads to prevent duplicates on view change
  payloads = [];
  allSMSIOschedulePayloads = [];
  let data = dataArray;
  all_devices_in_command_center = data;

  let allCommands;

  if (onlyOpenCommand) {
    allCommands = JSON.stringify({
      Release: false,
      Open: true,
      Holdopen: false,
    });
    isAllPermissions = true;
  } else {
    allCommands = JSON.stringify({
      Release: true,
      Open: true,
      Holdopen: true,
    });
  }

  const container = document.getElementById("door_controls_container");
  container.innerHTML="";
  let html = "";

  if (!data || data.length === 0) {
    html += `
      <div class="text-center p-4 w-100">
          <i class="fas fa-info-circle text-muted fa-3x mb-3"></i>
          <h5 class="text-muted">No Data Found</h5>
          <p class="text-muted">Note: Please add permissions for the logged-in user to access the command center. Only property admins can add permissions.</p>
      </div>`;
  } else {
    for (const item of data) {
      if (item?.calendar_event_id) {
        const command = all_schedules_command.find(
          (ele) => ele.id == item?.calendar_event_id
        );
        try {
          const scheduleDays = await get_events_doors_request({
            getCommandDays: true,
            id: command?.id,
          });
          setScheduleCommand(scheduleDays, item);
        } catch (error) {
          console.log("scheduleDays", error);
        }
      }

      let trueCommands = createPropertyCommandCenterButtons(
        isAllPermissions ? allCommands : item.actions_to_perform
      );
      let commandButtons = Commands_Buttons(
        trueCommands,
        item.hardware_setting_id
      );

      await is_current_date_in_range(item.start, item.end, item);
      const startDate = get_formatted_date_time(new Date(item?.start));

      let endDate = item.end
        ? get_formatted_date_time(new Date(item.end))
        : item.allDay === "true"
        ? get_formatted_date_time(
            new Date(item?.start).setHours(23, 59, 59, 999)
          )
        : "";

      let event_resp = await get_events_doors_request({
        event_of: item?.door_id || item.hardware_setting_id,
        get_device_events_request: true,
      }).catch((err) => console.log("Error fetching events:", err));

      let all_cameras = await get_events_doors_request({
        door_id: item.assigned_door,
        get_all_cameras_of_door_request: true,
      }).catch((err) => console.log("Error fetching cameras:", err));

      const event_data = event_resp?.reverse()?.slice(0, 10);
      
      let show_command_buttons = true;
      if(item?.device_type == "web_Relay"){
        show_command_buttons = get_inputs_automations_for_command_center(item);
      }
      
      html += `
      <div class="col-md-4">
          <div class="card">
            <div class= "card-body">
          <div class="command_center_mobile w-100">
          <div class="door_name">${item.door_name || "N/A"}</div>

          <div class="streaming_">
            ${
              all_cameras?.length > 1
                ? `<div>
                    <select class="form-control" required id="change_preview_value_${
                      item.hardware_setting_id
                    }" 
                      onchange="handle_camera_preview_change(${
                        item.hardware_setting_id
                      }, ${item.assigned_door})">
                      <option value="" disabled>Camera preview</option>
                      ${all_cameras
                        ?.map(
                          (camera) =>
                            `<option value="${camera.camera_id}" ${
                              item?.camera_id == camera.camera_id
                                ? "selected"
                                : ""
                            }>${camera.cameraName}</option>`
                        )
                        .join("")}
                    </select>
                  </div>`
                : ""
            } 
            <div class="image_wrap" id="streaming_Id_${
              item.hardware_setting_id
            }">
              <p class="text-center p-3 m-0">Stream content goes here</p>
            </div>
          </div>

          <div class="commands">
            ${show_command_buttons?commandButtons:""}
          </div>

          <div class="pt-3">
          ${
                  item?.is_keep_open_to == 0 || onlyOpenCommand
                    ? ""
                    : `<select class="form-control" required id="command_timer_value_${
                        item?.hardware_setting_id
                      }" onchange="handleTimerChange(${
                        item?.hardware_setting_id
                      },${isAllPermissions})">
              <option value="">Select Schedule</option>
                ${all_schedules_command
                  ?.map(
                    (schedule) =>
                      `<option value="${schedule.id}" ${
                        item?.timer == schedule.id ? "selected" : ""
                      }>${schedule.title}</option>`
                  )
                  .join("")}
            </select>`
                }
          </div>

          <div style="display:flex;justify-content:end">
            ${item?.ftp_host?`<i style="align-content: center; padding-right: 2%;" class="fa-solid fa-video fa-2x mr-2 text-success cursor_pointer redirect-playback" title="Playback Camera" data-id="${item?.camera_id}"></i><i style="align-content: center;" class="fa-solid fa-maximize fa-2x mr-2 text-black cursor_pointer camera-fullscreen" title="Fullscreen Preview" data-hsid="${item?.hardware_setting_id}"></i>`:''}
            <div class="custom-control custom-switch m-3">
              <input type="checkbox" class="custom-control-input" onchange="show10MostEventsMobile(${
                item.hardware_setting_id
              })" id="show_mobile_events${item.hardware_setting_id}">
              <label class="custom-control-label" for="show_mobile_events${
                item.hardware_setting_id
              }">Show events</label>
            </div>
          </div>

          <div class="table-responsive" style="display:none; max-height: 266px; overflow: auto; box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px; border-radius: 10px;" id="mobile_event_${
            item.hardware_setting_id
          }">
            <table id="command_center_data_table" class="table table-bordered table-head-fixed text-nowrap table-hover">
              <thead>
                <tr>
                  <th>Snap</th>
                  <th>Name</th>
                  <th>Type</th>
                  <th>Event of</th>
                  <th>Date</th>
                </tr>
              </thead>
              <tbody id="nested_table_row_${item.hardware_setting_id}">
                ${
                  event_data && event_data.length > 0
                    ? event_data
                        .map((event) => {
                          var property_id = event.property_id;
                          var file_name = event.file_name;
                          var camera_snap = event.camera_snap;
                          var camera_cell = "";

                          if (file_name && file_name.trim() !== "" && file_name.toLowerCase() !== "null" && file_name.toLowerCase() !== "undefined") {
                            var camera_snap_url = `/shared/snapshot_image.php?property_id=${property_id}&image_name=${file_name}`;
                            camera_cell = `
                              <div onclick="show_image_modal('snapImageModal', 'snapshotImage', '${camera_snap_url}')"> 
                                <img src="${camera_snap_url}" alt="Snap" class="camera-snap-clickable" 
                                  style="width: 90px; height: 90px; cursor: pointer;" 
                                  title="Click to view larger image" 
                                  data-image='${camera_snap_url}' data-name='Camera Snap'>
                              </div>`;
                          } else if (camera_snap && camera_snap.trim() !== "" && camera_snap.toLowerCase() !== "null" && camera_snap.toLowerCase() !== "undefined") {
                            camera_cell = `<span class="badge badge-danger">${camera_snap}</span>`;
                          } else {
                            camera_cell = `<span class="badge badge-danger">No Image</span>`;
                          }

                          var event_detail = event.eventDetail;
                          if (event_detail.includes("Error:")) {
                              event_detail = "Could not get status.";
                          }
                          
                          return `
                            <tr>
                              <td>${camera_cell}</td>
                              <td>${event.eventName || "N/A"}</td>
                              <td>${event.eventType || "N/A"}</td>
                              <td>${event_detail || "N/A"}</td>
                              <td>${formatDateTimeInCommandCenter(event.timestamp) || "N/A"}</td>
                            </tr>`;
                        })
                        .join("")
                    : `<tr><td colspan="4" class="text-center">No event data available</td></tr>`
                }
              </tbody>
            </table>
          </div>
          </div>
        </div>
        </div>
        </div>`;
    }
  }
  container.innerHTML=html;
  isLoadingCommandCenter(false);

  for (const item of data) {
    get_image_url_and_stream(item);
  }
  sendSchedulePayloadRequests();
}

function formatDateTimeInCommandCenter(dateString) {
  let date = null;
  if(dateString.includes("Z") || dateString.includes("z"))date = new Date(dateString); 
  else date = new Date(dateString + "Z");
  return date.toLocaleString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
    hour12: true,
  });
}


function getCsrf_token_command(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/dashboard/settings_requests.php",
      type: "post",
      timeout: 10000, // 10 seconds delay
      data,
      success: function (resp) {
        resolve(resp?.data);
      },
      error: function (xhr, status, error) {
        reject(xhr || error);
      },
    });
  });
}

async function sendSchedulePayloadRequests() {
  try {
    const csrfToken=await getCsrf_token_command({get_csrf_token:true});    
    if(!backendUrl) await getBackendStreamingUrlInCommandCenter({get_streaming_url_request:true})
    allSchedulePayloads?.map(async (ele) => {
      await sendSmsThroughNodeInCommand(
        ele,
        `${backendUrl}/execute_schedule_task`,
        csrfToken
      );
    });

    
    if(allSMSIOschedulePayloads?.length > 0){
      await sendSmsThroughNodeInCommand(
        {data:encryptData(allSMSIOschedulePayloads)},
        `${backendUrl}/execute_sms_schedule_task`,
        csrfToken
      );
    }

  } catch (error) {
    console.log("error in creating cron job",error);
  }
}

function get_hash_url(item_id, action, datetime) {
  return item_id + action + new Date(datetime).toISOString();
}

async function pre_check_for_schedule_event(hash) {
  const event = all_hardwares_settings_events.find(ele => ele.URL === hash);
  if(event) return true;
  return false;
}

async function setScheduleCommand(scheduleData, item) {
  const daysOfWeek = {
    sun: 0,
    mon: 1,
    tue: 2,
    wed: 3,
    thu: 4,
    fri: 5,
    sat: 6,
  };
  
  if(item?.device_type === "SMSIO"){
    scheduleData.forEach((period) => {
      const d = new Date(period.start_date);
      d.setHours(0,0,0,0);
      const periodStartDate=d;
      let periodEndDate = null;
      if (!period?.end_date) {
          const sevenDaysLater = new Date();
          sevenDaysLater.setDate(sevenDaysLater.getDate() + 7);
          periodEndDate = sevenDaysLater.toISOString().slice(0, 10);
          periodEndDate=new Date(periodEndDate)
      }else{
        periodEndDate = new Date(new Date(period?.end_date));
        periodEndDate.setHours(23, 59, 59, 999);
      }
      period.days.forEach((day) => {
        if (day.is_active === 1) {
          const nextDate = getNextDayDate(daysOfWeek[day.day], period.start_time);
          const nextEndDate = getNextDayDate(daysOfWeek[day.day], period.end_time);
          if (nextDate >= periodStartDate && nextDate <= periodEndDate) {
            allSMSIOschedulePayloads.push({
              datetime: nextDate.toISOString(),
              dayname: day?.day,
              time: day?.endTime,
              message_body: getTheMessageBody(item, "Holdopen"),
              from_number: item?.device_invisible_intercom_control_number,
              to_number: item?.device_sms_io_number,
              action: "open SMSIO",
              project_id: signalWireCredentials?.project_id,
              api_token: signalWireCredentials?.api_token,
              space_url: signalWireCredentials?.space_url,
              payload_type: "sms",
              period_start_date: period.start_date,
              period_end_date: period.end_date,
              item_id: item?.hardware_setting_id,
              scheduleId:item?.timer,
              schedule_event:{
                user_id: preferencesObj?.userid || null,
                action:`schedule Open SMSIO`,
                table_name:"hardware_settings",
                record_id:item?.hardware_setting_id,
                user_email:preferencesObj?.user_email || null,
                property_id:sessionStorage.getItem("propertyId") || null,
                old_value:null,
                new_value:null,
                additional_info:`Door opened at ${new Date(nextDate.toISOString()).toLocaleString()}`,
                log_level:"INFO",
                module_name:"Schedule"
              }
            });
            
            allSMSIOschedulePayloads.push({
              datetime: nextEndDate.toISOString(),
              dayname: day?.day,
              time: day?.endTime,
              message_body: getTheMessageBody(item, "Release"),
              from_number: item?.device_invisible_intercom_control_number,
              to_number: item?.device_sms_io_number,
              action: "close SMSIO",
              project_id: signalWireCredentials?.project_id,
              api_token: signalWireCredentials?.api_token,
              space_url: signalWireCredentials?.space_url,
              payload_type: "sms",
              period_start_date: period.start_date,
              period_end_date: period.end_date,
              item_id: item?.hardware_setting_id,
              scheduleId:item?.timer,
              schedule_event:{
                user_id: preferencesObj?.userid || null,
                action:`schedule close SMSIO`,
                table_name:"hardware_settings",
                record_id:item?.hardware_setting_id,
                user_email:preferencesObj?.user_email || null,
                property_id:sessionStorage.getItem("propertyId") || null,
                old_value:null,
                new_value:null,
                additional_info:`Door closed at ${new Date(nextDate.toISOString()).toLocaleString()}`,
                log_level:"INFO",
                module_name:"Schedule"
              }
            });
          }
        }
      });
    });
  }else {
    scheduleData.forEach((period) => {
      // const periodStartDate = new Date(new Date().toLocaleDateString());
      const d = new Date(period.start_date);
      d.setHours(0,0,0,0);
      const periodStartDate=d;
      
      let periodEndDate = null;
        if (!period?.end_date) {
          const sevenDaysLater = new Date();
          sevenDaysLater.setDate(sevenDaysLater.getDate() + 7);
          periodEndDate = sevenDaysLater.toISOString().slice(0, 10);
          periodEndDate=new Date(periodEndDate)
      }else{
        periodEndDate = new Date(new Date(period?.end_date));
        periodEndDate.setHours(23, 59, 59, 999);
      }
      period.days.forEach((day) => {
        if (day.is_active === 1) {
          // Get the next occurrence of this day
          const nextDate = getNextDayDate(daysOfWeek[day.day], period.start_time);
          const nextEndDate = getNextDayDate(daysOfWeek[day.day], period.end_time);
          
          if (nextDate >= periodStartDate && nextDate <= periodEndDate) {
            const encryptedUrl1 = encryptData({
              url: `${item?.completeUrl}?${item?.output}=1`,
            });

            payloads.push({
              datetime: nextDate.toISOString(),
              dayname: day.day,
              time: period.end_time,
              url: encryptedUrl1,
              action: "open",
              schedule_request: true,
              period_start_date: period.start_date,
              period_end_date: period.end_date,
              item_id: item?.hardware_setting_id,
              scheduleId:item?.timer,
              schedule_event:{
                user_id: preferencesObj?.userid || null,
                action:`schedule open`,
                table_name:"hardware_settings",
                record_id:item?.hardware_setting_id,
                user_email:preferencesObj?.user_email || null,
                property_id:sessionStorage.getItem("propertyId")||null,
                old_value:null,
                new_value:null,
                additional_info:`Door opened at ${new Date(nextDate.toISOString()).toLocaleString()}`,
                log_level:"INFO",
                module_name:"Schedule"
              }
            });
  
            const encryptedUrl2 = encryptData({
              url: `${item?.completeUrl}?${item?.output}=0`,
            });
            payloads.push({
              datetime: nextEndDate.toISOString(),
              url: encryptedUrl2,
              dayname: day.day,
              time: period.end_time,
              action: "close",
              schedule_request: true,
              period_start_date: period.start_date,
              period_end_date: period.end_date,
              item_id: item?.hardware_setting_id,
              scheduleId:item?.timer,
              schedule_event:{
                user_id: preferencesObj?.userid || null,
                action:`schedule close`,
                table_name:"hardware_settings",
                record_id:item?.hardware_setting_id,
                user_email:preferencesObj?.user_email || null,
                property_id:sessionStorage.getItem("propertyId") || null,
                old_value:null,
                new_value:null,
                additional_info:`Door closed at ${new Date(nextEndDate.toISOString()).toLocaleString()}`,
                log_level:"INFO",
                module_name:"Schedule"
              }
            });
          }
        }
      });
    });
    allSchedulePayloads = payloads;
  } 
  
}

function getNextDayDate(targetDay, time) {
  const [hours, minutes, seconds] = time.split(":").map(Number);
  const now = new Date();
  const currentDay = now.getDay();
  let daysToAdd = targetDay - currentDay;
  if (daysToAdd < 0) daysToAdd += 7; // Move to the next week if necessary
  const nextDate = new Date();
  nextDate.setDate(now.getDate() + daysToAdd);
  nextDate.setHours(hours, minutes, seconds, 0);
  return nextDate;
}

function show10MostEventsMobile(id) {
  const isShowEvents = document.getElementById(`show_mobile_events${id}`);
  const eventsEle = document.getElementById(`mobile_event_${id}`);
  if (isShowEvents?.checked) {
    eventsEle.style.display = "block";
  } else {
    eventsEle.style.display = "none";
  }
}

async function handle_camera_preview_change(settings_id, assigned_door) {
  let value = document.getElementById(
    `change_preview_value_${settings_id}`
  ).value;
  await get_events_doors_request({
    EditDoorInSettingsRequest: true,
    id: assigned_door,
    camera_id: value ? value : "",
  });
}

function createPropertyCommandCenterButtons(commands) {
  try {
    const decodedData = commands.replace(/&quot;/g, '"');
    let data = JSON.parse(decodedData);
    return filterTrueValues(data);
  } catch (error) {
    return "";
  }
}

function Commands_Buttons(commands, hardware_setting_id) {
  let buttonsHtml = "";
  const device = all_devices_in_command_center?.find(
    (ele) => ele.hardware_setting_id == hardware_setting_id
  );
  const commandStyles = {
    Open: { color: "#51a02e", text: "Open" },
    Release: { color: "#bf3333ed", text: "Release" },
    Holdopen: { color: "#007bff", text: "Hold Open" },
  };

  Object.keys(commands).forEach((command) => {
    if (commands[command] === true) {
      const { color, text } = commandStyles[command] || {
        color: "#007bff",
        text: command,
      };
      const style_text = `background-color:${color}; display: flex; align-items: center; padding: 5px 10px; border: none; border-radius: 4px; color: white; cursor: pointer;`;
      if (command == "Holdopen" && device?.device_model == "UC300") {
        buttonsHtml += `
        <button style="${style_text}" 
                onclick="control_command_door(${hardware_setting_id}, '${command}')">
          ${text}
          <img src="/include/images/loader.gif" 
               id="output_status_loading_${hardware_setting_id}_${command}" 
               style="width: 20px; margin-left: 5px; display: none;" 
               alt="">
        </button>
        <span class="schedule_command" onclick="control_command_door(${hardware_setting_id}, '1h')">1h</span>
        <span class="schedule_command" onclick="control_command_door(${hardware_setting_id}, '2h')">2h</span>
        <span class="schedule_command" onclick="control_command_door(${hardware_setting_id}, '4h')">4h</span>
      `;
        return;
      }

      if (command == "Holdopen" && device?.device_model == "UC1414") {
        buttonsHtml += `
        <button style="${style_text}" 
                onclick="control_command_door(${hardware_setting_id}, '${command}')">
          ${text}
          <img src="/include/images/loader.gif" 
               id="output_status_loading_${hardware_setting_id}_${command}" 
               style="width: 20px; margin-left: 5px; display: none;" 
               alt="">
        </button>`;
        
        if (device?.output === "output 1") {
          buttonsHtml += `
          <span class="schedule_command d-flex" onclick="control_command_door(${hardware_setting_id}, '1h')">1h <img src="/include/images/loader.gif" 
                 id="output_status_loading_${hardware_setting_id}_1h" 
                 style="width: 20px; margin-left: 5px; display: none;" 
                 alt=""></span>
          <span class="schedule_command d-flex" onclick="control_command_door(${hardware_setting_id}, '4h')">4h <img src="/include/images/loader.gif" 
                 id="output_status_loading_${hardware_setting_id}_4h" 
                 style="width: 20px; margin-left: 5px; display: none;" 
                 alt=""></span>
          <span class="schedule_command d-flex" onclick="control_command_door(${hardware_setting_id}, '8h')">8h <img src="/include/images/loader.gif" 
                 id="output_status_loading_${hardware_setting_id}_8h" 
                 style="width: 20px; margin-left: 5px; display: none;" 
                 alt=""></span>`;
        }
        return;
      }

      if (command == "Holdopen") {
        buttonsHtml += `
        <button style="${style_text}" 
                onclick="control_command_door(${hardware_setting_id}, '${command}')">
          ${text}
          <img src="/include/images/loader.gif" 
               id="output_status_loading_${hardware_setting_id}_${command}" 
               style="width: 20px; margin-left: 5px; display: none;" 
               alt="">
        </button>
        <span class="schedule_command d-flex" onclick="control_command_door_schedule(${hardware_setting_id}, '1h')">1h <img src="/include/images/loader.gif" 
               id="output_status_loading_${hardware_setting_id}_1h" 
               style="width: 20px; margin-left: 5px; display: none;" 
               alt=""></span>
        <span class="schedule_command d-flex" onclick="control_command_door_schedule(${hardware_setting_id}, '2h')">2h <img src="/include/images/loader.gif" 
               id="output_status_loading_${hardware_setting_id}_2h" 
               style="width: 20px; margin-left: 5px; display: none;" 
               alt=""></span>
        <span class="schedule_command d-flex" onclick="control_command_door_schedule(${hardware_setting_id}, '4h')">4h <img src="/include/images/loader.gif" 
               id="output_status_loading_${hardware_setting_id}_4h" 
               style="width: 20px; margin-left: 5px; display: none;" 
               alt=""></span>
      `;
        return;
      }
      buttonsHtml += `
        <button style="${style_text}" 
                onclick="control_command_door(${hardware_setting_id}, '${command}')">
          ${text}
          <img src="/include/images/loader.gif" 
               id="output_status_loading_${hardware_setting_id}_${command}" 
               style="width: 20px; margin-left: 5px; display: none;" 
               alt="">
        </button>
      `;
    }
  });

  return buttonsHtml;
}

async function control_command_door_schedule(id, type) {
  const outputLoadingEle = document.getElementById(
    `output_status_loading_${id}_${type}`
  );
  if (isLoadingToAddNewEvent) return;
  isLoadingToAddNewEvent = true;
  let url = "";
  let doorSetting = all_devices_in_command_center.find(
    (ele) => ele.hardware_setting_id == id
  );
  try {
    if (outputLoadingEle) outputLoadingEle.style.display = "block";
    if(!backendUrl) await getBackendStreamingUrlInCommandCenter({get_streaming_url_request:true})
    if (!backendUrl) {
      throw new Error("Please add Server VOIP URL");
    }
    url = `${doorSetting?.completeUrl}?${doorSetting?.output}=0`;
    if (url) {
      const csrfToken=await getCsrf_token_command({get_csrf_token:true})
      const payload = getPayloadForCronJob(url, type, "close",id);
      await sendSmsThroughNodeInCommand(
        payload,
        `${backendUrl}/execute_schedule_task`,
        csrfToken
      );

      url = `${doorSetting?.completeUrl}?${doorSetting?.output}=1`;
      await execute_command_door(url,doorSetting?.device_user_name,doorSetting?.device_password);
      let eventPayload = {
        eventName: type,
        eventType: "Relay",
        eventOf: doorSetting?.door_id ? doorSetting?.door_id : id,
        URL: url,
        eventDetail: `${doorSetting?.output} has ${type}`,
        property_id: sessionStorage.getItem("propertyId"),
        add_hardwares_settings_events: true,
      };
      await add_control_event_request(eventPayload);
      await update_nested_command_events(
        doorSetting?.door_id ? doorSetting?.door_id : id
      );

      if (outputLoadingEle) outputLoadingEle.style.display = "none";
    }
    isLoadingToAddNewEvent = false;
  } catch (error) {
    try {
      let eventPayloadForRejectedRequest = {
        eventName: `${type} Rejected`,
        eventType: "Relay rejected",
        eventOf: doorSetting?.door_id ? doorSetting?.door_id : id,
        URL: url,
        eventDetail: `Error: ${error?.error || error}`,
        property_id: sessionStorage.getItem("propertyId"),
        add_hardwares_settings_events: true,
      };
      await add_control_event_request(eventPayloadForRejectedRequest);
      await update_nested_command_events(
        doorSetting?.door_id ? doorSetting?.door_id : id
      );
    } catch (error) {
      console.log("error catch: ", error);
    }
    isLoadingToAddNewEvent = false;
    if (outputLoadingEle) outputLoadingEle.style.display = "none";
    console.log("error: ", error);
    show_command_center_toast_message(error);
  }
}

function getPayloadForCronJob(url, type, action,id=null) {
  const data = encryptData({ url });
  const currentTime = new Date();
  let hoursToAdd = 0;
  switch (type) {
    case "1h":
      hoursToAdd = 1;
      break;
    case "2h":
      hoursToAdd = 2;
      break;
    case "4h":
      hoursToAdd = 4;
      break;
    case "8h":
      hoursToAdd = 8;
      break;
    default:
      console.error("Invalid type:", type);
      return null;
  }
  const futureTime = new Date(
    currentTime.getTime() + hoursToAdd * 60 * 60 * 1000
  );
  return {
    dateTime: futureTime.toISOString(),
    data,
    action,
    time_ahead: type,
    schedule_event:{
      user_id: preferencesObj?.userid || null,
      action:`schedule ${type}`,
      table_name:"hardware_settings",
      record_id:id,
      user_email:preferencesObj?.user_email || null,
      property_id:sessionStorage.getItem("propertyId")||null,
      old_value:null,
      new_value:null,
      additional_info:`Closed the door after ${type}`,
      log_level:"INFO",
      module_name:"Schedule"
    }
  };
}


function filterTrueValues(commands) {
  const result = {};
  Object.keys(commands).forEach((key) => {
    if (commands[key] === true) {
      result[key] = commands[key];
    }
  });
  return result;
}

async function is_current_date_in_range(start, end, setting) {
  if (!start) return false;
  const startDate = new Date(start);

  if (setting.allDay == "true") {
    const lastMomentOfDay = new Date(startDate);
    lastMomentOfDay.setHours(23, 59, 59, 999); // Last moment of the day
    end = lastMomentOfDay;
  }

  let formattedEndDate;
  if (end) formattedEndDate = end;
  else {
    const today = new Date();
    today.setHours(23, 59, 0, 0);
    formattedEndDate = today;
  }
  const endDate = new Date(formattedEndDate);
  const currentDate = new Date();

  if (currentDate >= startDate && currentDate <= endDate) {
    await control_command_door(setting?.hardware_setting_id, "Holdopen");
  }
}

function get_formatted_date_time(dateObject) {
  const day = String(dateObject.getDate()).padStart(2, "0"); // Day
  const month = String(dateObject.getMonth() + 1).padStart(2, "0"); // Month (Months are 0-based, so add 1)
  const year = dateObject.getFullYear(); // Year

  const hours = String(dateObject.getHours()).padStart(2, "0"); // Hours
  const minutes = String(dateObject.getMinutes()).padStart(2, "0"); // Minutes
  const seconds = String(dateObject.getSeconds()).padStart(2, "0"); // Seconds

  // Combine into desired format
  const formattedDate = `${day}-${month}-${year}`;
  const formattedTime = `${hours}:${minutes}`;
  return `${formattedDate} ${formattedTime}`;
}

function toggleIcon(button) {
  const icon = button.querySelector("i");
  const isExpanded = button.getAttribute("aria-expanded") === "true";
  if (!isExpanded) {
    icon.classList.remove("fa-chevron-right");
    icon.classList.add("fa-chevron-down");
  } else {
    icon.classList.remove("fa-chevron-down");
    icon.classList.add("fa-chevron-right");
  }
}

async function get_events_doors_request(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/command_center/command_center_requests.php",
      type: "POST",
      timeout: 10000, // 10 seconds delay
      data,
      success: function (resp) {
        if (data?.EditDoorInSettingsRequest) window.location.reload();
        resolve(resp.data);
      },
      error: function (xhr, status, error) {
        if (xhr?.responseJSON?.error) reject(xhr?.responseJSON?.error);
        else reject(error);
      },
    });
  });
}

async function get_image_url_and_stream(item, toModal = false) {
  if (!request_pending_flags[item.hardware_setting_id]) {
    request_pending_flags[item.hardware_setting_id] = false;
  }
  if (item.liveImageURL) {
    // const csrfToken=await getCsrf_token_command({get_csrf_token:true});    
    if(!backendUrl) await getBackendStreamingUrlInCommandCenter({get_streaming_url_request:true})
    const data=await sendSmsThroughNodeInCommand(
      {},
      `${backendUrl}/getImageStreamingingUrl`,
      // csrfToken
    );
    connectImageSocketCommand(data?.url,item);
  } else {
    const streaming_id = `#streaming_Id_${item.hardware_setting_id}`;
    const imagePreview = document.querySelector(streaming_id);
    const windowWidth = window.innerWidth;
    let padding = "6px 1px";
    if (windowWidth < 800) padding = "50px 1px";
    imagePreview.innerHTML = `<div style="padding: ${padding};
    text-align: center;">No Camera is assigned to the door</div`;
  }
}

function connectImageSocketCommand(wsUrl,item) {
  if (wsUrl) {
    const ws = new WebSocket(wsUrl);
    const cameraId = item?.hardware_setting_id;
    
    // Store the WebSocket connection
    activeWebSocketConnections[cameraId] = ws;
    
    ws.onopen = () => {
      ws.send(JSON.stringify({
        event: "image_request",
        image_url: item.liveImageURL,
        pass:item?.password,
        user:item?.userName
      }));
      console.log("WebSocket connection established for camera:", cameraId);
    };
    ws.onmessage = (event) => {
      const message = JSON.parse(event.data);

      if (message.event === "image_data") {
        // Only show this camera's image if it's the active modal camera or if no modal is open
        if (modalActiveCameraId === null || modalActiveCameraId === cameraId) {
          create_image_streaming(message.image, cameraId);
        }
        
        setTimeout(() => {
          ws.send(JSON.stringify({
            event: "image_request",
            image_url: item.liveImageURL,
            pass:item?.password,
            user:item?.userName
          }));
        }, 1000);
      }
    };
    ws.onclose = async () => {
      // Remove from active connections when closed
      delete activeWebSocketConnections[cameraId];
    };
  } else {
    console.error("Failed to get SMS status:", result.error_message);
  }
}

function create_image_streaming(base64ImageData, itemId) {
  let streaming_id = "";
  
  // Better modal detection using multiple methods
  const modal = document.getElementById("show_image_modal");
  const isModalOpen = modal && (
    modal.classList.contains("show") || 
    modal.style.display === "block" ||
    modal.getAttribute("aria-hidden") === "false"
  );
  
  if (isModalOpen && modalActiveCameraId === itemId) {
    // Only show this camera's image in modal if it's the active modal camera
    streaming_id = "#show_image_in_modal";
  } else if (!isModalOpen) {
    // Show in table cell if modal is not open
    streaming_id = `#streaming_Id_${itemId}`;
  } else {
    // Don't show this camera's image if modal is open but this isn't the active camera
    return;
  }

  const imagePreview = document.querySelector(streaming_id);
  if (imagePreview) {
    imagePreview.innerHTML = ""; // Clear previous content if any
    const imageBox = document.createElement("div");
    imageBox.classList.add("image_box");
    const img = document.createElement("img");
    img.src = `data:image/jpeg;base64,${base64ImageData}`;
    img.style.width = "100%";
    img.style.objectFit = "contain";
    imageBox.appendChild(img);
    imagePreview.appendChild(imageBox);
  } else {
    console.error(`Element with ID ${streaming_id} not found for itemId: ${itemId}`);
  }
}

function show_image_modal(model_id, image_id, image){
  document.getElementById(image_id).src = image;
  $("#"+model_id).modal('show');
}

function send_image_Request(data) {
  return $.ajax({
    url: "/include/property_builder/command_center/command_center_requests.php",
    type: "post",
    timeout: 10000, // 10 seconds delay
    data,
    success: function (response) {
      return response;
    },
    error: function (xhr, status, error) {
      return Promise.reject(error);
    },
  });
}

isLoadingToAddNewEvent = false;

async function control_command_door(id, type, redirect = true) {
  const outputLoadingEle = document.getElementById(
    `output_status_loading_${id}_${type}`
  );
  if (isLoadingToAddNewEvent) return;
  isLoadingToAddNewEvent = true;
  let url = "";
  let doorSetting = all_devices_in_command_center.find(
    (ele) => ele.hardware_setting_id == id
  );

  try {
    if (outputLoadingEle) outputLoadingEle.style.display = "block";
    if (doorSetting?.device_type == "SMSIO") {
      await control_command_door_for_sms(doorSetting, type, id,outputLoadingEle);
      return;
    }

    if (type == "Open") {
      url = `${doorSetting?.completeUrl}?${doorSetting?.output}=2`;
      const inputStatusArray = await execute_command_door(doorSetting?.completeUrl,doorSetting?.device_user_name,doorSetting?.device_password);
      const isAllowed = await is_allowed_hardware_automations_for_command_center(inputStatusArray.inputs, doorSetting);
      if (!isAllowed.isAllowed) {
        throw {
          command_failed: true,
          error: isAllowed.message
        };
      }
    } else if (type == "Release") {
      url = `${doorSetting?.completeUrl}?${doorSetting?.output}=0`;
    } else if (type == "Holdopen") {
      const commandValue = 2;
      const relayMatch = doorSetting?.output?.match(/\d+$/);
      const relayNum = relayMatch ? relayMatch[0] : null;
      if (relayNum) {
        const pulseTimeKey = `pulseTime${relayNum}`;
        const pulseTime = doorSetting?.sms_duration ? doorSetting?.sms_duration*60 : 60;
        url = `${doorSetting?.completeUrl}?${pulseTimeKey}=${pulseTime}&${doorSetting?.output}=${commandValue}`;
      } else {
        url = `${doorSetting?.completeUrl}?${doorSetting?.output}=${commandValue}`;
      }
    }
    
    if (url) {
      const statusArray = await execute_command_door(url,doorSetting?.device_user_name,doorSetting?.device_password);
      let status =
        statusArray?.outputs?.find((ele) => ele.key == doorSetting?.output)
          ?.value == 1
          ? "On"
          : "Off";
      if (type === "release") status = "Off";
      let eventPayload = {
        eventName: type,
        eventType: "Relay",
        eventOf: doorSetting?.door_id ? doorSetting?.door_id : id,
        URL: url,
        eventDetail: `${doorSetting?.output} has ${type}`,
        property_id: sessionStorage.getItem("propertyId"),
        add_hardwares_settings_events: true,
      };
      await add_control_event_request(eventPayload);
      await update_nested_command_events(
        doorSetting?.door_id ? doorSetting?.door_id : id
      );
      if (outputLoadingEle) outputLoadingEle.style.display = "none";
    }
    isLoadingToAddNewEvent = false;
  } catch (error) {
    if (error?.command_failed) {
      try {
        let eventPayloadForRejectedRequest = {
          eventName: "Rejected",
          eventType: "Relay rejected",
          eventOf: doorSetting?.door_id ? doorSetting?.door_id : id,
          URL: url,
          eventDetail: `Error: ${error?.error}`,
          property_id: sessionStorage.getItem("propertyId"),
          add_hardwares_settings_events: true,
        };
        await add_control_event_request(eventPayloadForRejectedRequest);
        await update_nested_command_events(
          doorSetting?.door_id ? doorSetting?.door_id : id
        );
      } catch (error) {
        console.log("error catch: ", error);
      }
    }
    show_command_center_toast_message(error?.error || error);
    isLoadingToAddNewEvent = false;
    if (outputLoadingEle) outputLoadingEle.style.display = "none";
    console.log("error: ", error);
  }
}

async function is_allowed_hardware_automations_for_command_center(inputsArray, doorSetting) {
  try {
    const inputStatusMap = {};
    inputsArray.forEach(input => {
      inputStatusMap[input.key] = input.value;
    });

    const hardwareAutomations = await get_hardware_automations_request_for_command_center({
      get_hardware_automations_by_id_request: true,
      device_id: doorSetting?.hardware_setting_id
    });

    if (!hardwareAutomations || hardwareAutomations.length === 0) {
      console.log("No hardware automations found allowed");
      return {isAllowed: true, message: "No hardware automations found"};
    }

    for (const automation of hardwareAutomations) {
      const key = automation.input;
      const requiredStatus = automation.input_status;
      const currentValue = inputStatusMap[key];
      
      if(automation.triggered_by !=="WEBSITE" && automation.triggered_by !=="BOTH") {
        continue;
      }
      if (
        (requiredStatus === "ON" && currentValue === "1") ||
        (requiredStatus === "OFF" && currentValue === "0")
      ) {
        const schedulePermission = await checkSchedulePermission(automation, doorSetting);
        if (!schedulePermission.isAllowed) {
          const schedulePermissionForUser = await checkSchedulePermissionForUser(automation);
          if (!schedulePermissionForUser.isScheduleFound && !schedulePermission.isScheduleFound) { // if both schedules are not found open the door
            console.log("if both schedules are not found open the door");
            return {isAllowed: true, message: schedulePermission.message};
          }else if(schedulePermissionForUser.isAllowed && schedulePermissionForUser.isScheduleFound){ // if user schedule is found and allowed, open the door
            console.log("if user schedule is found and allowed, open the door");
            return {isAllowed: true, message: schedulePermissionForUser.message};            
          }else if(!schedulePermissionForUser.isScheduleFound && !schedulePermission.isAllowed) { // if user schedule is not found and door schedule is not allowed, do not open the door
            console.log("if user schedule is not found and door schedule is not allowed, do not open the door");
            return {isAllowed: false, message: schedulePermission.message};
          }else { // if user schedule is found and allowed, open the door
            console.log("if user schedule is found and allowed, open the door");
            return {isAllowed: false, message: schedulePermissionForUser.message};
          }
        }else {
          console.log("device schedule is within dates");
          return {isAllowed: true, message: "Hardware automation allowed"};
        }
      }
    }
    return {isAllowed: false, message: "No valid Input sensor automation allowed"};
  } catch (error) {
    console.error("Error in is_allowed_hardware_automations_for_command_center: ", error);
    return {isAllowed: false, message: `${error}`};
  }
}

async function checkSchedulePermission(automation_details, doorSetting) {
  if(!doorSetting?.timer) return {isAllowed: false, message: "Access not allowed without schedule", isScheduleFound: false};
  const scheduleData = await get_schedules_request_for_command_center({
    get_weekly_schedule_by_id:true, 
    property_id: sessionStorage.getItem("propertyId"), 
    schedule_id: doorSetting?.timer
  });
  const isWithinSchedule = checkIfWithinSchedule(scheduleData, automation_details);
  return {
    isAllowed: isWithinSchedule.isAllowed,
    message: isWithinSchedule.message,
    isScheduleFound: true,
  };
}

async function checkSchedulePermissionForUser(automation_details) {
  if(!automation_details?.user_schedule){
    return {isAllowed: true, message: "schedule not found in input automation", isScheduleFound: false};
  }
  const scheduleData = await get_schedules_request_for_command_center({
    get_weekly_schedule_by_id:true, 
    property_id: sessionStorage.getItem("propertyId"), 
    schedule_id: automation_details?.user_schedule
  });
  const isWithinSchedule = checkIfWithinSchedule(scheduleData, automation_details);
  return {
    isAllowed: isWithinSchedule.isAllowed,
    message: isWithinSchedule.message,
    isScheduleFound: true,
  };
}

function checkIfWithinSchedule(scheduleData, automation_details) {
  try {
    // 1) Fast exits and normalization
    if (!scheduleData) {
      return { isAllowed: true, message: `Access allowed without schedule` };
    }; // no schedule => allow
    const periods = Array.isArray(scheduleData?.periods) ? scheduleData.periods : [];
    if (periods.length === 0) return true;

    // 2) Time helpers
    const now = new Date();
    const tzOffsetMs = now.getTimezoneOffset() * 60 * 1000;
    const todayIdx = now.getDay(); // 0-6
    const dayKeys = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
    const todayKey = dayKeys[todayIdx];

    const toDateOnly = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
    const todayDateOnly = toDateOnly(now);

    const parseTimeOn = (baseDate, hhmmOrHhmmss) => {
      if (!hhmmOrHhmmss) return null;
      const [hh, mm = '0', ss = '0'] = hhmmOrHhmmss.split(':');
      const d = new Date(baseDate);
      d.setHours(parseInt(hh, 10), parseInt(mm, 10), parseInt(ss, 10), 0);
      return d;
    };

    const inDateRange = (startDateStr, endDateStr) => {
      if (!startDateStr && !endDateStr) return true;
      const start = startDateStr ? toDateOnly(new Date(startDateStr)) : null;
      const end = endDateStr ? toDateOnly(new Date(endDateStr)) : null;
      if (start && todayDateOnly < start) return false;
      if (end && todayDateOnly > end) return false;
      return true;
    };

    // 3) Evaluate each period; if any matches -> allowed
    for (const period of periods) {
      // 3a) Date bounds
      if (!inDateRange(period?.start_date, period?.end_date)) continue;

      // 3b) Per-day override
      const dayInfo = period?.days?.[todayKey] || null;
      if (dayInfo && dayInfo.is_active === false) continue;
      const isAllDay =
        scheduleData?.is_all_day === true ||
        period?.is_all_day === true ||
        dayInfo?.is_all_day === true;

      if (isAllDay) {
        return { isAllowed: true, message: `Within the schedule start and end time` };
      }

      const startStr = (dayInfo?.day_startTime && dayInfo.day_startTime !== 'null')
        ? dayInfo.day_startTime
        : period?.start_time;
      const endStr = (dayInfo?.day_endTime && dayInfo.day_endTime !== 'null')
        ? dayInfo.day_endTime
        : period?.end_time;

      if (!startStr || !endStr) continue;

      let start = parseTimeOn(now, startStr);
      let end = parseTimeOn(now, endStr);

      // 3e) Overnight handling (end <= start means window passes midnight)
      if (end <= start) {
        end = new Date(end.getTime() + 24 * 60 * 60 * 1000);
      }

      // 3f) Optional small grace to avoid flakiness at boundaries (e.g., ±1s)
      const graceMs = 1000;
      const within = now.getTime() + 0 >= start.getTime() - graceMs && now.getTime() <= end.getTime() + graceMs;
      if (within) {
        return { isAllowed: true, message: `Within the schedule start and end time` };
      }
    }

    return { isAllowed: false, message: `Outside the schedule start and end time` };
    // return Object.assign(false, { meta: { reason: 'outside all windows', day: dayKeys[todayIdx] } });
  } catch (error) {
    console.warn('checkIfWithinSchedule error:', error);
    // fail-open to avoid blocking due to parse issues; adjust to false if you prefer fail-closed
    return Object.assign(true, { meta: { reason: 'error parsing schedule (fail-open)', error: String(error) } });
  }
}

async function get_schedules_request_for_command_center(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/schedule/schedule_requests.php",
      type: "POST",
      timeout: 10000, // 10 seconds delay
      data,
      success: function (resp) {
        try {
          resolve(resp.data);
        } catch (error) {
          console.error("Error parsing response data: ", error);
          reject(error);
        }
      },
      error: function (xhr, status, error) {
        if (xhr?.responseJSON?.error) reject(xhr?.responseJSON?.error);
        else reject(error);
      },
    });
  });
}

async function get_hardware_automations_request_for_command_center(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/hardwares/hardwares_request.php",
      type: "POST",
      timeout: 10000, // 10 seconds delay
      data,
      success: function (resp) {
        try {
          resolve(resp.data);
        } catch (error) {
          console.error("Error parsing response data: ", error);
          reject(error);
        }
      },
      error: function (xhr, status, error) {
        if (xhr?.responseJSON?.error) reject(xhr?.responseJSON?.error);
        else reject(error);
      },
    });
  });
}

let testingRowDetailsCommand = {
  isTesting: false,
  testingId: "",
  command_type: "",
  message_body: "",
};
async function control_command_door_for_sms(doorSetting, type, id,loadingElem=null) {
  try {
    const message_body = getTheMessageBody(doorSetting, type);
    if (!signalWireCredentials) {
      show_command_center_toast_message("Please add signal wire credentials.");
      return;
    }
    let payload = {
      from_number: doorSetting?.device_invisible_intercom_control_number,
      to_number: doorSetting?.device_sms_io_number,
      message_body,
      project_id: signalWireCredentials?.project_id,
      space_url: signalWireCredentials?.space_url,
      api_token: signalWireCredentials?.api_token,
    };

    if(!backendUrl) await getBackendStreamingUrlInCommandCenter({get_streaming_url_request:true})
    if (!backendUrl) {
      if(loadingElem) loadingElem.style.display = "none";
      throw new Error("Please add Server VOIP URL (Nodejs url)");
    }

    const statusDisplay = document.getElementById("smsTestingStatusCommand");
    if (statusDisplay) statusDisplay.innerHTML = "";
    testingRowDetailsCommand.isTesting = true;
    testingRowDetailsCommand.testingId = doorSetting?.door_id
      ? doorSetting?.door_id
      : id;
    testingRowDetailsCommand.command_type = type;
    testingRowDetailsCommand.message_body = message_body;
    updateStatusMessageCommand("Sending");
    $("#testing_hardware_sms_device_command").modal({
      backdrop: "static",
      keyboard: false,
    });

    const data = encryptData(payload);
    const csrfToken=await getCsrf_token_command({get_csrf_token:true})
    let smsTested = await sendSmsThroughNodeInCommand(
      { data },
      `${backendUrl}/send_sms`,
      csrfToken
    );

    if (smsTested?.socket) { 
      connectSocketCommand(smsTested.socket);
    }

    let fetchStatus = {
      message_sid: smsTested?.message?.sid,
      project_id: signalWireCredentials?.project_id,
      space_url: signalWireCredentials?.space_url,
      api_token: signalWireCredentials?.api_token,
    };

    const fetchStatusEncryption = encryptData(fetchStatus);
    let status = "queued";
    let smsStatus = undefined;
    let statusCounter = 0;
    while (status == "queued" || status == "initiated" || status == "sent") {
      smsStatus = await sendSmsThroughNodeInCommand(
        { data: fetchStatusEncryption },
        `${backendUrl}/fetch_sms_status`,
        csrfToken
      );
      status = smsStatus?.message?.status;
      updateStatusMessageCommand(status);
      statusCounter++;
      if (statusCounter > 40) {
        smsStatus.message.status = "Not Delivered";
        break;
      }
    }
    if (smsStatus?.message?.status == "delivered") {
      isLoadingToAddNewEvent = false;
      updateStatusMessageCommand("delivered");
      updateStatusMessageCommand("Waiting for device response", "timer");
    }
  } catch (error) {
    try {
      let eventPayloadForRejectedRequest = {
        eventName: "Rejected",
        eventType: "SMS rejected",
        eventOf: doorSetting?.door_id ? doorSetting?.door_id : id,
        URL: "",
        eventDetail: `Error: ${error}`,
        property_id: sessionStorage.getItem("propertyId"),
        add_hardwares_settings_events: true,
      };
      await add_control_event_request(eventPayloadForRejectedRequest);
      await update_nested_command_events(
        doorSetting?.door_id ? doorSetting?.door_id : id
      );
    } catch (error) {
      console.log("error catch: ", error);
    }

    const outputLoadingEle = document.getElementById(
      `output_status_loading_${testingRowDetailsCommand.testingId}_${testingRowDetailsCommand.command_type}`
    );
    if (outputLoadingEle) outputLoadingEle.style.display = "none";
    setTimeout(() => {
      $("#testing_hardware_sms_device_command").modal("hide");
    }, 300);
    isLoadingToAddNewEvent = false;
    show_command_center_toast_message(error);
  }
}
function getTheMessageBody(doorSetting, type) {
  let message_body = "";
  if (doorSetting?.device_model == "UC300") {
    if (type == "Open") {
      message_body = `${doorSetting?.device_password};${doorSetting?.output},1,${doorSetting?.sms_duration}`;
    } else if (type == "Release") {
      message_body = `${doorSetting?.device_password};${doorSetting?.output},0,0`;
    } else if (type == "Holdopen") {
      message_body = `${doorSetting?.device_password};${doorSetting?.output},1,0`;
    } else if (type == "1h") {
      message_body = `${doorSetting?.device_password};${doorSetting?.output},1,3600`; // 1hours
    } else if (type == "2h") {
      message_body = `${doorSetting?.device_password};${doorSetting?.output},1,7200`; // 2hours
    } else if (type == "4h") {
      message_body = `${doorSetting?.device_password};${doorSetting?.output},1,14400`; // 4hours
    }
  } else {
    if (type == "Open") {
      message_body = `${doorSetting?.output} momentary, Reply-STOP-to-opt-out`;
    } else if (type == "Release") {
      message_body = `${doorSetting?.output} release, Reply-STOP-to-opt-out`;
    } else if (type == "Holdopen") {
      message_body = `${doorSetting?.output} hold open, Reply-STOP-to-opt-out`;
    } else if (type == "1h") {
      message_body = `${doorSetting?.output} 1 hour, Reply-STOP-to-opt-out`;
    } else if (type == "4h") {
      message_body = `${doorSetting?.output} 4 hour, Reply-STOP-to-opt-out`;
    } else if (type == "8h") {
      message_body = `${doorSetting?.output} 8 hour, Reply-STOP-to-opt-out`;
    }
  }
  return message_body;
}
let latestStatus = "";
function updateStatusMessageCommand(status, icon = "check") {
  if (latestStatus === status) return;
  latestStatus = status;
  const statusDisplay = document.getElementById("smsTestingStatusCommand");
  if (statusDisplay) {
    statusDisplay.innerHTML += DOMPurify.sanitize(`<div>Message status : <span>${status}</span> ${
      icon == "check"
        ? `<i class="fas fa-check" style="color: green; font-size: 16px;"></i>`
        : `<i class="fas fa-stopwatch" style="color: gray; font-size: 16px;"></i>`
    } </div>`);
  }
}

function connectSocketCommand(wsUrl) {
  if (wsUrl) {
    const outputLoadingEle = document.getElementById(
      `output_status_loading_${testingRowDetailsCommand.testingId}_${testingRowDetailsCommand.command_type}`
    );
    const ws = new WebSocket(wsUrl);
    let isDeviceResponded = false;
    ws.onopen = () => {
      console.log("WebSocket connection established.");
      ws.connectionTimeout = setTimeout(() => {
        if (!isDeviceResponded) {
          ws.close();
          show_command_center_toast_message(
            "No response received within 1 minute. Connection closed."
          );
         console.log("WebSocket connection closed due to timeout.");
        }
      }, 30000); // 30 seconds
    };
    ws.onmessage = (event) => {
      const data = JSON.parse(event.data);
      clearTimeout(ws.connectionTimeout);

      setTimeout(() => {
        $("#testing_hardware_sms_device_command").modal("hide");
      }, 1000);
      updateStatusMessageCommand("Request has completed");
      isDeviceResponded = true;
      update_nested_command_events(testingRowDetailsCommand?.testingId);
      // Creating event log
      let createLogPayload = {
        action: `SMS ${testingRowDetailsCommand.command_type}`,
        table_name: "hardwares_settings",
        property_id: sessionStorage.getItem("propertyId"),
        additional_info: `Door command using sms ${data?.Body}`,
        log_level: "Info",
        module_name: "Commands",
        addNewAuditLog: true,
      };
      createAuditLog(createLogPayload);
      // Created event log
      if (outputLoadingEle) outputLoadingEle.style.display = "none";
      isLoadingToAddNewEvent = false;
      let eventPayload = {
        eventName: testingRowDetailsCommand?.command_type,
        eventType: "SMS IO",
        eventOf: testingRowDetailsCommand?.testingId,
        URL: " ",
        property_id: sessionStorage.getItem("propertyId"),
        eventDetail:  `Door command using sms ${data?.Body}`,
        add_hardwares_settings_events: true,
      };
      add_control_event_request(eventPayload);
      update_nested_command_events(testingRowDetailsCommand?.testingId);
      ws.close();
    };
    ws.onclose = async () => {
      clearTimeout(ws.connectionTimeout);
      $("#testing_hardware_sms_device_command").modal("hide");
      $("#testing_hardware_sms_device").modal("hide");
      if (!isDeviceResponded) {
        show_command_center_toast_message(
          "Did not receive any response. Try again"
        );
        try {
          let eventPayloadForRejectedRequest = {
            eventName: "Rejected",
            eventType: "Not responding",
            eventOf: testingRowDetailsCommand.testingId,
            URL: "",
            eventDetail: `Did not receive any response.`,
            property_id: sessionStorage.getItem("propertyId"),
            add_hardwares_settings_events: true,
          };
          await add_control_event_request(eventPayloadForRejectedRequest);
          await update_nested_command_events(
            testingRowDetailsCommand.testingId
          );
        } catch (error) {
          console.log("error catch: ", error);
        }
      }
      if (outputLoadingEle) outputLoadingEle.style.display = "none";
      isLoadingToAddNewEvent = false;
      console.log("WebSocket connection closed");
    };
  } else {
    console.error("Failed to get SMS status:", result.error_message);
  }
}

async function sendSmsThroughNodeInCommand(data, url,token) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url,
      type: "POST",
      data: JSON.stringify(data),
      contentType: "application/json",
      timeout: 10000, // 10 seconds delay
      headers: {
        authorization: `${token}`
      },
      success: function (resp) {
        try {
          if (resp?.message) {
            resolve(resp);
          }
        } catch (error) {
          console.error("Error parsing response data: ", error);
          reject(error);
        }
      },
      error: function (xhr, status, error) {
        if (xhr?.responseJSON?.error) reject(xhr?.responseJSON?.error);
        else reject(error);
      },
    });
  });
}

async function update_nested_command_events(setting_id) {
  try {
    let latestEvents = await get_events_doors_request({
      event_of: setting_id,
      get_device_events_request: true,
    });
    const eventsTableBody = $(`#nested_table_row_${setting_id}`);

    eventsTableBody.empty(); // Clear the current table body

    // Update the table with the latest 10 events
    // latestEvents
    //   .reverse()
    //   .slice(0, 10)
    //   .forEach((event) => {
    //     const eventRow = `
    //     <tr>
    //       <td style="vertical-align: middle;">${event.eventName}</td>
    //       <td style="vertical-align: middle;">${event.eventType}</td>
    //       <td style="vertical-align: middle;">${event.eventDetail}</td>
    //       <td style="vertical-align: middle;">${formatDateTimeInCommandCenter(event.timestamp) || "N/A"}</td>
    //     </tr>
    //   `;
    //     const wrappedRow = `<table><tbody>${eventRow}</tbody></table>`;
    //     const cleanWrapped = DOMPurify.sanitize(wrappedRow);
    //     const sanitizedRow = $(cleanWrapped).find("tbody").html();
    //     eventsTableBody.append(sanitizedRow);
    //   });

          latestEvents
            .reverse()
            .slice(0, 10)
            .forEach((event) => {
              let property_id = event.property_id;
              let file_name = event.file_name;
              let camera_snap = event.camera_snap;
              let camera_cell = "";

              if (file_name && file_name.trim() !== "" && file_name.toLowerCase() !== "null" && file_name.toLowerCase() !== "undefined") {
                let camera_snap_url = `/shared/snapshot_image.php?property_id=${property_id}&image_name=${file_name}`;
                camera_cell = `
                  <div onclick="show_image_modal('snapImageModal', 'snapshotImage', '${camera_snap_url}')"> 
                    <img src="${camera_snap_url}" alt="Snap" class="camera-snap-clickable" 
                      style="width: 90px; height: 90px; cursor: pointer;" 
                      title="Click to view larger image" 
                      data-image='${camera_snap_url}' data-name='Camera Snap'>
                  </div>`;
              } else if (camera_snap && camera_snap.trim() !== "" && camera_snap.toLowerCase() !== "null" && camera_snap.toLowerCase() !== "undefined") {
                camera_cell = `<span class="badge badge-danger">${camera_snap}</span>`;
              } else {
                camera_cell = `<span class="badge badge-danger">No Image</span>`;
              }

              var event_detail = event.eventDetail;
              if (event_detail.includes("Error:")) {
                  event_detail = "Could not get status.";
              }
              const eventRow = `
                <tr>
                  <td>${camera_cell}</td>
                  <td style="vertical-align: middle;">${event.eventName || "N/A"}</td>
                  <td style="vertical-align: middle;">${event.eventType || "N/A"}</td>
                  <td style="vertical-align: middle;">${event_detail || "N/A"}</td>
                  <td style="vertical-align: middle;">${formatDateTimeInCommandCenter(event.timestamp) || "N/A"}</td>
                </tr>
              `;

              const wrappedRow = `<table><tbody>${eventRow}</tbody></table>`;
              const cleanWrapped = wrappedRow;
              const sanitizedRow = $(cleanWrapped).find("tbody").html();
              eventsTableBody.append(sanitizedRow);
            });
  } catch (error) {
    console.error("Failed to update door events:", error);
  }
}

async function execute_command_door(deviceUrl, userName='',password='',statusChange = false,) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/hardwares/hardwares_request.php",
      type: "POST",
      timeout: 10000, // 10 seconds delay
      data: { checkHardwareStatusRequest: true, request_url: deviceUrl, userName, password }, // Send the itemId in the request
      success: function (resp) {
        try {
          if (!statusChange) {
            const parsedData = JSON.parse(resp.data);
            const filteredData = {
              inputs: [],
              outputs: [],
            };
            for (const key in parsedData) {
              if (parsedData.hasOwnProperty(key) && key.includes("relay")) {
                filteredData.outputs.push({ value: parsedData[key], key });
              }
            }
            for (const key in parsedData) {
              if (
                parsedData.hasOwnProperty(key) &&
                key.includes("digitalInput")
              ) {
                filteredData.inputs.push({ value: parsedData[key], key });
              }
            }
            resolve(filteredData);
          } else {
            resolve(resp.data);
          }
        } catch (error) {
          console.error("Error parsing response data: ", error);
          reject(error);
        }
      },
      error: function (xhr, status, error) {
        let rejectObj = {
          command_failed: true,
          error: xhr?.responseJSON?.error ? xhr?.responseJSON?.error : error,
        };
        if (xhr?.responseJSON?.error) reject(rejectObj);
        else reject(rejectObj);
      },
    });
  });
}

async function add_control_event_request(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/hardwares/hardwares_request.php",
      type: "POST",
      timeout: 10000, // 10 seconds delay
      data,
      success: function (resp) {
        try {
          if (data?.EditHardwareSettingsRequest){
            // window.location.reload();
            console.log('its updated resp.data: ',resp.data);
            
          } 
          resolve(resp.data);
        } catch (error) {
          console.error("Error parsing response data: ", error);
          reject(error);
        }
      },
      error: function (xhr, status, error) {
        if (xhr?.responseJSON?.error) reject(xhr?.responseJSON?.error);
        else reject(error);
      },
    });
  });
}

async function handleTimerChange(setting_id, isForAll) {
  try {
    let id_to_update = -1;
    if (!isForAll) {
      selectedOne = all_devices_in_command_center.find(
        (ele) => ele.hardware_setting_id == setting_id
      );
      id_to_update = selectedOne?.hardware_id;
    } else id_to_update = setting_id;

    let value = document.getElementById(
      `command_timer_value_${setting_id}`
    )?.value;

    
    const updatedData = await add_control_event_request({
      EditHardwareSettingsRequest: true,
      id: id_to_update,
      timer: value ? value : "",
      command_center_update: true,
      property_id: sessionStorage.getItem("property_id"),
    });
    const selectedDevice = all_devices_in_command_center.find(
      (ele) => ele.hardware_setting_id == setting_id
    );

    if(selectedDevice?.timer){
     const smsResponse = await sendSmsThroughNodeInCommand(
        {scheduleId:selectedDevice?.timer},
        `${backendUrl}/delete_schedule_task`
      );
    }
    window.location.reload();
    
  } catch (error) {
    console.log("error", error);

    if (error) show_command_center_toast_message(error);
  }
}

function closeCommandCenterToastMessage() {
  const toastEl = document.getElementById("commandToastMessage");
  toastEl.style.display = "none";
}

function show_command_center_toast_message(errorMessage, delayTime = 3000) {
  document.getElementById("commandToastMessage").style.display = "block";
  document.getElementById("commandErrorMessage").innerHTML = errorMessage;
  var toastEl = document.getElementById("commandErrorToast");
  var toast = new bootstrap.Toast(toastEl, {
    delay: delayTime,
    autohide: false,
  });
  toast.show();
  setTimeout(() => {
    closeCommandCenterToastMessage();
  }, delayTime);
}

function handle_dont_disturb_change() {
  const is_dont_disturb = document.getElementById("is_dont_disturb").checked;
  send_command_center_request({
    update_property_user_disturb_request: true,
    isDontDisturb: is_dont_disturb ? 1 : 0,
    property_id: sessionStorage.getItem("propertyId"),
  });
}

function showImageInModal(itemId) {
  let doorSetting = all_devices_in_command_center.find(
    (ele) => ele.hardware_setting_id == itemId
  );

  if (doorSetting?.liveImageURL) {
    modalActiveCameraId = itemId;
    const modalContainer = document.getElementById("show_image_in_modal");
    if (!modalContainer) {
      console.error("Modal container #show_image_in_modal not found");
      return;
    }
    
    $("#show_image_modal").modal("show");
    
    $("#show_image_modal").on("shown.bs.modal", function() {
      get_image_url_and_stream(doorSetting, true);
    });
  } else {
    console.log("No live image URL available for this door");
  }
}

async function createAuditLog(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/command_center/command_center_requests.php",
      type: "POST",
      timeout: 10000, // 10 seconds delay
      data,
      success: function (resp) {
        try {
          if (resp?.message) {
            resolve(resp);
          }
        } catch (error) {
          console.error("Error parsing response data: ", error);
          reject(error);
        }
      },
      error: function (xhr, status, error) {
        if (xhr?.responseJSON?.error) reject(xhr?.responseJSON?.error);
        else reject(error);
      },
    });
  });
}

// function changeCommandView(state) {
//   const changeDoorViewEle = document.getElementById(
//     "changeCommandViewEle"
//   ).checked;
//   const command_center_search_container = document.getElementById(
//     "door_controls_container"
//   );
//   isLoadingCommandCenter(true);
//   if (changeDoorViewEle) {
//     if(command_center_search_container) command_center_search_container.style.display="block"
//     create_command_center(
//       allItemsOfCommandCenter.data,
//       allItemsOfCommandCenter?.all_permissions,
//       allItemsOfCommandCenter?.onlyOpenCommand
//     );
//   } else {
//     if(command_center_search_container) command_center_search_container.style.display="flex"
//     create_command_center_mobile(
//       allItemsOfCommandCenter.data,
//       allItemsOfCommandCenter?.all_permissions,
//       allItemsOfCommandCenter?.onlyOpenCommand
//     );
//   }
// }

let debounceCommandTimer;

function searchCommandCenter() {
  if(!isCardViewForCommandCenter){
    searchTable('command_center_complete_data_table', 'search_command_value');
    return;
  }
  clearTimeout(commandCenterDebounceTimer);
  commandCenterDebounceTimer = setTimeout(() => {
    const searchInput = document.getElementById("search_command_value");
    if (!searchInput) {
      console.warn("Search input not found: search_command_value");
      return;
    }
    
    const searchValue = searchInput.value.toLowerCase();
    
    // Filter command center data
    let matchedCommands = allItemsOfCommandCenter?.data.filter(
      (event) =>
        !searchValue ||
        Object.values(event).some(
          (field) =>
            field && field.toString().toLowerCase().includes(searchValue)
        )
    );
    
    // Re-render based on current view
    if (window.innerWidth <= 600 || isCardViewForCommandCenter) {
      create_command_center_mobile(
        matchedCommands,
        allItemsOfCommandCenter?.all_permissions,
        allItemsOfCommandCenter?.onlyOpenCommand
      );
    } else {
      create_command_center(
        matchedCommands,
        allItemsOfCommandCenter?.all_permissions,
        allItemsOfCommandCenter?.onlyOpenCommand
      );
    }
  }, 300);
}

async function getBackendStreamingUrlInCommandCenter(data) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: "/include/property_builder/command_center/command_center_requests.php",
      type: "post",
      timeout: 10000, // 10 seconds delay
      data,
      success: function (resp) {
        backendUrl = `${resp?.data}/api`;
        resolve();
      },
      error: function (xhr, status, error) {
        reject(xhr || error);
      },
    });
  });
}

function requestAnyFullscreen(el) {
  if (!el) return;
  const req = el.requestFullscreen || el.webkitRequestFullscreen || el.msRequestFullscreen || el.mozRequestFullScreen;
  if (req) req.call(el);
}

function exitAnyFullscreen() {
  const exit = document.exitFullscreen || document.webkitExitFullscreen || document.msExitFullscreen || document.mozCancelFullScreen;
  if (exit) exit.call(document);
}

function toggleFsClass(on, el) {
  if (!el) return;
  el.classList.toggle('fs-container', !!on);
}

document.addEventListener('click', (e) => {
  const btn = e.target.closest('.camera-fullscreen');
  if (!btn) return;

  const hsid = btn.getAttribute('data-hsid');
  const target = document.getElementById(`streaming_Id_${hsid}`);
  if (!target) return;

  requestAnyFullscreen(target);
});

document.addEventListener('fullscreenchange', () => {
  const fsEl = document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement;

  document.querySelectorAll('.fs-container').forEach(el => el.classList.remove('fs-container'));
  if (fsEl) toggleFsClass(true, fsEl);
});

document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') exitAnyFullscreen();
});
