import { ServerlessEventObject, ServerlessFunctionSignature } from "@twilio-labs/serverless-runtime-types/types";
import { TwilioContext } from "../../../types/TwilioContext";
import { jsonMsgSuffix, sendMessageToUser } from "../../../utils/discord";
import { getMetricFromRegistry, withMetrics } from "../../../common/DoormanHandler";
import { NotifyMetrics, registerMetrics } from "../../../metrics/NotifyMetrics";
import { Counter, Summary } from "prom-client";


export interface NotifyRequest extends ServerlessEventObject {
  door: string;

  // TODO: change these to be multiple
  discordUser: string;
  msg: string;
  json: string;
}

export const handler: ServerlessFunctionSignature<TwilioContext, NotifyRequest> = withMetrics('notify', async (context, event, callback, metricsRegistry) => {
  const response = new Twilio.Response();

  registerMetrics(metricsRegistry);

  let users: string[];
  let msgs: string[];
  let jsons: string[];
  let promises = [];

  try {
    users = JSON.parse(event.discordUser);
    msgs = JSON.parse(event.msg);
    console.log("before parsing", event.json);
    jsons = JSON.parse(event.json);
    console.log("after parsing", event.json);

    const recordNotifyLatency = getMetricFromRegistry<Summary>(metricsRegistry, NotifyMetrics.DISCORD_LATENCY)
        .startTimer();

    promises = msgs.map((msg, i) => 
      sendMessageToUser(
        context,
        users[i], 
        msg + jsonMsgSuffix(jsons[i])
      )
        .then(() => {
          recordNotifyLatency();
        })
        .catch((e: Error) => {
          recordNotifyLatency();
          getMetricFromRegistry<Counter>(metricsRegistry, NotifyMetrics.DISCORD_FAILURE).inc({ error: e.name }, 1);
        })
    );
  } catch (e) {
    console.error(e);
    response
      .setStatusCode(500)
      .appendHeader('Content-Type', 'application/json')
      .setBody({ err: e, event });
    return callback(null, response);
  }

  let timer = setTimeout(() => {
    console.log("Ungraceful finish: running out of time");
    getMetricFromRegistry<Counter>(metricsRegistry, NotifyMetrics.NOTIFY_TIMEOUT).inc(1);
    callback(null, response);
  }, 9500);

  await Promise.all(promises);
  clearTimeout(timer);
  return callback(null, response);
});
