import {
  Controller,
  Get,
  Post,
  Body,
  Patch,
  Param,
  Query,
  UseGuards,
} from "@nestjs/common";
import { AppointmentService } from "./appointment.service";
import {
  CancelAppointment,
  CancelAppointmentResponse200,
  chargeout,
  ErrorResponse400,
  ErrorResponse500,
  PostAppointment,
  StatusChangePatch,
  SuccessResponse,
  updateappdetails,
  UpdateAppointment,
  UpdateAppointmentcharge,
  UpdateAppointmentResponse,
  UpdateStatusResponse200,
} from "./entities/appointment.entity";
import { ApiOperation, ApiBody, ApiResponse, ApiTags } from "@nestjs/swagger";
import { AuthGuard } from "src/auth/auth.guard";
@ApiTags("appointment")
@Controller("appointment")
export class AppointmentController {
  constructor(private readonly appointmentService: AppointmentService) { }

  @Post()
  @ApiOperation({ summary: "Create a new appointment" })
  @ApiBody({
    description: "Details of the appointment to be created",
    type: PostAppointment,
  })
  @ApiResponse({
    status: 201,
    description: "The appointment has been successfully created.",
    type: SuccessResponse,
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
    type: ErrorResponse400,
  })
  @ApiResponse({
    status: 500,
    description: "Internal server error.",
    type: ErrorResponse500,
  })
  create(@Body() entity: PostAppointment) {
    if (!entity.Hospital_id) {
      return {
        status: "failed",
        message: "Enter hospital_id to get the values",
      };
    }
    if (!entity.received_by_name) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING,
        status: process.env.ERROR_STATUS,
        message: process.env.HOSPITAL_ID_ERR,
      };
    }
    return this.appointmentService.create(entity);
  }

  // @UseGuards(AuthGuard)
  @Get()
  @ApiOperation({ summary: "Retrieve all appointments based on filters" })
  @ApiResponse({
    status: 200,
    description: "List of appointments retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  findAll(
    @Query("fromDate") fromDate: string,
    @Query("toDate") toDate: string,
    @Query("doctorId") doctorId: number,
    @Query("appointStatus") appointStatus: string,
    @Query("payment_status") paymentStatus: string,
    @Query("hospital_id") hospital_id: number
  ) {
    if (!hospital_id) {
      return {
        status: "failed",
        message: "Enter hospital_id to get the values",
      };
    }
    return this.appointmentService.findAll(
      fromDate,
      toDate,
      doctorId,
      appointStatus,
      hospital_id,
      paymentStatus
    );
  }

  @Get("/history")
  @ApiOperation({ summary: "Retrieve appointment history based on filters" })
  @ApiResponse({
    status: 200,
    description: "Appointment history retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  findAllHistory(
    @Query("fromDate") fromDate: string,
    @Query("toDate") toDate: string,
    @Query("doctorId") doctorId: number,
    @Query("appointStatus") appointStatus: string,
    @Query("payment_status") paymentStatus: string,
    @Query("hospital_id") hospital_id: number
  ) {
    if (!hospital_id) {
      return {
        status: "failed",
        message: "Enter hospital_id to get the values",
      };
    }
    return this.appointmentService.findAllHistory(
      fromDate,
      toDate,
      doctorId,
      appointStatus,
      hospital_id,
      paymentStatus
    );
  }

  @Get("/Today")
  @ApiOperation({
    summary: "Retrieve appointment Today appointments based on filters",
  })
  @ApiResponse({
    status: 200,
    description: "Appointment Today appointments retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  Today(
    @Query("fromDate") fromDate: string,
    @Query("toDate") toDate: string,
    @Query("doctorId") doctorId: number,
    @Query("appointStatus") appointStatus: string,
    @Query("payment_status") paymentStatus: string,
    @Query("hospital_id") hospital_id: number
  ) {
    if (!hospital_id) {
      return {
        status: "failed",
        message: "Enter hospital_id to get the values",
      };
    }
    return this.appointmentService.Today(
      fromDate,
      toDate,
      doctorId,
      appointStatus,
      hospital_id,
      paymentStatus
    );
  }

  @Get("/info")
  @ApiOperation({
    summary: "Retrieve appointment information based on token and hospital ID",
  })
  @ApiResponse({
    status: 200,
    description: "Appointment information retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  @ApiResponse({
    status: 404,
    description: "Appointment not found.",
  })
  findOne(
    @Query("token") token: string,
    @Query("hospital_id") hospital_id: number
  ) {
    return this.appointmentService.findOne(token, hospital_id);
  }

  @Get("/getQR")
  @ApiOperation({
    summary: "Retrieve QR code information based on token and hospital ID",
  })
  @ApiResponse({
    status: 200,
    description: "QR code information retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  @ApiResponse({
    status: 404,
    description: "QR code not found.",
  })
  findQR(
    @Query("token") token: string,
    @Query("hospital_id") hospital_id: number
  ) {
    return this.appointmentService.findQR(token, hospital_id);
  }

  @Get("/encrypted-getQR")
  @ApiOperation({
    summary: "Retrieve QR code information based on token and hospital ID",
  })
  @ApiResponse({
    status: 200,
    description: "QR code information retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  @ApiResponse({
    status: 404,
    description: "QR code not found.",
  })
  EnfindQR(
    @Query("token") token: string,
    @Query("hospital_id") hospital_id: number
  ) {
    return this.appointmentService.EncryptedfindQR(token, hospital_id);
  }

  @Get("/encrypted-getQR/v2")
  @ApiOperation({
    summary: "Retrieve QR code information based on token and hospital ID",
  })
  @ApiResponse({
    status: 200,
    description: "QR code information retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  @ApiResponse({
    status: 404,
    description: "QR code not found.",
  })
  EnfindQRV2(
    @Query("token") token: string,
    @Query("hospital_id") hospital_id: number
  ) {
    return this.appointmentService.V2EncryptedfindQR(token, hospital_id);
  }

  @Patch("/status/:id")
  @ApiOperation({ summary: "Update the status of an appointment" })
  @ApiResponse({
    status: 200,
    description: "The appointment status has been successfully updated.",
    type: UpdateStatusResponse200,
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
    type: ErrorResponse400,
  })
  @ApiResponse({
    status: 404,
    description: "Appointment not found.",
  })
  @ApiResponse({
    status: 500,
    description: "Internal server error.",
    type: ErrorResponse500,
  })
  updateStatus(@Param("id") id: string, @Body() entity: StatusChangePatch) {
    return this.appointmentService.updateStatus(id, entity);
  }

  @Post("/reshedule/:id")
  @ApiOperation({ summary: "Resheduling appointment" })
  @ApiResponse({
    status: 200,
    description: "Appointment resheduleld successfully",
    type: UpdateAppointmentResponse,
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  @ApiResponse({
    status: 404,
    description: "Appointment not found.",
  })
  @ApiResponse({
    status: 500,
    description: "Internal server error.",
    type: ErrorResponse500,
  })
  update(@Param("id") id: string, @Body() Entity: UpdateAppointment) {
    if (!Entity.received_by_name) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING,
        status: process.env.ERROR_STATUS,
        message: process.env.HOSPITAL_ID_ERR,
      };
    }
    return this.appointmentService.reshedule(id, Entity);
  }

  @Patch("/cancel/:id")
  @ApiOperation({ summary: "Cancel an appointment" })
  @ApiResponse({
    status: 200,
    description: "The appointment has been successfully canceled.",
    type: CancelAppointmentResponse200,
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  @ApiResponse({
    status: 404,
    description: "Appointment not found.",
  })
  @ApiResponse({
    status: 500,
    description: "Internal server error.",
    type: ErrorResponse500,
  })
  cancelAppointment(
    @Param("id") id: string,
    @Body() entity: CancelAppointment
  ) {
    return this.appointmentService.cancelAppointment(id, entity);
  }

  @Patch("/add-or-discount-charges/:id")
  @ApiOperation({
    summary:
      "Add or update additional charges and discounts for an appointment",
  })
  @ApiResponse({
    status: 200,
    description: "Charges updated successfully.",
    type: chargeout,
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
    type: ErrorResponse400,
  })
  @ApiResponse({
    status: 404,
    description: "Appointment not found.",
  })
  @ApiResponse({
    status: 500,
    description: "Internal server error.",
    type: ErrorResponse500,
  })
  remove(@Param("id") id: string, @Body() entity: UpdateAppointmentcharge) {
    return this.appointmentService.updateChargeDetails(+id, entity);
  }

  @Post("/updatePaymentDetails")
  @ApiOperation({
    summary:
      "Add or update additional charges and discounts for an appointment",
  })
  @ApiResponse({
    status: 200,
    description: "Charges updated successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
    type: ErrorResponse400,
  })
  @ApiResponse({
    status: 404,
    description: "Appointment not found.",
  })
  @ApiResponse({
    status: 500,
    description: "Internal server error.",
    type: ErrorResponse500,
  })
  makePayment(
    @Query("transaction_id") id: string,
    @Body() entity: PostAppointment
  ) {
    if (!entity.received_by_name) {
      return {
        status_code: process.env.ERROR_STATUS_CODE_PARAMS_MISSING,
        status: process.env.ERROR_STATUS,
        message: process.env.HOSPITAL_ID_ERR,
      };
    }
    return this.appointmentService.makepayment(entity, id);
  }

  //v2
  @UseGuards(AuthGuard)
  @Get("/v2/upcoming")
  @ApiOperation({ summary: "Retrieve all appointments based on filters" })
  @ApiResponse({
    status: 200,
    description: "List of appointments retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  V2findAll(
    @Query("fromDate") fromDate: string,
    @Query("toDate") toDate: string,
    @Query("doctorId") doctorId: number,
    @Query("appointStatus") appointStatus: string,
    @Query("payment_status") paymentStatus: string,
    @Query("hospital_id") hospital_id: number,
    @Query("limit") limit: number,
    @Query("page") page: number
  ) {
    if (!hospital_id) {
      return {
        status: "failed",
        message: "Enter hospital_id to get the values",
      };
    }

    return this.appointmentService.V2findAll(
      fromDate,
      toDate,
      doctorId,
      appointStatus,
      hospital_id,
      paymentStatus,
      limit || 10,
      page || 1
    );
  }

  @UseGuards(AuthGuard)
  @Get("/v2/today")
  @ApiOperation({
    summary: "Retrieve appointment Today appointments based on filters",
  })
  @ApiResponse({
    status: 200,
    description: "Appointment Today appointments retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  V2Today(
    @Query("fromDate") fromDate: string,
    @Query("toDate") toDate: string,
    @Query("doctorId") doctorId: number,
    @Query("appointStatus") appointStatus: string,
    @Query("payment_status") paymentStatus: string,
    @Query("hospital_id") hospital_id: number,
    @Query("limit") limit: number,
    @Query("page") page: number
  ) {
    if (!hospital_id) {
      return {
        status: "failed",
        message: "Enter hospital_id to get the values",
      };
    }
    return this.appointmentService.V2Today(
      fromDate,
      toDate,
      doctorId,
      appointStatus,
      hospital_id,
      paymentStatus,
      limit || 10,
      page || 1
    );
  }

  @UseGuards(AuthGuard)
  @Get("/v2/history")
  @ApiOperation({ summary: "Retrieve appointment history based on filters" })
  @ApiResponse({
    status: 200,
    description: "Appointment history retrieved successfully.",
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  V2findAllHistory(
    @Query("fromDate") fromDate: string,
    @Query("toDate") toDate: string,
    @Query("doctorId") doctorId: number,
    @Query("appointStatus") appointStatus: string,
    @Query("payment_status") paymentStatus: string,
    @Query("hospital_id") hospital_id: number,
    @Query("limit") limit: number,
    @Query("page") page: number
  ) {
    if (!hospital_id) {
      return {
        status: "failed",
        message: "Enter hospital_id to get the values",
      };
    }
    return this.appointmentService.V2findAllHistory(
      fromDate,
      toDate,
      doctorId,
      appointStatus,
      hospital_id,
      paymentStatus,
      limit || 10,
      page || 1
    );
  }

  @UseGuards(AuthGuard)
  @Post("/update-appt-payment")
  @ApiOperation({ summary: "updating appointment" })
  @ApiResponse({
    status: 200,
    description: "Appointment resheduleld successfully",
    type: UpdateAppointmentResponse,
  })
  @ApiResponse({
    status: 400,
    description: "Bad request. Validation errors or missing parameters.",
  })
  @ApiResponse({
    status: 404,
    description: "Appointment not found.",
  })
  @ApiResponse({
    status: 500,
    description: "Internal server error.",
    type: ErrorResponse500,
  })
  updateappdetails(
    @Query("appointment_id") appointment_id: string,
    @Body() Entity: updateappdetails
  ) {
    return this.appointmentService.updateappointmentdetails(
      appointment_id,
      Entity
    );
  }

  @UseGuards(AuthGuard)
  @Get("/get-hos-appt-details")
  async getHosApptDetails(@Query("appt_id") appt_id: number) {
    if (!appt_id) {
      return {
        status: "failed",
        statusCode: 400,
        message: "appt_id is required",
      };
    }
    return this.appointmentService.getHosApptId(appt_id);
  }

  @UseGuards(AuthGuard)
  @Get("/speciality_list")
  async specialityList(@Query("hospital_id") hospital_id: number) {
    if (!hospital_id) {
      return {
        status: "failed",
        statusCode: 400,
        message: "hospital_id is required",
      };
    }
    return this.appointmentService.specialistList(hospital_id);
  }
}
