import * as Hapi from "@hapi/hapi";
import * as Helpers from "../helpers/index.js";
import Boom from "@hapi/boom";

export const GetAllWhatsappBotsRoute = Helpers.withDefaults({
  method: "get",
  path: "/api/whatsapp/bots",
  options: {
    description: "Get all bots",
    async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
      const { whatsappService } = request.services("app");

      const bots = await whatsappService.findAll();

      if (bots) {
        // with the pino logger the first arg is an object of data to log
        // the second arg is a message
        // all other args are formated args for the msg
        request.logger.info({ bots }, "Retrieved bot(s) at %s", new Date());

        return { bots };
      }

      return _h.response().code(204);
    },
  },
});

export const GetBotsRoute = Helpers.noAuth({
  method: "get",
  path: "/api/whatsapp/bots/{token}",
  options: {
    description: "Get one bot",
    async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
      const { token } = request.params;
      const { whatsappService } = request.services("app");

      const bot = await whatsappService.findByToken(token);

      if (bot) {
        // with the pino logger the first arg is an object of data to log
        // the second arg is a message
        // all other args are formated args for the msg
        request.logger.info({ bot }, "Retrieved bot(s) at %s", new Date());

        return bot;
      }

      throw Boom.notFound("Bot not found");
    },
  },
});

interface MessageRequest {
  phoneNumber: string;
  message: string;
}

export const SendBotRoute = Helpers.noAuth({
  method: "post",
  path: "/api/whatsapp/bots/{token}/send",
  options: {
    description: "Send a message",
    async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
      const { token } = request.params;
      const { phoneNumber, message } = request.payload as MessageRequest;
      const { whatsappService } = request.services("app");

      const bot = await whatsappService.findByToken(token);

      if (bot) {
        request.logger.info({ bot }, "Sent a message at %s", new Date());

        await whatsappService.send(bot, phoneNumber, message as string);
        return _h
          .response({
            result: {
              recipient: phoneNumber,
              timestamp: new Date().toISOString(),
              source: bot.phoneNumber,
            },
          })
          .code(200); // temp
      }

      throw Boom.notFound("Bot not found");
    },
  },
});

export const ReceiveBotRoute = Helpers.withDefaults({
  method: "get",
  path: "/api/whatsapp/bots/{token}/receive",
  options: {
    description: "Receive messages",
    async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
      const { token } = request.params;
      const { whatsappService } = request.services("app");

      const bot = await whatsappService.findByToken(token);

      if (bot) {
        request.logger.info({ bot }, "Received messages at %s", new Date());

        // temp
        const date = new Date();
        const twoDaysAgo = new Date(date.getTime());
        twoDaysAgo.setDate(date.getDate() - 2);
        return whatsappService.receive(bot, twoDaysAgo);
      }

      throw Boom.notFound("Bot not found");
    },
  },
});

export const RegisterBotRoute = Helpers.withDefaults({
  method: "get",
  path: "/api/whatsapp/bots/{id}/register",
  options: {
    description: "Register a bot",
    async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
      const { id } = request.params;
      const { whatsappService } = request.services("app");

      const bot = await whatsappService.findById(id);

      if (bot) {
        await whatsappService.register(bot, (error: string) => {
          if (error) {
            return _h.response(error).code(500);
          }

          request.logger.info({ bot }, "Register bot at %s", new Date());
          return _h.response().code(200);
        });
      }

      throw Boom.notFound("Bot not found");
    },
  },
});

export const UnverifyBotRoute = Helpers.withDefaults({
  method: "post",
  path: "/api/whatsapp/bots/{id}/unverify",
  options: {
    description: "Unverify bot",
    async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
      const { id } = request.params;
      const { whatsappService } = request.services("app");

      const bot = await whatsappService.findById(id);

      if (bot) {
        return whatsappService.unverify(bot);
      }

      throw Boom.notFound("Bot not found");
    },
  },
});

export const RefreshBotRoute = Helpers.withDefaults({
  method: "get",
  path: "/api/whatsapp/bots/{id}/refresh",
  options: {
    description: "Refresh messages",
    async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
      const { id } = request.params;
      const { whatsappService } = request.services("app");

      const bot = await whatsappService.findById(id);

      if (bot) {
        request.logger.info({ bot }, "Refreshed messages at %s", new Date());

        //       await whatsappService.refresh(bot);
        return;
      }

      throw Boom.notFound("Bot not found");
    },
  },
});

interface BotRequest {
  phoneNumber: string;
  description: string;
}

export const CreateBotRoute = Helpers.withDefaults({
  method: "post",
  path: "/api/whatsapp/bots",
  options: {
    description: "Register a bot",
    async handler(request: Hapi.Request, _h: Hapi.ResponseToolkit) {
      const { phoneNumber, description } = request.payload as BotRequest;
      const { whatsappService } = request.services("app");
      console.log("request.auth.credentials:", request.auth.credentials);

      const bot = await whatsappService.create(
        phoneNumber,
        description,
        request.auth.credentials.email as string
      );
      if (bot) {
        request.logger.info({ bot }, "Register bot at %s", new Date());
        return bot;
      }

      throw Boom.notFound("Bot not found");
    },
  },
});
