const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const path = require("path");
const compression = require("compression");
const twilio = require("twilio");
const logger = require("./server/utils/logger");
var fb = require("./server/firebase/firebase-handler");
var cookieParser = require("cookie-parser");
const multer = require("multer");
const upload = multer();
//var enforce = require("express-sslify");

require("dotenv").config({
  path: path.resolve(
    process.cwd(),
    `.env.${process.env.NODE_ENV || "development"}`
  ),
});

const app = express();
const port = process.env.PORT || 5000;
//const port = 5000;

const http = require("http");
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
  path: "/ws",
  cors: {
    origin: [
      "https://test.imex.online",
      "https://www.test.imex.online",
      "http://localhost:3000",
      "https://imex.online",
      "https://www.imex.online",
    ],
    methods: ["GET", "POST"],
    credentials: true,
    exposedHeaders: ["set-cookie"],
  },
});
exports.io = io;
require("./server/web-sockets/web-socket");

//app.use(fb.validateFirebaseIdToken);
app.use(compression());
app.use(cookieParser());
app.use(bodyParser.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ limit: "50mb", extended: true }));
//app.use(enforce.HTTPS({ trustProtoHeader: true }));
app.use(
  cors({ credentials: true, exposedHeaders: ["set-cookie"] })
  // cors({
  //   credentials: true,
  //   origin: [
  //     "https://test.imex.online",
  //     "http://localhost:3000",
  //     "https://imex.online",
  //   ],
  // })
);

//Email Based Paths.
var sendEmail = require("./server/email/sendemail.js");
app.post("/sendemail", fb.validateFirebaseIdToken, sendEmail.sendEmail);
app.post("/emailbounce", bodyParser.text(), sendEmail.emailBounce);

//Test route to ensure Express is responding.
app.get("/test", async function (req, res) {
  const commit = require("child_process").execSync(
    "git rev-parse --short HEAD"
  );
  logger.log("test-api-status", "DEBUG", "api", { commit });
  sendEmail.sendServerEmail({
    subject: `API Check - ${process.env.NODE_ENV}`,
    text: `Server API check has come in.    `,
  });
  res.status(200).send(`OK - ${commit}`);
});

//Accounting Qbxml
const accountQbxml = require("./server/accounting/qbxml/qbxml");
app.post(
  "/accounting/qbxml/receivables",
  fb.validateFirebaseIdToken,
  accountQbxml.receivables
);
app.post(
  "/accounting/qbxml/payables",
  fb.validateFirebaseIdToken,
  accountQbxml.payables
);
app.post(
  "/accounting/qbxml/payments",
  fb.validateFirebaseIdToken,
  accountQbxml.payments
);

//Cloudinary Media Paths
var media = require("./server/media/media");
app.post(
  "/media/sign",
  fb.validateFirebaseIdToken,
  media.createSignedUploadURL
);
app.post("/media/download", fb.validateFirebaseIdToken, media.downloadFiles);
app.post("/media/rename", fb.validateFirebaseIdToken, media.renameKeys);
app.post("/media/delete", fb.validateFirebaseIdToken, media.deleteFiles);

//SMS/Twilio Paths
var smsReceive = require("./server/sms/receive");
app.post(
  "/sms/receive",
  twilio.webhook({ validate: process.env.NODE_ENV === "PRODUCTION" }),
  smsReceive.receive
);
var smsSend = require("./server/sms/send");
app.post("/sms/send", fb.validateFirebaseIdToken, smsSend.send);
var smsStatus = require("./server/sms/status");
app.post(
  "/sms/status",
  twilio.webhook({ validate: process.env.NODE_ENV === "PRODUCTION" }),
  smsStatus.status
);
app.post("/sms/markConversationRead", smsStatus.markConversationRead);

var job = require("./server/job/job");
app.post("/job/totals", fb.validateFirebaseIdToken, job.totals);
app.post(
  "/job/statustransition",
  // fb.validateFirebaseIdToken,
  job.statustransition
);
app.post("/job/totalsssu", fb.validateFirebaseIdToken, job.totalsSsu);
app.post("/job/costing", fb.validateFirebaseIdToken, job.costing);
app.post("/job/costingmulti", fb.validateFirebaseIdToken, job.costingmulti);

//Scheduling
var scheduling = require("./server/scheduling/scheduling-job");
app.post("/scheduling/job", fb.validateFirebaseIdToken, scheduling.job);

//Handlebars Paths for Email/Report Rendering
// var renderHandlebars = require("./server/render/renderHandlebars");
// app.post("/render", fb.validateFirebaseIdToken, renderHandlebars.render);
var inlineCss = require("./server/render/inlinecss");
app.post("/render/inlinecss", fb.validateFirebaseIdToken, inlineCss.inlinecss);

app.post(
  "/notifications/send",

  fb.sendNotification
);
app.post("/notifications/subscribe", fb.validateFirebaseIdToken, fb.subscribe);
app.post(
  "/notifications/unsubscribe",
  fb.validateFirebaseIdToken,
  fb.unsubscribe
);
app.post("/adm/updateuser", fb.validateFirebaseIdToken, fb.updateUser);
app.post("/adm/getuser", fb.validateFirebaseIdToken, fb.getUser);
app.post("/adm/createuser", fb.validateFirebaseIdToken, fb.createUser);
const adm = require("./server/admin/adminops");
app.post(
  "/adm/createassociation",
  fb.validateFirebaseIdToken,
  fb.validateAdmin,
  adm.createAssociation
);
app.post(
  "/adm/createshop",
  fb.validateFirebaseIdToken,
  fb.validateAdmin,
  adm.createShop
);
app.post(
  "/adm/updateshop",
  fb.validateFirebaseIdToken,
  fb.validateAdmin,
  adm.updateShop
);
app.post(
  "/adm/updatecounter",
  fb.validateFirebaseIdToken,
  fb.validateAdmin,
  adm.updateCounter
);

//Stripe Processing
var stripe = require("./server/stripe/payment");
app.post("/stripe/payment", fb.validateFirebaseIdToken, stripe.payment);
app.post(
  "/stripe/mobilepayment",
  fb.validateFirebaseIdToken,
  stripe.mobile_payment
);

//Tech Console
var tech = require("./server/tech/tech");
app.post("/tech/login", fb.validateFirebaseIdToken, tech.techLogin);

var utils = require("./server/utils/utils");
app.post("/utils/time", utils.servertime);

var qbo = require("./server/accounting/qbo/qbo");
app.post("/qbo/authorize", fb.validateFirebaseIdToken, qbo.authorize);
app.get("/qbo/callback", qbo.callback);
app.post("/qbo/receivables", fb.validateFirebaseIdToken, qbo.receivables);
app.post("/qbo/payables", fb.validateFirebaseIdToken, qbo.payables);
app.post("/qbo/payments", fb.validateFirebaseIdToken, qbo.payments);

var data = require("./server/data/data");
app.post("/data/ah", data.autohouse);
app.post("/record-handler/arms", data.arms);

var taskHandler = require("./server/tasks/tasks");
app.post("/taskHandler", taskHandler.taskHandler);

var mixdataUpload = require("./server/mixdata/mixdata");

app.post(
  "/mixdata/upload",
  fb.validateFirebaseIdToken,
  upload.any(),
  mixdataUpload.mixdataUpload
);

var ioevent = require("./server/ioevent/ioevent");
app.post("/ioevent", ioevent.default);
app.post("/newlog", (req, res) => {
  const { message, type, user, record, object } = req.body;
  logger.log(message, type, user, record, object);
});

var cdkGetMake = require("./server/cdk/cdk-get-makes");
app.post("/cdk/getvehicles", fb.validateFirebaseIdToken, cdkGetMake.default);

app.get("/", async function (req, res) {
  res.status(200).send("Access Forbidden.");
});

server.listen(port, (error) => {
  if (error) throw error;
  logger.log(
    `[${process.env.NODE_ENV || "DEVELOPMENT"}] Server running on port ${port}`,
    "INFO",
    "api"
  );
});
