/**
 * Try to get door info
 */

import { ServerlessEventObject, ServerlessFunctionSignature } from "@twilio-labs/serverless-runtime-types/types";
import { TwilioContext } from "../../../types/TwilioContext";
import { createDDBClient, createDynaBridgeClient, ddbItemToJSON, getDoorAliasCommand, getDoorConfigCommand, getLockStatusCommand, isLockOpen } from "../../../utils/ddb";
import { DoorStatus } from "../../../types/DoorStatus";
import { DoorConfig } from "../../../types/DoorConfig";
import { DOOR_CONFIG_SK, getDoorConfigID } from "../../../schema/DoorConfig";

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 client = createDDBClient(context);
  const db = createDynaBridgeClient(context);

  if (buzzer) {
    door = await client.send(getDoorAliasCommand(buzzer))
      .then(async (alias) => {
        if (!alias.Item) {
          response
            .setStatusCode(404)
            .appendHeader('Content-Type', 'application/json')
            .setBody({ err: "This buzzer is not registered" });
          return undefined;
        }
        return alias.Item.name.S;
      });
  }

  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 {
        await client.send(getLockStatusCommand(door))
          .then(async (lock) => {
            const config = await client.send(getDoorConfigCommand(door));
            const status = isLockOpen(lock) ? DoorStatus.OPEN: DoorStatus.CLOSED;
            const doorConfig: DoorConfig = ddbItemToJSON<DoorConfig>(config);
      
            // respond to UI
            response
              .setStatusCode(200)
              .appendHeader('Content-Type', 'application/json')
              .setBody({ 
                id: door, 
                timeout: doorConfig.timeout,
                buzzer: doorConfig.buzzer,
                status, 
                buzzerCode: doorConfig.buzzerCode,
                fallbackNumbers: doorConfig.fallbackNumbers,
                pressKey: doorConfig.pressKey,
                discordUsers: doorConfig.discordUsers || [],
                greeting: doorConfig.greeting || "",
              });
      
          }).catch((e) => {
            console.log(e);
            response
              .setStatusCode(500)
              .appendHeader('Content-Type', 'application/json')
              .setBody({ err: e });
          });
      }
    }
  }
  await client.destroy();
  return callback(null, response);
};