import { forwardRef, Inject, Injectable } from "@nestjs/common";
import {
  CancelAppointment,
  PostAppointment,
  StatusChangePatch,
  UpdateAppointment,
  UpdateAppointmentcharge,
  updateappdetails,
} from "./entities/appointment.entity";
import { DataSource } from "typeorm";

import axios from "axios";
import { CryptoService } from "src/qr-encrpyt/qr-encrpyt.service";
@Injectable()
export class AppointmentService {
  constructor(
    private readonly connection: DataSource,
    @Inject(forwardRef(() => CryptoService))
    private readonly EncryptedService: CryptoService
  ) {}

  async create(AppointmentEntity: PostAppointment) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [AppointmentEntity.Hospital_id]
      );
      const bookAppointment = await axios.post(
        `${getBaseURL.op_hub_base_url}/op-hub-appointment`,
        AppointmentEntity
      );
      return bookAppointment.data;
    } catch (error) {
      console.log(error, "error");

      throw new Error("error is : " + error);
    }
  }

  async findAll(
    fromDate: string,
    toDate: string,
    doctorId: number,
    appointStatus: string,
    hospital_id: number,
    paymentStatus: string
  ) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment?hospital_id=${hospital_id}`;
      if (fromDate) {
        apiURL += `&fromDate=${fromDate}`;
      }
      if (toDate) {
        apiURL += `&toDate=${toDate}`;
      }
      if (doctorId) {
        apiURL += `&doctorId=${doctorId}`;
      }
      if (appointStatus) {
        apiURL += `&appointStatus=${appointStatus}`;
      }
      if (paymentStatus) {
        apiURL += `&payment_status=${paymentStatus}`;
      }
      const getAppointment = await axios.get(apiURL);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async Today(
    fromDate: string,
    toDate: string,
    doctorId: number,
    appointStatus: string,
    hospital_id: number,
    paymentStatus: string
  ) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/Today?hospital_id=${hospital_id}`;
      if (fromDate) {
        apiURL += `&fromDate=${fromDate}`;
      }
      if (toDate) {
        apiURL += `&toDate=${toDate}`;
      }
      if (doctorId) {
        apiURL += `&doctorId=${doctorId}`;
      }
      if (appointStatus) {
        apiURL += `&appointStatus=${appointStatus}`;
      }
      if (paymentStatus) {
        apiURL += `&payment_status=${paymentStatus}`;
      }
      const getAppointment = await axios.get(apiURL);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async findAllHistory(
    fromDate: string,
    toDate: string,
    doctorId: number,
    appointStatus: string,
    hospital_id: number,
    paymentStatus: string
  ) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/history?hospital_id=${hospital_id}`;
      if (fromDate) {
        apiURL += `&fromDate=${fromDate}`;
      }
      if (toDate) {
        apiURL += `&toDate=${toDate}`;
      }
      if (doctorId) {
        apiURL += `&doctorId=${doctorId}`;
      }
      if (appointStatus) {
        apiURL += `&appointStatus=${appointStatus}`;
      }
      if (paymentStatus) {
        apiURL += `&payment_status=${paymentStatus}`;
      }
      const getAppointment = await axios.get(apiURL);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async findOne(token: string, hospital_id: number) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/info?hospital_id=${hospital_id}&token=${token}`;
      const getAppointment = await axios.get(apiURL);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async findQR(token: string, hospital_id: number) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/getQR?hospital_id=${hospital_id}&token=${token}`;
      const getAppointment = await axios.get(apiURL);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async EncryptedfindQR(token: string, hospital_id: number) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/getQR?hospital_id=${hospital_id}&token=${token}`;
      const getAppointment = await axios.get(apiURL);
      delete getAppointment.data?.Appointment_details?.id;

      delete getAppointment.data?.Appointment_details?.doctor_id;
      delete getAppointment.data?.Appointment_details?.mobileno;
      delete getAppointment.data?.Appointment_details?.tokenNumber;
      let create_qr = getAppointment.data.Appointment_details;
      ((create_qr.QR_Type_ID = 3), (create_qr.QR_Type = "Appointment_QR"));

      const encrypt_apicall = await this.EncryptedService.encrypt(
        JSON.stringify(create_qr),
        process.env.encryption_key,
        process.env.encryption_iv
      );
      return encrypt_apicall;
    } catch (error) {
      throw new Error(error);
    }
  }

  async V2EncryptedfindQR(token: string, hospital_id: number) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      console.log(getBaseURL, "getBaseURL");

      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/getQR?hospital_id=${hospital_id}&token=${token}`;
      const getAppointment = await axios.get(apiURL);
      delete getAppointment.data?.Appointment_details?.id;

      delete getAppointment.data?.Appointment_details?.doctor_id;
      delete getAppointment.data?.Appointment_details?.mobileno;
      delete getAppointment.data?.Appointment_details?.tokenNumber;
      delete getAppointment.data?.Appointment_details?.patient_id;
      delete getAppointment.data?.Appointment_details?.aayush_unique_id;
      delete getAppointment.data?.Appointment_details?.Hospital_id;
      delete getAppointment.data?.Appointment_details?.appointment_id;
      delete getAppointment.data?.Appointment_details?.hos_appointment_id;

      let create_qr = getAppointment.data.Appointment_details;
      create_qr.id = create_qr.phr_appointment_id;
      delete create_qr.phr_appointment_id;
      console.log(create_qr, "create_qr");

      ((create_qr.QR_Type_ID = 3), (create_qr.QR_Type = "Appointment_QR"));
      console.log(create_qr, "create_qr");

      const encrypt_apicall = await this.EncryptedService.encrypt(
        JSON.stringify(create_qr),
        process.env.encryption_key,
        process.env.encryption_iv
      );
      return encrypt_apicall;
    } catch (error) {
      console.log(error, "aassddffhvnhh");

      throw new Error(error);
    }
  }
  async updateStatus(id: string, Entity: StatusChangePatch) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [Entity.Hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/status/${id}`;
      const getAppointment = await axios.patch(apiURL, Entity);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async reshedule(id: string, Entity: UpdateAppointment) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [Entity.Hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/reshedule/${id}`;
      const getAppointment = await axios.post(apiURL, Entity);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async updateChargeDetails(id: number, Entity: UpdateAppointmentcharge) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [Entity.Hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/add-or-discount-charges/${id}`;
      const getAppointment = await axios.patch(apiURL, Entity);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async cancelAppointment(id: string, Entity: CancelAppointment) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [Entity.Hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/cancel/${id}`;
      const getAppointment = await axios.patch(apiURL, Entity);
      return getAppointment.data;
    } catch (error) {
      console.log(error, "error");

      throw new Error(error);
    }
  }

  async makepayment(paymentDetails: PostAppointment, transaction_id: any) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [paymentDetails.Hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/updatePaymentDetails?transaction_id=${transaction_id}`;
      console.log(apiURL, "apiURL");

      const getAppointment = await axios.post(apiURL, paymentDetails);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  //v2 API's http://13.200.35.19:3102/op-hub-appointment/updatePaymentDetails?transaction_id=TRID2229

  async V2findAll(
    fromDate: string,
    toDate: string,
    doctorId: number,
    appointStatus: string,
    hospital_id: number,
    paymentStatus: string,
    limit: number,
    page: number
  ) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      console.log(getBaseURL, "getBaseURL");

      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/v2/upcoming-appointment?hospital_id=${hospital_id}&limit=${limit}&page=${page}`;
      console.log(apiURL, "apiURL");

      if (fromDate) {
        apiURL += `&fromDate=${fromDate}`;
      }
      if (toDate) {
        apiURL += `&toDate=${toDate}`;
      }
      if (doctorId) {
        apiURL += `&doctorId=${doctorId}`;
      }
      if (appointStatus) {
        apiURL += `&appointStatus=${appointStatus}`;
      }
      if (paymentStatus) {
        apiURL += `&payment_status=${paymentStatus}`;
      }
      const getAppointment = await axios.get(apiURL);
      return getAppointment.data;
    } catch (error) {
      console.log(error, "err");

      throw new Error(error);
    }
  }

  async V2Today(
    fromDate: string,
    toDate: string,
    doctorId: number,
    appointStatus: string,
    hospital_id: number,
    paymentStatus: string,
    limit: number,
    page: number
  ) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/v2/today-appointment?hospital_id=${hospital_id}&limit=${limit}&page=${page}`;
      if (fromDate) {
        apiURL += `&fromDate=${fromDate}`;
      }
      if (toDate) {
        apiURL += `&toDate=${toDate}`;
      }
      if (doctorId) {
        apiURL += `&doctorId=${doctorId}`;
      }
      if (appointStatus) {
        apiURL += `&appointStatus=${appointStatus}`;
      }
      if (paymentStatus) {
        apiURL += `&payment_status=${paymentStatus}`;
      }
      const getAppointment = await axios.get(apiURL);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async V2findAllHistory(
    fromDate: string,
    toDate: string,
    doctorId: number,
    appointStatus: string,
    hospital_id: number,
    paymentStatus: string,
    limit: number,
    page: number
  ) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );
      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/v2/history-appointment?hospital_id=${hospital_id}&limit=${limit}&page=${page}`;
      if (fromDate) {
        apiURL += `&fromDate=${fromDate}`;
      }
      if (toDate) {
        apiURL += `&toDate=${toDate}`;
      }
      if (doctorId) {
        apiURL += `&doctorId=${doctorId}`;
      }
      if (appointStatus) {
        apiURL += `&appointStatus=${appointStatus}`;
      }
      if (paymentStatus) {
        apiURL += `&payment_status=${paymentStatus}`;
      }
      const getAppointment = await axios.get(apiURL);
      return getAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async updateappointmentdetails(
    appointment_id: string,
    appdetails: updateappdetails
  ) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [appdetails.Hospital_id]
      );

      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/update-appt-payment?appointment_id=${appointment_id}`;

      const updateAppointment = await axios.post(apiURL, appdetails);
      return updateAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }

  async getHosApptId(appt_id: number) {
    const [getHosApptDetails] = await this.connection.query(
      `select concat("APPN",hos_appointment_id) id,Hospital_id from appointment where id = ? `,
      [appt_id]
    );
    return {
      status: "success",
      statusCode: 200,
      message: "Details fetched succeessfully",
      data: getHosApptDetails,
    };
  }

  async specialistList(hospital_id: number) {
    try {
      const [getBaseURL] = await this.connection.query(
        `select op_hub_base_url from hospitals where plenome_id = ?`,
        [hospital_id]
      );

      let apiURL = `${getBaseURL.op_hub_base_url}/op-hub-appointment/speciality_list`;

      const updateAppointment = await axios.get(apiURL);
      return updateAppointment.data;
    } catch (error) {
      throw new Error(error);
    }
  }
}
