/**
 * Try to update door status
 */

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

export const StatusRequestSchema = z.object({
  door: z.string(),
});

export type StatusRequest = z.infer<typeof StatusRequestSchema>;

export interface StatusRequestTwilio extends ServerlessEventObject<StatusRequest, UserAgentHeader> { }

export const StatusResponseSchema = z.object({
  status: z.nativeEnum(DoorStatus),
  fingerprint: zu.json().optional(),
})

export type StatusResponse = z.infer<typeof StatusResponseSchema>;

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

  const req = StatusRequestSchema.parse(event);
  const door = req.door;

  const db = createDynaBridgeClient(context);
  const lock = await db.entities.lockStatus.findById(getLockStatusID(door));

  const isOpen = isLockOpen(lock);

  if (isOpen && lock) {
    const fingerprint = JSON.parse(lock.fingerprint);

    const body = StatusResponseSchema.parse({
      status: DoorStatus.OPEN,
      fingerprint,
    });

    setResponseJson(response, 200, body);

    await db.entities.lockStatus.deleteById(getLockStatusID(door));
  } else {
    const body = StatusResponseSchema.parse({
      status: DoorStatus.CLOSED,
    });

    setResponseJson(response, 200, body);
  }

  // destroy the internal client after
  // @ts-ignore
  db.ddbClient.destroy();
  return callback(null, response);
});
