import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
  UseGuards,
  Req,
  Headers,
  Query,
} from "@nestjs/common";
import { SignUpService } from "./sign_up.service";
import { User } from "./entities/sign_up.entity";
import { AuthGuardRefresh } from "src/auth/auth.guard_refresh";
import { ThrottlerGuard, SkipThrottle } from "@nestjs/throttler";
import { AuthApiKeyGuard } from "src/auth/apiKey.guard";
import * as jwt from "jsonwebtoken";
import axios from "axios";

@Controller("sign_up")
export class SignUpController {
  constructor(private readonly signUpService: SignUpService) {}
  @UseGuards(ThrottlerGuard, AuthApiKeyGuard)
  @SkipThrottle()
  @Post("/check")
  async check_old_or_new(@Body() userEntity: any) {
    return await this.signUpService.check_old_or_new(userEntity);
  }

  @UseGuards(AuthApiKeyGuard)
  @SkipThrottle()
  @Post("/getDetails")
  getDetails(@Body() userEntity: User) {
    return this.signUpService.getDetails(userEntity);
  }
  @UseGuards(AuthApiKeyGuard)
  @Post("/old")
  async verifyOld(@Body() userEntity: any) {
    try {
      const decrypt = await axios.post(
        `http://localhost:7000/crypto/decrypt`,
        userEntity
      );
      userEntity = JSON.parse(decrypt.data.decrypted);
      console.log(userEntity, "userEntity");

      const result = await this.signUpService.verifyOld(userEntity);
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        result
      );
      return encrypted_data.data.encrypted;
    } catch (error) {
      const error_req = {
        status: "failed",
        statusCode: 400,
        message: "Encryption failed",
      };
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        error_req
      );
      return encrypted_data.data.encrypted;
    }
  }
  @UseGuards(AuthApiKeyGuard)
  @Post("/new")
  async createnew(@Body() userEntity: User) {
    try {
      const decrypt = await axios.post(
        `http://localhost:7000/crypto/decrypt`,
        userEntity
      );
      console.log(JSON.parse(decrypt.data.decrypted), "decrypt");
      userEntity = JSON.parse(decrypt.data.decrypted);
      const result = await this.signUpService.createnew(userEntity);
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        result
      );
      return encrypted_data.data.encrypted;
    } catch (error) {
      const error_req = {
        status: "failed",
        statusCode: 400,
        message: "Encryption failed",
      };
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        error_req
      );
      return encrypted_data.data.encrypted;
    }
  }
  @UseGuards(AuthApiKeyGuard)
  @Get("/settings/:id")
  findsettings(@Param("id") id: string) {
    return this.signUpService.findsettings(+id);
  }
  @UseGuards(AuthApiKeyGuard)
  @Patch("/updatePassword")
  async updatePassword(
    @Body() userEntity: User,
    @Headers() headers: any,
    @Query("username") username: string
  ) {
    try {
      if (!headers.authorization && !username) {
        console.log("header illayae", "id illayae");

        let result = {
          status: "failed",
          statusCode: 400,
          message: "Please provide token or username",
        };
        const encrypted_data = await axios.post(
          `http://localhost:7000/crypto/encrypt`,
          result
        );
        return encrypted_data.data.encrypted;
      }
      const decrypt = await axios.post(
        `http://localhost:7000/crypto/decrypt`,
        userEntity
      );
      console.log(JSON.parse(decrypt.data.decrypted), "decryptsss");
      userEntity = JSON.parse(decrypt.data.decrypted);
      let ids;
      if (headers.authorization) {
        try {
          const decoded = jwt.verify(
            headers.authorization,
            process.env.JWT_SECRET
          );
          ids = decoded.id;
        } catch (error) {
          console.log(error, "error");
        }
      } else {
        const user_id = await this.signUpService.get_user_id(username);
        ids = user_id;
      }
      console.log(ids, "asdf");

      const result = await this.signUpService.updatePassword(+ids, userEntity);
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        result
      );
      return encrypted_data.data.encrypted;
    } catch (error) {
      const error_req = {
        status: "failed",
        statusCode: 400,
        message: "Encryption failed",
      };
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        error_req
      );
      return encrypted_data.data.encrypted;
    }
  }
  @UseGuards(AuthApiKeyGuard)
  @Patch("/updateSettings/:id")
  async updateStettings(@Param("id") id: string, @Body() userEntity: User) {
    try {
      const decrypt = await axios.post(
        `http://localhost:7000/crypto/decrypt`,
        userEntity
      );
      console.log(JSON.parse(decrypt.data.decrypted), "decrypt");
      userEntity = JSON.parse(decrypt.data.decrypted);
      const result = await this.signUpService.updateStettings(+id, userEntity);
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        result
      );
      return encrypted_data.data.encrypted;
    } catch (error) {
      const error_req = {
        status: "failed",
        statusCode: 400,
        message: "Encryption failed",
      };
      const encrypted_data = await axios.post(
        `http://localhost:7000/crypto/encrypt`,
        error_req
      );
      return encrypted_data.data.encrypted;
    }
  }
  @UseGuards(AuthApiKeyGuard)
  @Delete(":id")
  remove(@Param("id") id: string) {
    return this.signUpService.remove(+id);
  }
  @UseGuards(AuthApiKeyGuard)
  @Post("/fcm")
  updateFCM(@Body() userEntity: User) {
    return this.signUpService.updateFCM(userEntity);
  }

  @UseGuards(AuthGuardRefresh)
  @Post("/getAccessToken")
  async getAccessToken(
    @Req() request: Request,
    @Body("username") username: string
  ) {
    if (!username) {
      return {
        status: "failed",
        message: "enter username to get access token",
      };
    }
    return await this.signUpService.createToken(
      username,
      request.headers["authorization"]
    );
  }

  // @UseGuards(AuthGuardRefresh)
  @Post("/getpatientlist")
  async getpatientlist(@Body() userEntity: any) {
    if (!userEntity.username) {
      return {
        status: "failed",
        message: "enter username to get patient list",
      };
    }
    return await this.signUpService.user_patient_list(userEntity);
  }
}
