/**
 * Try to get door info
 */

import { ServerlessEventObject, ServerlessFunctionSignature } from "@twilio-labs/serverless-runtime-types/types";
import { TwilioContext } from "../../../types/TwilioContext";
import { createDynaBridgeClient } from "../../../utils/ddb";
import { ONBOARDING_DOOR_NAME } from "../../../schema/DoorConfig";
import { getLockStatusID, isLockOpen } from "../../../schema/LockStatus";
import { withMetrics } from "../../../common/DoormanHandler";
import { z } from "zod";
import { UserAgentHeader } from "../../../utils/blockUserAgent";
import { setResponseJson } from "../../../utils/responseUtils";
import { LOG_CALL_SK, LogCallSchema } from "../../../schema/LogCall";

export const LogCallRequestSchema = z.object({
  caller: z.string(),
});

export type LogCallRequest = z.infer<typeof LogCallRequestSchema>;
export interface LogCallRequestTwilio extends ServerlessEventObject<LogCallRequest, UserAgentHeader> { };

export const LogCallResponseSchema = z.object({
  otp: z.string(),
});

export type LogCallResponse = z.infer<typeof LogCallResponseSchema>;

function getCode() {
  return `${Math.floor(Math.random() * 10000)}`.padStart(4, '0');
};

export const handler: ServerlessFunctionSignature<TwilioContext, LogCallRequestTwilio> = withMetrics("logCall", async (context, event, callback, metricsRegistry) => {
  const response = new Twilio.Response();
  const req = LogCallRequestSchema.parse(event);

  let caller = req.caller;

  const db = createDynaBridgeClient(context);

  // check if onboarding is actually open
  const lock = await db.entities.lockStatus.findById(getLockStatusID(ONBOARDING_DOOR_NAME));

  if (!isLockOpen(lock)) {
    setResponseJson(response, 400, {
      msg: "Onboarding is not open",
    });
  } else {
    // log this caller
    const otp = getCode();
    const logCall = LogCallSchema.parse({
      PK: otp,
      SK: LOG_CALL_SK,
      caller,
      TTL: Date.now() + 60 * 60 * 1000, // 60 minutes from now
    });

    await db.entities.logCall.save(logCall);

    setResponseJson(response, 200, {
      otp,
    });
  }

  // destroy the internal client after
  // @ts-ignore
  db.ddbClient.destroy();

  return callback(null, response);
});
