import { forwardRef, Inject, Injectable } from "@nestjs/common";
import { CreateScanAndShareAppointmentTokenDto } from "./dto/create-scan-and-share-appointment-token.dto";
import { DataSource } from "typeorm";
import { AppointmentService } from "src/appointment/appointment.service";
@Injectable()
export class ScanAndShareAppointmentTokenService {
  constructor(
    private readonly connection: DataSource,
    @Inject(forwardRef(() => AppointmentService))
    private appointmentServices: AppointmentService
  ) { }

  async generateUniqueId() {
    const digits = Array.from({ length: 10 }, () =>
      Math.floor(Math.random() * 10)
    ).join("");
    const alphabets = Array.from({ length: 5 }, () =>
      String.fromCharCode(65 + Math.floor(Math.random() * 26))
    ).join("");

    // Shuffle only the first 11 characters, ensuring last 4 are numeric
    const shuffled = (digits.slice(0, 6) + alphabets)
      .split("")
      .sort(() => Math.random() - 0.5)
      .join("");

    return shuffled + digits.slice(6, 10); // Ensuring last 4 are numeric
  }
  async create(
    createScanAndShareAppointmentTokenDto: CreateScanAndShareAppointmentTokenDto
  ) {
    console.log(
      createScanAndShareAppointmentTokenDto.profile.patient.abhaNumber,
      "createScanAndShareAppointmentTokenDto"
    );

    if (!createScanAndShareAppointmentTokenDto.metaData.hipId) {
      return {
        status: "failed",
        message: "hipId is required",
      };
    }
    console.log(
      createScanAndShareAppointmentTokenDto.metaData.hipId,
      "createScanAndShareAppointmentTokenDto.metaData.hipId"
    );

    let [hos_id] = await this.connection.query(
      `select plenome_id from hospitals where hip_id = ?`,
      [createScanAndShareAppointmentTokenDto.metaData.hipId]
    );
    try {
      const currentDate = new Date();
      const updatedDate = new Date(currentDate.getTime() + (5.5 * 60 * 60 * 1000));

      let employee_id = createScanAndShareAppointmentTokenDto.metaData.context;
      let staffempID = employee_id.split("-")[1];
      const formattedDate = updatedDate.toISOString().split("T")[0];
      const formattedTime = updatedDate
        .toISOString()
        .split("T")[1]
        .split(".")[0];
      if (staffempID != "0") {
        const [getStaff] = await this.connection.query(
          `select id from staff where employee_id = ?`,
          [staffempID]
        );
        console.log(getStaff, "getStaff");

        const [get_slot_and_shift] = await this.connection.query(
          `SELECT * 
    FROM doctor_shift 
    WHERE staff_id = ? and day = DAYNAME(date(now())) 
      AND time(now()) BETWEEN start_time AND end_time;
    `,
          [getStaff.id]
        );
        let uuid = await this.generateUniqueId();
        const patDetails = createScanAndShareAppointmentTokenDto.profile;
        const { yearOfBirth, monthOfBirth, dayOfBirth } = patDetails.patient;

        const mysqlDate = `${yearOfBirth}-${String(monthOfBirth).padStart(2, "0")}-${String(dayOfBirth).padStart(2, "0")}`;
        console.log(patDetails.patient.abhaNumber, "mysqlDate");

        const [check_address_pat_in_Admin] = await this.connection.query(
          `select * from patients where (ABHA_number = ?) or (patient_name like ? and dob = ? and mobileno = ?)`,
          [
            patDetails.patient.abhaNumber,
            `%${patDetails.patient.name}%`,
            mysqlDate,
            patDetails.patient.phoneNumber,
          ]
        );
        console.log(
          check_address_pat_in_Admin,
          "check_address_pat_in_Admin",
          patDetails.patient.abhaNumber
        );

        let pat_id;
        try {
          if (check_address_pat_in_Admin) {
            pat_id = check_address_pat_in_Admin.id;
            console.log("palaya patient thaa bahaa");
          } else {
            let abha;
            if (patDetails.patient.abhaNumber) {
              let inputString = patDetails.patient.abhaNumber;
              abha = inputString;
            }
            let pirandha_date = null;
            if (
              patDetails.patient.yearOfBirth &&
              patDetails.patient.monthOfBirth &&
              patDetails.patient.dayOfBirth
            ) {
              pirandha_date =
                patDetails.patient.yearOfBirth +
                "-" +
                patDetails.patient.monthOfBirth +
                "-" +
                patDetails.patient.dayOfBirth;
            }
            console.log(pirandha_date, "pirandha_date");

            const create_new_pat = await this.connection.query(
              `INSERT into patients(patient_name,
          dob,
          mobileno,
          gender,
          address,
          ABHA_number,
          state_name,
          district_name,
          aayush_unique_id,
          abha_address
          ) values(?,?,?,?,?,?,?,?,?,?)`,
              [
                patDetails.patient.name,
                pirandha_date,
                patDetails.patient.phoneNumber,
                patDetails.patient.gender,
                patDetails.patient.address.line +
                "," +
                patDetails.patient.address.pincode,
                abha,
                patDetails.patient.address.state,
                patDetails.patient.address.district,
                uuid,
                patDetails.patient.abhaAddress,
              ]
            );
            pat_id = create_new_pat.insertId;
            console.log("pudhu patient bhaa");
          }

          if (get_slot_and_shift) {
            let apptBookBody = {
              date: formattedDate.toString(),
              time: formattedTime.toString(),
              doctor: getStaff.id,
              shift_id: get_slot_and_shift.id,
              patient_id: pat_id,
              Hospital_id: hos_id.plenome_id,
              payment_mode: "Offline",
              live_consult: "no",
              global_shift_id: get_slot_and_shift.global_shift_id,
              abha_address: patDetails.patient.abhaAddress,
            };
            const bookAppnt =
              await this.appointmentServices.create(apptBookBody);
            return bookAppnt;
          } else {
            return {
              status: "failed",
              message: "Doctor is unavailable",
            };
          }
        } catch (error) {
          console.log(error, "1111[[]][[]][[]][[]]");
        }
      } else {
        let uuid = await this.generateUniqueId();
        const patDetails = createScanAndShareAppointmentTokenDto.profile;
        const { yearOfBirth, monthOfBirth, dayOfBirth } = patDetails.patient;
        const mysqlDate = `${yearOfBirth}-${String(monthOfBirth).padStart(2, "0")}-${String(dayOfBirth).padStart(2, "0")}`;

        const [check_address_pat_in_Admin] = await this.connection.query(
          `select * from patients where (ABHA_number = ?) or (patient_name like ? and dob = ? and mobileno = ?)`,
          [
            patDetails.patient.abhaNumber,
            `%${patDetails.patient.name}%`,
            mysqlDate,
            patDetails.patient.phoneNumber,
          ]
        );
        console.log(check_address_pat_in_Admin, "check_address_pat_in_Admin");

        let pat_id;
        try {
          if (check_address_pat_in_Admin) {
            console.log("iffff");

            pat_id = check_address_pat_in_Admin.id;
            console.log("palaya patient thaa bahaa");
          } else {
            console.log("elseee", patDetails.patient.abhaNumber);

            let abha;
            if (patDetails.patient.abhaNumber) {
              let inputString = patDetails.patient.abhaNumber;
              abha = inputString;
            }
            let pirandha_date = null;
            if (
              patDetails.patient.yearOfBirth &&
              patDetails.patient.monthOfBirth &&
              patDetails.patient.dayOfBirth
            ) {
              pirandha_date =
                patDetails.patient.yearOfBirth +
                "-" +
                patDetails.patient.monthOfBirth +
                "-" +
                patDetails.patient.dayOfBirth;
            }
            const create_new_pat = await this.connection.query(
              `INSERT into patients(patient_name,
          dob,
          mobileno,
          gender,
          address,
          ABHA_number,
          state_name,
          district_name,
          aayush_unique_id,
          abha_address
          ) values(?,?,?,?,?,?,?,?,?,?)`,
              [
                patDetails.patient.name,
                pirandha_date,
                patDetails.patient.phoneNumber,
                patDetails.patient.gender,
                patDetails.patient.address.line +
                "," +
                patDetails.patient.address.pincode,
                abha,
                patDetails.patient.address.state,
                patDetails.patient.address.district,
                uuid,
                patDetails.patient.abhaAddress,
              ]
            );
            pat_id = create_new_pat.insertId;
          }

          try {
            let apptBookBody = {
              date: formattedDate.toString(),
              time: formattedTime.toString(),
              patient_id: pat_id,
              Hospital_id: hos_id.plenome_id,
              payment_mode: "Offline",
              live_consult: "no",
              abha_address: patDetails.patient.abhaAddress,
            };
            console.log(apptBookBody, "apptBookBody");

            const bookAppnt =
              await this.appointmentServices.create(apptBookBody);
            return bookAppnt;
          } catch (error) {
            console.log(error, "idhu oru error");
          }
        } catch (error) {
          console.log(error, "[[]][[]][[]][[]]");
        }
      }
    } catch (error) {
      return {
        status: "failed",
        message: "unable to get token",
      };
    }
  }
}
