import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Delete,
  Query,
  UseGuards,
  Req,
} from "@nestjs/common";
import { AppointmentService } from "./appointment.service";
import { Appointment } from "./entities/appointment.entity";
import { AuthGuard } from "src/auth/auth.guard";
import { SkipThrottle, Throttle, ThrottlerGuard } from "@nestjs/throttler";
import { auth } from "google-auth-library";

@Controller("appointment")
export class AppointmentController {
  constructor(private readonly appointmentService: AppointmentService) {}
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Post()
  create(@Body() AppointmentEntity: Appointment) {
    const priority = AppointmentEntity.priority?.toLowerCase();

    if (!priority) {
      return {
        status_code: 500,
        status: "failed",
        message: "Select your appointment priority status",
      };
    }

    const validPriorities = ["normal", "urgent", "emergency"];

    if (!validPriorities.includes(priority)) {
      return {
        status_code: 500,
        status: "failed",
        message: "Provide an appropriate appointment priority status",
      };
    }
    return this.appointmentService.create(AppointmentEntity);
  }
  // ssss
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("/doctors")
  findDoctors(@Query("search") search: string) {
    return this.appointmentService.findDoctors(search);
  }
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("/doctors/:id")
  findOneDoctors(@Param("id") id: number) {
    return this.appointmentService.findOneDoctors(id);
  }
  @UseGuards(AuthGuard, ThrottlerGuard)
  @Get("/past/:id")
  findAllPast(@Param("id") id: string) {
    return this.appointmentService.findAllPast(+id);
  }
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("/upcoming/:id")
  findAllUpcoming(@Param("id") id: string) {
    return this.appointmentService.findAllUpcoming(+id);
  }
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("/getOne/:appointment_id")
  findOne(
    @Param("appointment_id") appointment_id: string,
    @Req() auth_token: any
  ) {
    return this.appointmentService.findOne(
      +appointment_id,
      auth_token.headers["authorization"]
    );
  }
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("/getQR/:appointment_id")
  findOneQR(@Param("appointment_id") appointment_id: string) {
    return this.appointmentService.findOneQR(appointment_id);
  }
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Post(":id")
  update(@Param("id") id: string, @Body() AppointmentEntity: Appointment) {
    return this.appointmentService.update(+id, AppointmentEntity);
  }
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Delete(":id")
  remove(@Param("id") id: string) {
    return this.appointmentService.remove(+id);
  }
  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Patch("/cancelAppointment/:id")
  updateCancelApp(
    @Param("id") id: string,
    @Body() AppointmentEntity: Appointment
  ) {
    return this.appointmentService.updateCancelApp(+id, AppointmentEntity);
  }

  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("v2/past")
  async findAllPastlist(
    @Query("id") id: string,
    @Query("limit") limit?: string,
    @Query("page") page?: string,
    @Query("filters") filters?: string,
    @Query("dateRange") dateRange?: string
  ) {
    if (!id) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING,
        status: process.env.ERROR_STATUS,
        message: process.env.PATIENT_ID_ERR,
      };
    }
    try {
      let past_result = await this.appointmentService.findAllPastlist(
        +id,
        +limit || 10,
        +page || 1,
        filters,
        dateRange
      );
      if (past_result.details.length > 0) {
        return {
          status_code: process.env.SUCCESS_STATUS_CODE,
          status: process.env.SUCCESS_STATUS,
          message: process.env.SUCCESS_MESSAGE,
          data: past_result.details,
          total: past_result.total,
        };
      } else {
        return {
          status_code: process.env.SUCCESS_STATUS_CODE,
          status: process.env.SUCCESS_STATUS,
          message: process.env.DATA_NOT_FOUND,
        };
      }
    } catch (error) {
      return {
        status_code: process.env.ERROR_STATUS_CODE,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE,
      };
    }
  }

  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("v2/upcoming")
  async findAllUpcominglist(
    @Query("id") id: string,
    @Query("limit") limit?: string,
    @Query("page") page?: string,
    @Query("filters") filters?: string,
    @Query("dateRange") dateRange?: string
  ) {
    if (!id) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING,
        status: process.env.ERROR_STATUS,
        message: process.env.PATIENT_ID_ERR,
      };
    }
    try {
      let output = await this.appointmentService.findAllUpcominglist(
        +id,
        +limit || 10,
        +page || 1,
        filters,
        dateRange
      );

      if (output.details.length > 0) {
        return {
          status_code: process.env.SUCCESS_STATUS_CODE,
          status: process.env.SUCCESS_STATUS,
          message: process.env.SUCCESS_MESSAGE,
          data: output.details,
          total: output.total,
        };
      } else {
        return {
          status_code: process.env.SUCCESS_STATUS_CODE,
          status: process.env.SUCCESS_STATUS,
          message: process.env.DATA_NOT_FOUND,
        };
      }
    } catch (error) {
      return {
        status_code: process.env.ERROR_STATUS_CODE,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE,
      };
    }
  }

  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("v2/doctors")
  async findDoctorslist(
    @Query("search") search: string,
    @Query("limit") limit?: string,
    @Query("page") page?: string
  ) {
    try {
      let final_out = await this.appointmentService.findDoctorslist(
        search,
        +limit || 10,
        +page || 1
      );

      if (final_out.details.length > 0) {
        return {
          status_code: process.env.SUCCESS_STATUS_CODE,
          status: process.env.SUCCESS_STATUS,
          message: process.env.SUCCESS_MESSAGE,
          data: final_out.details,
          total: final_out.total,
        };
      } else {
        return {
          status_code: process.env.SUCCESS_STATUS_CODE,
          status: process.env.SUCCESS_STATUS,
          message: process.env.DATA_NOT_FOUND,
        };
      }
    } catch (error) {
      return {
        status_code: process.env.ERROR_STATUS_CODE,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE,
      };
    }
  }

  @Get("lastAppointment")
  async findlastOnelist(
    @Query("id") id: string,
    @Query("limit") limit?: string,
    @Query("page") page?: string
  ) {
    if (!id) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING,
        status: process.env.ERROR_STATUS,
        message: process.env.PATIENT_ID_ERR,
      };
    }
    try {
      let past_result = await this.appointmentService.findLastOneAppointment(
        +id,
        +limit || 1,
        +page || 1
      );
      if (past_result.details.length > 0) {
        return {
          status_code: process.env.SUCCESS_STATUS_CODE,
          status: process.env.SUCCESS_STATUS,
          message: process.env.SUCCESS_MESSAGE,
          data: past_result.details,
        };
      } else {
        return {
          status_code: process.env.SUCCESS_STATUS_CODE,
          status: process.env.SUCCESS_STATUS,
          message: process.env.DATA_NOT_FOUND,
        };
      }
    } catch (error) {
      return {
        status_code: process.env.ERROR_STATUS_CODE,
        status: process.env.ERROR_STATUS,
        message: process.env.ERROR_MESSAGE,
      };
    }
  }

  @UseGuards(AuthGuard, ThrottlerGuard)
  @SkipThrottle()
  @Get("/encrypt-getQR/:appointment_id")
  EncryptfindOneQR(@Param("appointment_id") appointment_id: string) {
    return this.appointmentService.EncryptfindOneQR(appointment_id);
  }

  @SkipThrottle()
  @Get("/encrypt-getQR/v2/:appointment_id")
  V2EncryptfindOneQR(@Param("appointment_id") appointment_id: string) {
    return this.appointmentService.V2EncryptfindOneQR(appointment_id);
  }
}
