import { forwardRef, Inject, Injectable } from "@nestjs/common";
import { DataSource } from "typeorm";
import { ABHAProfile, Patient } from "./entities/profile.entity";
import { parse, format } from "date-fns";
import { CryptoService } from "src/qr-encrpyt/qr-encrpyt.service";
import * as jwt from "jsonwebtoken";

@Injectable()
export class ProfileService {
  constructor(
    private readonly connection: DataSource,
    @Inject(forwardRef(() => CryptoService))
    private readonly EncryptedService: CryptoService
  ) { }
  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("");
    const shuffled = (digits.slice(0, 6) + alphabets)
      .split("")
      .sort(() => Math.random() - 0.5)
      .join("");
    return shuffled + digits.slice(6, 10);
  }

  async create(PatientEntity: Patient) {
    let uuid = await this.generateUniqueId();
    if (!PatientEntity.dial_code) {
      PatientEntity.dial_code = "91";
    }
    const [checkOld] = await this.connection.query(
      `select * from  patients WHERE mobileno = ?`,
      [PatientEntity.mobileno]
    );
    console.log(checkOld, "[[]][[]][[]]][");

    const result = await this.connection.query(
      `INSERT INTO patients (
        patient_name,image,dob,email,
        gender,mobileno,blood_bank_product_id,
        emergency_mobile_no,address,state_code,district_code,pincode,
        ABHA_number,dial_code,salutation,emergency_dial_code,state_name,district_name,aayush_unique_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,
      [
        PatientEntity.patient_name,
        PatientEntity.image,
        PatientEntity.dob,
        PatientEntity.email,
        PatientEntity.gender,
        PatientEntity.mobileno,
        PatientEntity.blood_bank_product_id,
        PatientEntity.emergency_mobile_no,
        PatientEntity.address,
        PatientEntity.state_code,
        PatientEntity.district_code,
        PatientEntity.pincode,
        PatientEntity.ABHA_number,
        PatientEntity.dial_code,
        PatientEntity.salutation,
        PatientEntity.emergency_dial_code,
        PatientEntity.state_name,
        PatientEntity.district_name,
        uuid,
      ]
    );
    console.log(
      "000",
      result.insertId,
      PatientEntity.dial_code + PatientEntity.mobileno
    );

    const user = await this.connection.query(
      "update users set users.user_id = ? where users.username = ?",
      [result.insertId, PatientEntity.dial_code + PatientEntity.mobileno]
    );
    const [user_id] = await this.connection.query(`select id from users where username = ?`,
      [PatientEntity.dial_code + PatientEntity.mobileno]);
    console.log(user_id, "user_id", PatientEntity.dial_code + PatientEntity.mobileno);
    let id_token = user_id?.id
    if (!user_id) {
      const a = await this.connection.query(`insert into users (username,role,user_id) values (?,?,?)`,
        [PatientEntity.dial_code + PatientEntity.mobileno, 'Patient', result.insertId])
      id_token = a.insertId
    }


    return [
      {
        id: result.insertId,
        status: "success",
        user_id: id_token,
        messege: "Patient Profile added successfully",
        inserted_data: await this.connection.query(
          "SELECT * FROM patients WHERE id = ?",
          [result.insertId]
        ),
      },
    ];
  }

  async findOne(id_enc: string) {
    const id = await this.EncryptedService.decrypt(id_enc);
    console.log(id, "id");
    if (id === "Decryption failed") {
      return {
        status: "failed",
        status_code: 400,
        messege: "Invalid ID format",
      };
    }

    const [result] = await this.connection.query(
      `select patients.*,blood_bank_products.name blood_group
      from patients left join
       blood_bank_products on blood_bank_products.id = patients.blood_bank_product_id where patients.id = ?`,
      [id]
    );
    if (!result) {
      return [
        {
          status: "failed",
          status_code: 404,
          messege: "Patient not found",
        },
      ];
    }
    console.log(result, "result");

    let Emergencyno = result?.emergency_mobile_no;
    let EmergencynoTrimmedMobileno;
    if (Emergencyno) {
      if (Emergencyno.length > 10) {
        console.log(Emergencyno.length, "AdminPatientMobileNo.length");

        EmergencynoTrimmedMobileno = Emergencyno.startsWith("91")
          ? Emergencyno.slice(2)
          : Emergencyno;
      } else {
        EmergencynoTrimmedMobileno = Emergencyno;
      }
    }
    if (result?.dob) {
      const date = new Date(result.dob);

      const DOByear = date.getFullYear();
      const DOBmonth = (date.getMonth() + 1).toString().padStart(2, "0");
      const DOBday = date.getDate().toString().padStart(2, "0");

      const formattedDate = `${DOByear}-${DOBmonth}-${DOBday}`;
      console.log(formattedDate, "result.dob");

      result.dob = formattedDate;
    }
    result.emergency_mobile_no = EmergencynoTrimmedMobileno;
    const a = {
      status: "success",
      messege: "Patient Profile fetched successfully",
      profile: [
        {
          QR_Type_id: 4,
          QR_Type: "Patient_QR",
          profile_details: result,
        },
      ],
    };

    const encrypt_apicall = this.EncryptedService.encrypt(
      JSON.stringify(a),
      process.env.encryption_key,
      process.env.encryption_iv
    );
    return [
      {
        data: encrypt_apicall,
      },
    ];
  }

  async update(id: number, PatientEntity: Patient) {
    try {
      await this.connection.query(
        `UPDATE patients SET image = ?, patient_name =?,dob =?,email =?,gender =?,
        blood_bank_product_id =?,emergency_mobile_no =?,address =?,
        state_code =?,district_code =?,pincode =?,ABHA_number =?,dial_code = ?,salutation = ?,emergency_dial_code = ?,state_name = ?,district_name = ? WHERE id = ?`,
        [
          PatientEntity.image,
          PatientEntity.patient_name,
          PatientEntity.dob,
          PatientEntity.email,
          PatientEntity.gender,
          PatientEntity.blood_bank_product_id,
          PatientEntity.emergency_mobile_no,
          PatientEntity.address,
          PatientEntity.state_code,
          PatientEntity.district_code,
          PatientEntity.pincode,
          PatientEntity.ABHA_number,
          PatientEntity.dial_code,
          PatientEntity.salutation,
          PatientEntity.emergency_dial_code,
          PatientEntity.state_name,
          PatientEntity.district_name,
          id,
        ]
      );

      return [
        {
          data: {
            status: "success",
            messege: "Patient details updated successfully inserted",
            updated_values: await this.connection.query(
              "SELECT * FROM patients WHERE id = ?",
              [id]
            ),
          },
        },
      ];
    } catch (error) {
      return [
        {
          status: "failed",
          messege: "cannot update patient profile",
          error: error,
        },
      ];
    }
  }

  async updateAbhaNumber(id: string, Entity: ABHAProfile) {
    try {
      if (Entity.dob) {
        const inputDate = Entity.dob;
        const parsedDate = parse(inputDate, "dd-MM-yyyy", new Date());
        Entity.dob = await format(parsedDate, "yyyy-MM-dd");
      }
      if (Entity.gender == "M") {
        Entity.gender = "Male";
      } else if (Entity.gender == "F") {
        Entity.gender = "Female";
      } else if (Entity.gender == "O") {
        Entity.gender = "Others";
      }
      await this.connection.query(
        `UPDATE patients SET ABHA_number =?,
          patient_name = ?,
          dob = ?,
          gender = ?,
          address = ?,
          pincode = ?,
          state_code = ?,
          district_code = ?,
          state_name = ?,
          district_name = ?,
          is_kyc_verified = 1
           WHERE id = ?`,
        [
          Entity.ABHANumber,
          Entity.firstName + " " + Entity.middleName + " " + Entity.lastName,
          Entity.dob,
          Entity.gender,
          Entity.address,
          Entity.pinCode,
          Entity.stateCode,
          Entity.districtCode,
          Entity.stateName,
          Entity.districtName,
          id,
        ]
      );

      return [
        {
          data: {
            status: "success",
            messege: "AbhaNumber updated successfully inserted",
            updated_values: await this.connection.query(
              "SELECT * FROM patients WHERE id = ?",
              [id]
            ),
          },
        },
      ];
    } catch (error) {
      return [
        {
          status: "failed",
          messege: "cannot update Abha Number to patient profile",
          error: error,
        },
      ];
    }
  }
  async remove(id: number) {
    console.log(id, "aaa");
    try {
      await this.connection.query("DELETE FROM patients WHERE id = ?", [id]);
      return [
        {
          status: "success",
          message: " id: " + id + " deleted successfully",
        },
      ];
    } catch (error) {
      return [
        {
          status: "failed",
          message:
            "for patients those who booked appointments will cannot be deleted",
        },
      ];
    }
  }

  async Patientqr(id: number) {
    const [result] = await this.connection.query(
      `select coalesce(id,0) as id, coalesce(aayush_unique_id,0) as aayush_unique_id, coalesce(gender," ") as gender, coalesce(dob," ") as dob, coalesce(mobileno," ") as mobileno
    from patients where patients.id = ?`,
      [id]
    );
    console.log(result, "result");

    if (result?.dob) {
      const date = new Date(result.dob);

      const DOByear = date.getFullYear();
      const DOBmonth = (date.getMonth() + 1).toString().padStart(2, "0");
      const DOBday = date.getDate().toString().padStart(2, "0");

      const formattedDate = `${DOByear}-${DOBmonth}-${DOBday}`;
      console.log(formattedDate, "result.dob");

      result.dob = formattedDate;
    }
    return [
      {
        data: {
          status: "success",
          messege: "Patient Profile fetched successfully",

          profile: [
            {
              QR_Type_id: 4,
              QR_Type: "Patient_QR",
              profile_details: result,
            },
          ],
        },
      },
    ];
  }

  async Encrypted_Patientqr(id: number) {
    const [result] = await this.connection.query(
      `select coalesce(id,0) as id, coalesce(aayush_unique_id,0) as aayush_unique_id
    from patients where patients.id = ?`,
      [id]
    );
    console.log(result, "result");

    if (result?.dob) {
      const date = new Date(result.dob);

      const DOByear = date.getFullYear();
      const DOBmonth = (date.getMonth() + 1).toString().padStart(2, "0");
      const DOBday = date.getDate().toString().padStart(2, "0");

      const formattedDate = `${DOByear}-${DOBmonth}-${DOBday}`;
      console.log(formattedDate, "result.dob");

      result.dob = formattedDate;
    }
    let a = result;
    (a.QR_Type_id = 4), (a.QR_Type = "Patient_QR");

    const encrypt_apicall = await this.EncryptedService.encrypt(
      JSON.stringify(a),
      process.env.encryption_key,
      process.env.encryption_iv
    );
    return encrypt_apicall;
  }
}
