/**
 * 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 { DoorStatus } from "../../../types/DoorStatus";
import { getDoorConfigID } from "../../../schema/DoorConfig";
import { getDoorAliasID } from "../../../schema/DoorAlias";
import { getLockStatusID, isLockOpen } from "../../../schema/LockStatus";

export interface InfoRequest extends ServerlessEventObject {
  door?: string;
  buzzer?: string;

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

export interface InfoResponseClient {
  buzzer: string;
  door: string;
  pressKey: string;
  fallbackNumbers: string[];
  discordUsers: string[];
}

export const handler: ServerlessFunctionSignature<TwilioContext, InfoRequest> = async function(context, event, callback) {
  const response = new Twilio.Response();

  let door = event.door;
  const buzzer = event.buzzer?.slice(-10);

  if (!door && !buzzer) {
    response.setStatusCode(400);
    return callback(null, response);
  }

  const db = createDynaBridgeClient(context);

  if (buzzer) {
    door = await db.entities.doorAlias.findById(getDoorAliasID(buzzer))
      .then(async (alias) => {
        if (!alias) {
          response
            .setStatusCode(404)
            .appendHeader('Content-Type', 'application/json')
            .setBody({ err: "This buzzer is not registered" });
          return undefined;
        }
        return alias.name;
      });
  }

  if (door) {
    const config = await db.entities.doorConfig.findById(getDoorConfigID(door));

    if (!config) {
      response
        .setStatusCode(404)
        .appendHeader('Content-Type', 'application/json')
        .setBody({ err: "This buzzer is not registered properly" });
    } else {
      if (buzzer) {
        // respond to twilio CLIENT
        response
          .setStatusCode(200)
          .appendHeader('Content-Type', 'application/json')
          .setBody({ 
            buzzer,
            door,
            fallbackNumbers: config.fallbackNumbers,
            pressKey: config.pressKey,
            discordUsers: config.discordUsers,
          });
      } else {
        const lock = await db.entities.lockStatus.findById(getLockStatusID(door));
        const status = isLockOpen(lock) ? DoorStatus.OPEN: DoorStatus.CLOSED;
      
        // respond to UI
        response
          .setStatusCode(200)
          .appendHeader('Content-Type', 'application/json')
          .setBody({ 
            id: door, 
            timeout: config.timeout,
            buzzer: config.buzzer,
            status, 
            buzzerCode: config.buzzerCode,
            fallbackNumbers: config.fallbackNumbers,
            pressKey: config.pressKey,
            discordUsers: config.discordUsers,
            greeting: config.greeting || "",
          });
      }
    }
  }

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

  return callback(null, response);
};