import { Controller, Post, Body, UseGuards } from "@nestjs/common";
import { SendOtpService } from "./send-otp.service";
import { ThrottlerGuard, Throttle, SkipThrottle } from "@nestjs/throttler";
import { AuthApiKeyGuard } from "src/auth/apiKey.guard";
import axios from "axios";
import * as crypto from "crypto";

@Controller("send_otp")
export class SendOtpController {
  constructor(private readonly otpService: SendOtpService) { }

  @UseGuards(AuthApiKeyGuard, ThrottlerGuard)
  @SkipThrottle()
  // @Throttle(4, 600)
  @Post()
  async sendOtp(@Body("mobileNumber") mobileNumber: string): Promise<any> {
    const otpTemplateId = "65648d86d6fc0502dd1ab8e2";
    try {
      if (mobileNumber == "917092327667") {
        return {
          success: true,
          result: {
            request_id: "346342707568323638313036",
            type: "success",
          },
        };
      } else {
        const result = await this.otpService.sendOtp(
          mobileNumber,
          otpTemplateId
        );
        return { success: true, result };
      }
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  @UseGuards(AuthApiKeyGuard, ThrottlerGuard)
  @SkipThrottle()

  // @Throttle(5, 600)
  @Post("/forgot-mpin")
  async sendOtpFor(@Body("mobileNumber") mobileNumber: string): Promise<any> {
    const otpTemplateId = "65648d86d6fc0502dd1ab8e2";
    try {
      if (mobileNumber == "917092327667") {
        return {
          success: true,
          result: {
            request_id: "346342707568323638313036",
            type: "success",
          },
        };
      } else {
        const result = await this.otpService.sendOtp(
          mobileNumber,
          otpTemplateId
        );
        return { success: true, result };
      }
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  @UseGuards(AuthApiKeyGuard, ThrottlerGuard)
  @SkipThrottle()
  // @Throttle(4, 600)
  @Post("/encrypted")
  async encsendOtp(@Body() mobileNumber: any): Promise<any> {
    mobileNumber = mobileNumber.body;
    let base64Key = process.env.encryption_key;
    let base64Iv = process.env.encryption_iv;

    const key = Buffer.from(base64Key, "base64");
    const iv = Buffer.from(base64Iv, "base64");

    if (key.length !== 32) throw new Error("Key must be 32 bytes");
    if (iv.length !== 16) throw new Error("IV must be 16 bytes");
    const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
    let decrypted = decipher.update(Buffer.from(mobileNumber, "base64"));
    decrypted = Buffer.concat([decrypted, decipher.final()]);

    const decryptedStr = decrypted.toString("utf8"); // Convert Buffer → String

    const decryptedObj = JSON.parse(decryptedStr); // Convert JSON string → object
    mobileNumber = decryptedObj.mobileNumber;
    const otpTemplateId = "65648d86d6fc0502dd1ab8e2";
    try {
      if (mobileNumber == "917092327667") {
        const resp = {
          success: true,
          result: {
            request_id: "346342707568323638313036",
            type: "success",
          },
        };
        const encrypted_data = await axios.post(
          `http://localhost:7000/crypto/encrypt`,
          resp
        );
        return encrypted_data.data.encrypted;
      } else {
        const result = await this.otpService.sendOtp(
          mobileNumber,
          otpTemplateId
        );
        let succ_req;
        if (result.status_code !== 200) {
          succ_req = { success: false, result };
        } else {
          succ_req = { success: true, result };
        }
        console.log(result, "result");

        const encrypted_data = await axios.post(
          `http://localhost:7000/crypto/encrypt`,
          succ_req
        );

        return encrypted_data.data.encrypted;
      }
    } catch (error) {
      console.log(error, "error");

      const error_req = { success: false, error: error.message };
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        error_req
      );
      return encrypted_data.data.encrypted;
    }
  }

  @UseGuards(AuthApiKeyGuard, ThrottlerGuard)
  @SkipThrottle()
  // @Throttle(5, 600)
  @Post("/forgot-mpin/encrypted")
  async encsendOtpFor(@Body() mobileNumber: any): Promise<any> {
    mobileNumber = mobileNumber.body;
    let base64Key = process.env.encryption_key;
    let base64Iv = process.env.encryption_iv;

    const key = Buffer.from(base64Key, "base64");
    const iv = Buffer.from(base64Iv, "base64");

    if (key.length !== 32) throw new Error("Key must be 32 bytes");
    if (iv.length !== 16) throw new Error("IV must be 16 bytes");
    const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
    let decrypted = decipher.update(Buffer.from(mobileNumber, "base64"));
    decrypted = Buffer.concat([decrypted, decipher.final()]);

    const decryptedStr = decrypted.toString("utf8"); // Convert Buffer → String
    const decryptedObj = JSON.parse(decryptedStr); // Convert JSON string → object
    mobileNumber = decryptedObj.mobileNumber;
    const otpTemplateId = "65648d86d6fc0502dd1ab8e2";
    try {
      if (mobileNumber == "917092327667") {
        const resp = {
          success: true,
          result: {
            request_id: "346342707568323638313036",
            type: "success",
          },
        };
        const encrypted_data = await axios.post(
          `http://localhost:7000/crypto/encrypt`,
          resp
        );
        return encrypted_data.data.encrypted;
      } else {
        const result = await this.otpService.sendOtp(
          mobileNumber,
          otpTemplateId
        );
        let succ_req;
        if (result.status_code !== 200) {
          succ_req = { success: false, result };
        } else {
          succ_req = { success: true, result };
        }
        console.log(result, "result");

        const encrypted_data = await axios.post(
          `http://localhost:7000/crypto/encrypt`,
          succ_req
        );

        return encrypted_data.data.encrypted;
      }
    } catch (error) {
      const error_req = { success: false, error: error.message };
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        error_req
      );
      return encrypted_data.data.encrypted;
    }
  }
}
