// Parse and return an LDB Request

const log = require("../utils/logs.utils"); // Log Helper
const ldb = require("ldbs-json");
const util = require("../utils/ldb.utils");
const san = require("../utils/sanitizer.utils");
const db = require("../services/dbAccess.services");

import { transform as staffStationTransform } from "../utils/translators/ldb/staffStation";
import { msgCodes } from "../configs/errorCodes.configs";

const ldbKey = process.env.OWL_LDB_KEY;
const ldbsvKey = process.env.OWL_LDB_SVKEY;

async function get(id, staff = false) {
  const cleanId = san.cleanApiEndpointTxt(id);
  const obj = await util.checkCrs(cleanId);
  try {
    const crs = obj[0]["3ALPHA"];
    log.out(`ldbService.get: Determined CRS for lookup to be: ${crs}`, "info");
    if (staff) {
      const data = arrDepBoardStaff(crs);
      db.increment("ldbsvws");
      return await data;
    } else {
      const data = arrDepBoard(crs);
      db.increment("ldbws");
      return await data;
    }
  } catch (err) {
    log.out(`ldbService.get: Error, Unable to find CRS: ${err}`, "info");
    return {
      obStatus: "LOC_NOT_FOUND",
      obMsg: "UNABLE TO FIND MESSAGE",
    };
  }
}

async function arrDepBoard(CRS) {
  log.out(`ldbService.arrDepBoard: Trying to fetch board for ${CRS}`, "info");
  try {
    const options = {
      numRows: 10,
      crs: CRS.toUpperCase(),
    };
    const api = new ldb(ldbKey, false);
    let d = await api.call("GetArrDepBoardWithDetails", options, false, false);
    return await util.cleanData(d);
  } catch (err) {
    log.out(`ldbService.arrDepBoard: Lookup Failed for: ${CRS}`, "warn");
    return {
      GetStationBoardResult: "not available",
      Reason: `The CRS code ${CRS} is not valid`,
    };
  }
}

async function arrDepBoardStaff(CRS) {
  log.out(`ldbService.arrDepBoardStaff: Try to fetch board for ${CRS}`, "dbug");
  try {
    const options = {
      numRows: 40,
      crs: CRS.toUpperCase(),
      getNonPassengerServices: true,
      time: await getDateTimeString(new Date()),
      timeWindow: 120,
      services: "PBS",
    };
    const api = new ldb(ldbsvKey, true);
    console.time(`Fetch Staff LDB for ${CRS.toUpperCase()}`);
    const result = await api.call(
      "GetArrivalDepartureBoardByCRS",
      options,
      false,
      false
    );
    console.timeEnd(`Fetch Staff LDB for ${CRS.toUpperCase()}`);
    try {
      const _staffLdb = staffStationTransform(result);
      console.log("Transformation Test Successful");
      console.log(JSON.stringify(_staffLdb));
      return {
        obStatus: "OK",
        obMsg: "OK",
        data: _staffLdb,
      };
    } catch (err) {
      console.log("Transformation Test Failed: " + err);
    }
    return result;
  } catch (err) {
    log.out(`ldbService.arrDepBoardStaff: Lookup Failed for: ${CRS}`, "warn");
    log.out(`ldbService.arrDepBoardStaff: ${err}`);
    return {
      GetStationBoardResult: "not available",
      Reason: `The CRS code ${CRS} is not valid`,
    };
  }
}

async function getServiceByRID(rid) {
  log.out(`ldbService.getServiceByRID: Finding RID: ${rid}`, "dbug");
  try {
    const options = {
      rid: String(rid),
    };
    const api = new ldb(ldbsvKey, true);
    return await api.call("GetServiceDetailsByRID", options, false, false);
  } catch (err) {
    log.out(`ldbService.queryService: ${err}`, "EROR");
  }
}

async function getServicesByOther(id) {
  log.out(`ldbService.getServiceByOther: Finding services: ${id}`, "dbug");
  try {
    const options = {
      serviceID: id,
      sdd: getDateString(new Date()),
    };
    const api = new ldb(ldbsvKey, true);
    return await api.call("QueryServices", options, false, false);
  } catch (err) {
    log.out(`ldbService.getServiceByOther: Error: ${err}`, "EROR");
    return false;
  }
}

async function getReasonCodeList() {
  log.out("ldbService.getReasonCodeList: Fetching reason code list", "eror");
  try {
    const dbFilter = {};
    return await db.query("reasonCodes", dbFilter, false);
  } catch (err) {
    log.out(`ldbService.getReasonCodeList: ${err}`, "eror");
  }
}

async function getReasonCode(code) {
  log.out(`ldbService.getReasonCode: Fetching reason code ${code}`, "dbug");
  try {
    const dbFilter = {
      code: code,
    };
    return await db.query("reasonCodes", dbFilter, false);
  } catch (err) {
    log.out(`ldbService.getReasonCode: ${err}`, "eror");
  }
}

async function getDateTimeString(date) {
  const year = date.getFullYear(),
    month = String(date.getMonth() + 1).padStart(2, "0"),
    day = String(date.getDate()).padStart(2, "0"),
    hour = String(date.getHours()).padStart(2, "0"),
    minute = String(date.getMinutes()).padStart(2, "0"),
    second = String(date.getSeconds()).padStart(2, "0");
  const format = `${year}-${month}-${day}T${hour}:${minute}:${second}`;
  return format;
}

async function getDateString(date) {
  const year = date.getFullYear(),
    month = String(date.getMonth() + 1).padStart(2, "0"),
    day = String(date.getDate()).padStart(2, "0");
  const format = `${year}-${month}-${day}`;
  return format;
}

module.exports = {
  get,
  getServiceByRID,
  getServicesByOther,
  getReasonCodeList,
  getReasonCode,
};
