const screen_save = async function (SESSION_ID, paramsP) {
  var str = '[screenid="' + paramsP.screenId + '"]';
  var elm = $('#' + paramsP.screenId).find(str);
  var dsSession;

  if (!elm || !elm.length) {
    return func.db.save_data(SESSION_ID, paramsP.dsSession, 0);
  }

  for await (const [key, val] of Object.entries(elm)) {
    if (key === 'length') {
      break;
    }
    if (!val) {
      continue;
    }

    dsSession = $(val).data().xuData.dsSession;
    let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[dsSession];
    if (!dsSession || !_ds) {
      continue;
    }

    if (_ds.tree_obj.renderType === 'form') {
      if (_ds._dataSourceTableId) {
        // update only when file exist
        if (!_ds.abort_save) await func.db.save_data(SESSION_ID, dsSession, key);
        _ds.abort_save = false;
        continue;
      }
    }
  }
};

export const action_execute = async function (SESSION_ID, actionP, params, isScreenActionP, event_sourceP, jobNoP, containerP) {
  var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[params.dsSession];

  if (!_ds) {
    func.events.delete_job(SESSION_ID, jobNoP);
    return;
  }

  var action = actionP;

  var formGrid_dsSession; // null when action triggered from screen
  var EVENTSUFFIX = '_triggered';
  if (!isScreenActionP) formGrid_dsSession = params.dsSession;

  var do_event = async function (actionP) {
    var delete_job = async function (jobsP) {
      await func.events.check_jobs_idle(SESSION_ID, jobsP);
      func.events.delete_job(SESSION_ID, jobNoP);
    };
    const jobsP = await func.events.validate(SESSION_ID, actionP + EVENTSUFFIX, params.dsSession, null, 'action');
    await delete_job(jobsP);
  };

  const fx = {
    act_next: async function () {
      await locate_record(SESSION_ID, 'next', params.dsSession);
      if (_ds.tree_obj.renderType === 'form') {
        $('body').trigger('xu-bind-refresh.' + params.dsSession.toString());
      }
    },
    act_prev: async function () {
      await locate_record(SESSION_ID, 'prev', params.dsSession);
      if (_ds.tree_obj.renderType === 'form') $('body').trigger('xu-bind-refresh.' + params.dsSession.toString());
    },
    act_last: async function () {
      await locate_record(SESSION_ID, 'last', params.dsSession);
      if (_ds.tree_obj.renderType === 'form') $('body').trigger('xu-bind-refresh.' + params.dsSession.toString());
    },
    act_first: async function () {
      await locate_record(SESSION_ID, 'first', params.dsSession);
      if (_ds.tree_obj.renderType === 'form') $('body').trigger('xu-bind-refresh.' + params.dsSession.toString());
    },
    act_refresh: async function (sourceP) {
      let screen_params = params.screen_params;

      await func.datasource.create(SESSION_ID, params.prog_id, params.dsSession, params.parentDataSourceNo, params.containerId, params.rowIdP);
      let _ds = SESSION_OBJ[SESSION_ID].DS_GLB[params.dsSession];
      _ds.screen_params = screen_params;
      func.UI.screen.update_SYS_OBJ_WIN_INFO(SESSION_ID, params.dsSession);
      $('body').trigger('xu-bind-refresh.' + params.dsSession.toString());

      let prog_obj = await func.utils.VIEWS_OBJ.get(SESSION_ID, _ds.prog_id);
      let field_changed = [];
      for (let field of prog_obj?.progFields) {
        field_changed.push(field?.data?.field_id || '');
      }
      func.UI.screen.refresh_xu_attributes(SESSION_ID, field_changed);
    },
    act_save: async function () {
      await screen_save(SESSION_ID, params);
    },
    act_delete: async function () {
      _ds.data_feed.rows_deleted.push(_ds.currentRecordId);
      await screen_save(SESSION_ID, params);
    },
    // act_close: async function () {
    //   switch (params.screen_params.screen_type) {
    //     case 'modal':
    //       let modal_id = 'app_modal-' + params.dsSession.toString();
    //       // APP_MODAL_OBJ[modal_id].dismiss().then(async () => {
    //       //   APP_MODAL_OBJ[modal_id] = null;

    //       //   func.events.delete_job(SESSION_ID, jobNoP);
    //       // });
    //       APP_MODAL_OBJ[modal_id].close();
    //       // APP_MODAL_OBJ[modal_id] = null;
    //       func.events.delete_job(SESSION_ID, jobNoP);
    //       break;

    //     case 'popover':
    //       CURRENT_APP_POPOVER.dismiss().then(async () => {
    //         CURRENT_APP_POPOVER = null;

    //         func.events.delete_job(SESSION_ID, jobNoP);
    //       });
    //       break;

    //     case 'page':
    //       var nav = $(SESSION_OBJ[SESSION_ID].root_element).find('xu-nav')[0];
    //       nav.popToRoot();

    //       var ds_obj = $(nav).data().xuData.nav_params;

    //       break;

    //     default:
    //       break;
    //   }

    //   // if (params.screen_params.is_mobile_modal) {
    //   //   let modal_id = "app_modal-" + params.dsSession.toString();
    //   //   APP_MODAL_OBJ[modal_id].dismiss().then(async () => {
    //   //     APP_MODAL_OBJ[modal_id] = null;

    //   //     // func.datasource.clean_all(SESSION_ID, params.dsSession);
    //   //     func.events.delete_job(SESSION_ID, jobNoP);
    //   //   });
    //   // }
    //   // if (params.screen_params.is_mobile_popover) {
    //   //   CURRENT_APP_POPOVER.dismiss().then(async () => {
    //   //     CURRENT_APP_POPOVER = null;

    //   //     // func.datasource.clean_all(SESSION_ID, params.dsSession);
    //   //     func.events.delete_job(SESSION_ID, jobNoP);
    //   //   });
    //   // }
    //   // if (params.screen_params.is_mobile_page) {
    //   //   var nav = $(SESSION_OBJ[SESSION_ID].root_element).find("xu-nav")[0];
    //   //   nav.popToRoot();

    //   //   var ds_obj = $(nav).data().xuData.nav_params;

    //   //   // $.each(ds_obj, function (key, val) {
    //   //   //   func.datasource.clean_all(SESSION_ID, key);
    //   //   // });

    //   //   // var interval = setInterval(function () {
    //   //   //   if (!validate_pending_ds_jobs()) {
    //   //   //     setTimeout(function () {
    //   //   //       func.datasource.del(SESSION_ID, params.dsSession);
    //   //   //       // clean after screen is closing but causing a bug when interval is low
    //   //   //     }, 10000);
    //   //   //     clearInterval(interval);
    //   //   //   }
    //   //   // }, 2000);
    //   // }
    // },
    act_reload: async function () {
      var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[params.dsSession];

      let screen_params = _.cloneDeep(params.screen_params);

      switch (params.screen_params.screen_type) {
        case 'modal':
          debugger;
          break;

        case 'popover':
          debugger;
          break;

        case 'panel':
          func.UI.screen.refresh_screen(SESSION_ID, null, params.dsSession);
          func.events.delete_job(SESSION_ID, jobNoP);

          break;

        case 'page':
          let nav = $(SESSION_OBJ[SESSION_ID].root_element).find('xu-nav')[0];
          nav.popTo();
          break;

        default:
          screen_params.$callingContainerP.empty();
          break;
      }

      let ret = await func.UI.screen.init(
        SESSION_ID,
        params.screen_params.prog_id,
        params.screen_params.sourceScreenP,
        params.screen_params.callingDataSource_objP,
        params.screen_params.$callingContainerP,
        params.screen_params.triggerIdP,
        params.screen_params.rowIdP,
        null,
        params.screen_params.is_panelP,
        params.screen_params.parameters_obj_inP,
        params.screen_params.source_functionP,
      );
    },
    // act_back: async function () {
    //   if (params.screen_params.is_mobile_page) {
    //     var nav = $(SESSION_OBJ[SESSION_ID].root_element).find('xu-nav')[0];
    //     nav.popTo();
    //   }
    // },
    act_print: async function () {
      window.print();
    },
  };

  if (event_sourceP === 'click') {
    await func.events.validate(SESSION_ID, action + '_clicked', params.dsSession, null, 'toolbar');
    params.event_sourceP = event_sourceP;
    params.isScreenActionP = isScreenActionP;
    await func.events.add_to_queue(SESSION_ID, params.renderType, null, event_sourceP, 'invoke_action', action, params.udfContainer, null, null, null, null, params.rootScreenIdP, null, null, null, null, null, 'click', params, null, null, null);
  } else {
    await fx[action]();
    await do_event(action);
  }
};

const locate_record = async function (SESSION_ID, actionP, dsSessionP) {
  // init/next/prev

  var arr = [];
  var result;
  var _ds = SESSION_OBJ[SESSION_ID].DS_GLB[dsSessionP];
  var current = _ds.currentRecordId;
  if (!current) return;

  // setup temp index arr
  var i = 1;
  // $.each(_ds.data_feed.sort, function (key, val) {
  //   if (key === "newRecord") return true;
  //   arr[i] = val;
  //   i++;
  // });

  try {
    let arr = ds?.data_feed?.rows || [];
    var len = srr.length;
    const idx = func.common.find_ROWID_idx(_ds, _ds.currentRecordId);

    if (actionP === 'next') {
      if (idx + 1 < len) {
        new_idx = idx + 1;
        result = arr[new_idx]._ROWID;
      } else {
        new_idx = idx;
        result = arr[new_idx]._ROWID;
      }
    }
    if (actionP === 'prev') {
      if (idx - 1 > 0) {
        new_idx = idx - 1;
        result = arr[new_idx]._ROWID;
      } else {
        new_idx = idx;
        result = arr[new_idx]._ROWID;
      }
    }
    if (actionP === 'first') {
      new_idx = 1;
      result = arr[new_idx]._ROWID;
    }
    if (actionP === 'last') {
      new_idx = arr.length - 1;
      result = arr[new_idx]._ROWID;
    }
    // _ds.currentRecordId = result;

    var datasource_changes = {
      [_ds.dsSession]: { [result]: 'set' },
    };
    await func.datasource.update(SESSION_ID, datasource_changes);
  } catch (err) {
    console.error(err);
  }

  // var idx = arr.indexOf(current);
  // var len = arr.length;
  // var new_idx = 0;
  // if (idx > 0) {
  //   //-1
  //   if (actionP === "next") {
  //     if (idx + 1 < len) {
  //       new_idx = idx + 1;
  //       result = arr[new_idx];
  //     } else {
  //       new_idx = idx;
  //       result = arr[new_idx];
  //     }
  //   }
  //   if (actionP === "prev") {
  //     if (idx - 1 > 0) {
  //       new_idx = idx - 1;
  //       result = arr[new_idx];
  //     } else {
  //       new_idx = idx;
  //       result = arr[new_idx];
  //     }
  //   }
  //   if (actionP === "first") {
  //     new_idx = 1;
  //     result = arr[new_idx];
  //   }
  //   if (actionP === "last") {
  //     new_idx = arr.length - 1;
  //     result = arr[new_idx];
  //   }
  //   // _ds.currentRecordId = result;

  //   var datasource_changes = {
  //     [_ds.dsSession]: { [result]: "set" },
  //   };
  //   await func.datasource.update(SESSION_ID, datasource_changes);
  // }
};
