import { Injectable } from '@nestjs/common';
import { UpdateOpHubBundleGenerationDto } from './dto/update-op-hub-bundle-generation.dto';
import { InjectDataSource } from '@nestjs/typeorm';
import axios from 'axios';
import { awsConfig } from 'src/aws.config';
import { DataSource } from 'typeorm';
import { v4 as uuidv4 } from 'uuid';
import { S3, GetObjectCommand } from '@aws-sdk/client-s3';
@Injectable()
export class OpHubBundleGenerationService {
  constructor(
    private readonly dynamicConnection: DataSource,
    @InjectDataSource('AdminConnection')
    private readonly connection: DataSource,
  ) { }
  async normalizeSpaces(text: string): Promise<string> {
    return text.replace(/\s+/g, ' ').trim();
  }

  async create(
    followupDetails: any,
    other_observations: any,
    Lifestyle: any,
    women_health: any,
    generalAssment: any,
    physicalActivity: any,
    vitalDetails: any,
    body_measurement: any,
    hospital_id: any,
    opd_id: any,
    abhaAddress: string,
    file: any,
  ) {
    if (!hospital_id) {
      return {
        status: 'failed',
        messege: 'enter hospital_id to post clinical notes',
      };
    }
    const docs = await this.findAll(await file);

    const [getPatientID] = await this.dynamicConnection.query(
      `select patient_id from opd_details where id = ?`,
      [opd_id],
    );
    const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
      `select * from patient_abha_address where abhaAddress = ?`,
      [abhaAddress],
    );
    const [getPatDOB] = await this.dynamicConnection.query(
      `select * from patients where id = ?`,
      [getPatientID.patient_id],
    );

    let yob;
    if (getPatDOB.dob) {
      const [getYob] = await this.dynamicConnection.query(
        `SELECT YEAR(dob) AS year FROM patients where id = ?`,
        [getPatientID.patient_id],
      );
      yob = await getYob.year;
    }

    const [patientDetails] = await this.dynamicConnection.query(
      `select patients.id,
      emergency_mobile_no,
        coalesce(patients.patient_name,"-") patientName,
        coalesce(DATE_FORMAT(patients.dob, '%D %b %Y'),"-") dob,
        date(patients.dob) bundleDate,
        coalesce(patients.age,"-") age,
        coalesce(patients.mobileno,"-") mobileno,
        coalesce(patients.email,"-") email,
        coalesce(patients.gender,"-") gender,
        coalesce(patients.abha_address,"-") abha_address,
        coalesce(patients.address,"-") address,
        coalesce(blood_bank_products.name,"-") patient_blood_group 
      from patients 
      left join blood_bank_products 
        on patients.blood_bank_product_id = blood_bank_products.id 
      where patients.id = ?`,
      [getPatientID.patient_id],
    );
    if (patientDetails.gender.toLocaleLowerCase() == 'm' || patientDetails.gender.toLocaleLowerCase() == 'male') {
      patientDetails.gender = 'male';
    } else if (patientDetails.gender.toLocaleLowerCase() == 'f' || patientDetails.gender.toLocaleLowerCase() == 'female') {
      patientDetails.gender = 'female';
    } else {
      patientDetails.gender = 'other';
    }
    console.log(patientDetails, "patientDetails");

    const [getDocId] = await this.dynamicConnection.query(
      `select cons_doctor from visit_details where opd_details_id = ?`,
      [opd_id],
    );

    const [doctorDetails] = await this.dynamicConnection.query(
      `select concat(staff.name," ",staff.surname) doctorName,staff.employee_id,staff.gender 
      from staff where id = ?`,
      [getDocId.cons_doctor],
    );

    const bundleDate = new Date(patientDetails.bundleDate);
    const options = {
      year: 'numeric' as const,
      month: '2-digit' as const,
      day: '2-digit' as const,
      hour: '2-digit' as const,
      minute: '2-digit' as const,
      second: '2-digit' as const,
      hourCycle: 'h23' as const,
      timeZone: 'Asia/Kolkata',
    };

    const new_bundle_Date = new Intl.DateTimeFormat('en-CA', options).format(
      bundleDate,
    );
    const [date, time] = new_bundle_Date.split(', ');
    const isoDate = `${date}T${time}`;
    const finaldob = isoDate.split('T')[0];
    patientDetails.bundleDate = finaldob;

    const [getHosDetails] = await this.connection.query(
      `select * from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    const [getHosHipId] = await this.connection.query(
      `select hip_id from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    let CurrDate = new Date().toISOString();
    let CompositionID = uuidv4();
    let PractitionerID = uuidv4();
    let PatientID = uuidv4();
    let OrgtID = uuidv4();
    let EncounterID = uuidv4();
    let docRefId = uuidv4();
    let wellnessBundle: any = {
      resourceType: 'Bundle',
      id: uuidv4(),
      meta: {
        versionId: '1',
        lastUpdated: CurrDate,
        profile: [
          'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle',
        ],
        security: [
          {
            system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality',
            code: 'V',
            display: 'very restricted',
          },
        ],
      },
      identifier: {
        system: 'http://hip.in',
        value: uuidv4(),
      },
      type: 'document',
      timestamp: CurrDate,
      entry: [
        {
          fullUrl: `urn:uuid:${CompositionID}`,
          resource: {
            resourceType: 'Composition',
            id: CompositionID,
            language: 'en-IN',
            identifier: [
              {
                system: 'https://ndhm.in/phr',
                value: uuidv4(),
              },
            ],
            status: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '736373009',
                  display: 'Wellness record',
                },
              ],
              text: 'Wellness Record',
            },
            encounter: {
              reference: `urn:uuid:${EncounterID}`,
            },
            subject: [
              {
                reference: `urn:uuid:${PatientID}`,
                display: patientDetails.patientName,
              },
            ],
            date: CurrDate,
            author: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
            title: 'Wellness Record',
            custodian: {
              reference: `urn:uuid:${OrgtID}`,
              display: 'Plenome',
            },
            section: [
              {
                title: 'Document Reference',
                code: {
                  coding: [
                    {
                      system: 'http://snomed.info/sct',
                      code: '371530004',
                      display: 'Clinical consultation report',
                    },
                  ],
                },
                entry: [
                  {
                    reference: `urn:uuid:${docRefId}`,
                    display: 'DocumentReference',
                  },
                ],
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PractitionerID}`,
          resource: {
            resourceType: 'Practitioner',
            id: PractitionerID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MD',
                      display: 'Medical License number',
                    },
                  ],
                },
                system: 'https://doctor.ndhm.gov.in',
                value: doctorDetails.employee_id || '21-1521-3828-3227',
              },
            ],
            name: [
              {
                text: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PatientID}`,
          resource: {
            resourceType: 'Patient',
            id: PatientID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MR',
                      display: 'Medical record number',
                    },
                  ],
                },
                system: 'https://healthid.ndhm.gov.in',
                value: patientDetails.abha_address || uuidv4(),
              },
            ],
            name: [
              {
                text: patientDetails.patientName,
              },
            ],
            telecom: [
              {
                system: 'phone',
                value: String(patientDetails.mobileno),
                use: 'home',
              },
            ],
            gender: patientDetails.gender?.toLowerCase(),
            birthDate: patientDetails.bundleDate,
          },
        },
        {
          fullUrl: `urn:uuid:${EncounterID}`,
          resource: {
            resourceType: 'Encounter',
            id: EncounterID,
            status: 'finished',
            class: [
              {
                system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
                code: 'AMB',
                display: 'OPD Visit',
              },
            ],
            subject: {
              reference: `urn:uuid:${PatientID}`,
            },
            period: {
              start: CurrDate,
            },
          },
        },
        {
          fullUrl: `urn:uuid:${OrgtID}`,
          resource: {
            resourceType: 'Organization',
            id: OrgtID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'PRN',
                      display: 'Provider number',
                    },
                  ],
                },
                system: 'https://facility.ndhm.gov.in',
                value: String(getHosDetails.plenome_id) || '4567823',
              },
            ],
            name: getHosDetails.hospital_name,
            telecom: [
              {
                system: 'phone',
                value: getHosDetails.contact_no,
                use: 'work',
              },
              {
                system: 'email',
                value: getHosDetails.email,
                use: 'work',
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${docRefId}`,
          resource: {
            resourceType: 'DocumentReference',
            id: docRefId,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference',
              ],
            },
            status: 'current',
            docStatus: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '4241000179101',
                  display: 'consult note',
                },
              ],
              text: file.split('.')[0],
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: 'Patient',
            },
            content: [
              {
                attachment: {
                  contentType: 'application/pdf',
                  language: 'en-IN',
                  data: docs,
                  title: file.originalname,
                  creation: CurrDate,
                },
              },
            ],
          },
        },
      ],
    };

    if (followupDetails) {
      let FollowupID = uuidv4();
      wellnessBundle.entry[0].resource.section.push({
        title: 'Follow up',
        entry: [
          {
            reference: `urn:uuid:${FollowupID}`,
            display: 'Follow-up Instruction',
          },
        ],
      });

      wellnessBundle.entry.push({
        fullUrl: `urn:uuid:${FollowupID}`,
        resource: {
          resourceType: 'CarePlan',
          id: FollowupID,
          status: 'active',
          intent: 'plan',
          title: 'Follow-up Plan',
          description: `Patient needs to return on follow-up date ${followupDetails.followup_date}`,
          subject: { reference: `urn:uuid:${PatientID}` },
        },
      });
    }

    if (other_observations && other_observations.length > 0) {
      const refs = [];
      const entries = [];

      other_observations.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({
          reference: `urn:uuid:${obsId}`,
          display: obs.display || 'Other Observation',
        });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            status: 'final',
            code: { text: obs.display || 'Other Obervations' },
            valueString: obs.value || '',
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Other Observations',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (Lifestyle && Lifestyle.length > 0) {
      const refs = [];
      const entries = [];

      Lifestyle.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({ reference: `urn:uuid:${obsId}`, display: obs.display });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'lifestyle',
                    display: 'Lifestyle',
                  },
                ],
              },
            ],
            status: 'final',
            code: { text: obs.display },
            valueString: obs.value || '',
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Lifestyle',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (women_health && women_health.length > 0) {
      const refs = [];
      const entries = [];

      women_health.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({ reference: `urn:uuid:${obsId}`, display: obs.display });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            status: 'final',
            code: { text: obs.display },
            valueString: obs.value || '',
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Women Health',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (generalAssment && generalAssment.length > 0) {
      const refs = [];
      const entries = [];

      generalAssment.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({ reference: `urn:uuid:${obsId}`, display: obs.display });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'survey',
                    display: 'Survey',
                  },
                ],
              },
            ],
            status: 'final',
            code: { text: obs.display },
            valueString: obs.value + ' ' + obs.unit,
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'General Assessment',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (physicalActivity && physicalActivity.length > 0) {
      const refs = [];
      const entries = [];

      physicalActivity.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({ reference: `urn:uuid:${obsId}`, display: obs.display });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'activity',
                    display: 'Activity',
                  },
                ],
              },
            ],
            status: 'final',
            code: { text: obs.display },
            valueString: obs.value,
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Physical Activity',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (vitalDetails && vitalDetails.length > 0) {
      const refs = [];
      const entries = [];

      vitalDetails.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({ reference: `urn:uuid:${obsId}`, display: obs.display });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            status: 'final',
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'vital-signs',
                    display: 'Vital Signs',
                  },
                ],
                text: 'Vital Signs',
              },
            ],
            code: {
              text: obs.display,
            },
            subject: { reference: `urn:uuid:${PatientID}` },
            effectiveDateTime: CurrDate,
            performer: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: 'Practitioner',
              },
            ],
            valueQuantity: {
              value: Number(obs.value),
              unit: obs.unit || '',
            },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Vital Signs',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (body_measurement && body_measurement.length > 0) {
      const refs = [];
      const entries = [];

      body_measurement.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({ reference: `urn:uuid:${obsId}`, display: obs.display });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            status: 'final',
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'exam',
                    display: 'Exam',
                  },
                ],
              },
            ],
            code: {
              text: obs.display,
            },
            subject: { reference: `urn:uuid:${PatientID}` },
            effectiveDateTime: CurrDate,
            performer: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: 'Practitioner',
              },
            ],
            valueQuantity: {
              value: Number(obs.value),
              unit: obs.unit || '',
            },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Body Measurement',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    const uploadWellnessBody = {
      value: wellnessBundle,
    };

    const response1 = await axios.post(
      'https://abha-api.plenome.com/file_upload',
      uploadWellnessBody,
    );
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];

    const carecontext_reqbody = {
      abhaAddress: abhaAddress,
      patient_ref_no: await getPatDOB.aayush_unique_id,
      name: await this.normalizeSpaces(await getPatDOB.patient_name),

      gender: await getPatDOB.gender,
      year_of_birth: await yob,
      mobileno: await getPatDOB.mobileno,
      secondary_mobile: await getPatDOB.emergency_mobile_no,
      patient: [
        {
          display: 'Wellness Record Linked',
          careContexts: [
            {
              display: 'Wellness document' + formattedDate,
              doc_key: response1.data.data,
            },
          ],

          hiType: 'WellnessRecord',
          count: 1,
        },
      ],
    };

    if (
      abhaAddress &&
      abhaAddress.trim() != '' &&
      abhaAddress.toLocaleLowerCase() != 'null'
    ) {
      if (getPatientID.patient_id == checkPatientAbhaAddress.patient_id) {
        const PatientDetails = await patientDetails;

        if (
          checkPatientAbhaAddress.link_token_updated_date &&
          checkPatientAbhaAddress.linkToken
        ) {
          const givenDate = new Date(
            checkPatientAbhaAddress.link_token_updated_date,
          );
          const currentDate = new Date();

          currentDate.setHours(0, 0, 0, 0);
          givenDate.setHours(0, 0, 0, 0);

          const monthDifference =
            (currentDate.getFullYear() - givenDate.getFullYear()) * 12 +
            currentDate.getMonth() -
            givenDate.getMonth();

          if (monthDifference > 5) {
            const getPatnameBody = {
              abhaAddress: abhaAddress,
            };

            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };
            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };

            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }
        } else {
          const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
            `select * from patient_abha_address where abhaAddress = ?`,
            [abhaAddress],
          );
          if (!checkPatientAbhaAddress.linkToken && !checkPatientAbhaAddress.link_token_updated_date) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const [getHosHipId] = await this.connection.query(
              `select hip_id from hospitals where plenome_id = ?`,
              [hospital_id],
            );

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };

            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };
            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }


        }
        const existing_link_token: any = await this.getexistingLinkToken(
          hospital_id,
          abhaAddress,
        );

        if (existing_link_token.linkToken) {
          const cc_headers = {
            'X-LINK-TOKEN': await existing_link_token.linkToken,
            'X-HIP-ID': await getHosHipId.hip_id,
            'Content-Type': 'application/json',
          };
          await axios.post(
            'https://abha-api.plenome.com/link/carecontext',
            carecontext_reqbody,
            { headers: cc_headers },
          );
        }
      }
    } else {
      const cc_headers = {
        'X-LINK-TOKEN': 'Temp_linktoken',
        'X-HIP-ID': await getHosHipId.hip_id,
        'Content-Type': 'application/json',
      };
      try {
        await axios.post(
          'https://abha-api.plenome.com/link/carecontext',
          carecontext_reqbody,
          { headers: cc_headers },
        );
        await this.send_sms(
          patientDetails.emergency_mobile_no?.trim() || patientDetails.mobileno,
          getHosHipId.hip_id,
          getHosHipId.hip_name,
        );
      } catch (error) {
        console.log(error, 'error1111');
      }
    }
    return wellnessBundle;
  }

  async createDischargeSummary(
    followupDetails: any,
    clinicalPresentation: any[],
    investigationsPerformed: any[],
    treatment_given: any[],
    condition_at_discharge: any[],
    discharge_advice: any[],
    hospital_id: any,
    opd_id: any,
    abhaAddress: string,
  ) {
    if (!hospital_id) {
      return {
        status: 'failed',
        message: 'enter hospital_id to post clinical notes',
      };
    }

    const [getPatientID] = await this.dynamicConnection.query(
      `select patient_id from opd_details where id = ?`,
      [opd_id],
    );

    const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
      `select * from patient_abha_address where abhaAddress = ?`,
      [abhaAddress],
    );

    const [getPatDOB] = await this.dynamicConnection.query(
      `select * from patients where id = ?`,
      [getPatientID.patient_id],
    );

    let yob;
    if (getPatDOB.dob) {
      const [getYob] = await this.dynamicConnection.query(
        `SELECT YEAR(dob) AS year FROM patients where id = ?`,
        [getPatientID.patient_id],
      );
      yob = getYob.year;
    }

    const [patientDetails] = await this.dynamicConnection.query(
      `select patients.id,
      emergency_mobile_no,
      coalesce(patients.patient_name,"-") patientName,
      coalesce(DATE_FORMAT(patients.dob, '%D %b %Y'),"-") dob,
      date(patients.dob) bundleDate,
      coalesce(patients.age,"-") age,
      coalesce(patients.mobileno,"-") mobileno,
      coalesce(patients.email,"-") email,
      coalesce(patients.gender,"-") gender,
      coalesce(patients.abha_address,"-") abha_address,
      coalesce(patients.address,"-") address,
      coalesce(blood_bank_products.name,"-") patient_blood_group 
    from patients 
    left join blood_bank_products 
      on patients.blood_bank_product_id = blood_bank_products.id 
    where patients.id = ?`,
      [getPatientID.patient_id],
    );

    const [getDocId] = await this.dynamicConnection.query(
      `select cons_doctor from visit_details where opd_details_id = ?`,
      [opd_id],
    );

    const [doctorDetails] = await this.dynamicConnection.query(
      `select concat(staff.name," ",staff.surname) doctorName,staff.employee_id,staff.gender 
    from staff where id = ?`,
      [getDocId.cons_doctor],
    );

    const bundleDate = new Date(patientDetails.bundleDate);
    const options = {
      year: 'numeric' as const,
      month: '2-digit' as const,
      day: '2-digit' as const,
      hour: '2-digit' as const,
      minute: '2-digit' as const,
      second: '2-digit' as const,
      hourCycle: 'h23' as const,
      timeZone: 'Asia/Kolkata',
    };

    const new_bundle_Date = new Intl.DateTimeFormat('en-CA', options).format(
      bundleDate,
    );
    const [date, time] = new_bundle_Date.split(', ');
    const isoDate = `${date}T${time}`;
    const finaldob = isoDate.split('T')[0];
    patientDetails.bundleDate = finaldob;

    const [getHosDetails] = await this.connection.query(
      `select * from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    const [getHosHipId] = await this.connection.query(
      `select hip_id from hospitals where plenome_id = ?`,
      [hospital_id],
    );

    let CurrDate = new Date().toISOString();
    let CompositionID = uuidv4();
    let PractitionerID = uuidv4();
    let PatientID = uuidv4();
    let OrgtID = uuidv4();
    let EncounterID = uuidv4();

    let wellnessBundle: any = {
      resourceType: 'Bundle',
      id: uuidv4(),
      meta: {
        versionId: '1',
        lastUpdated: CurrDate,
        profile: [
          'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle',
        ],
        security: [
          {
            system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality',
            code: 'V',
            display: 'very restricted',
          },
        ],
      },
      identifier: {
        system: 'http://hip.in',
        value: uuidv4(),
      },
      type: 'document',
      timestamp: CurrDate,
      entry: [
        {
          fullUrl: `urn:uuid:${CompositionID}`,
          resource: {
            resourceType: 'Composition',
            id: CompositionID,
            language: 'en-IN',
            identifier: [
              {
                system: 'https://ndhm.in/phr',
                value: uuidv4(),
              },
            ],
            status: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '736373009',
                  display: 'Discharge Summary Record',
                },
              ],
              text: 'Discharge Summary Record',
            },
            encounter: {
              reference: `urn:uuid:${EncounterID}`,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            date: CurrDate,
            author: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
            title: 'Discharge Summary',
            custodian: {
              reference: `urn:uuid:${OrgtID}`,
              display: getHosDetails.hospital_name,
            },
            section: [],
          },
        },
        {
          fullUrl: `urn:uuid:${PractitionerID}`,
          resource: {
            resourceType: 'Practitioner',
            id: PractitionerID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MD',
                      display: 'Medical License number',
                    },
                  ],
                },
                system: 'https://doctor.ndhm.gov.in',
                value: doctorDetails.employee_id || '21-1521-3828-3227',
              },
            ],
            name: [
              {
                text: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PatientID}`,
          resource: {
            resourceType: 'Patient',
            id: PatientID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MR',
                      display: 'Medical record number',
                    },
                  ],
                },
                system: 'https://healthid.ndhm.gov.in',
                value: patientDetails.abha_address || uuidv4(),
              },
            ],
            name: [
              {
                text: patientDetails.patientName,
              },
            ],
            telecom: [
              {
                system: 'phone',
                value: String(patientDetails.mobileno),
                use: 'home',
              },
            ],
            gender: patientDetails.gender?.toLowerCase(),
            birthDate: patientDetails.bundleDate,
          },
        },
        {
          fullUrl: `urn:uuid:${EncounterID}`,
          resource: {
            resourceType: 'Encounter',
            id: EncounterID,
            status: 'finished',
            class: {
              system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
              code: 'AMB',
              display: 'OPD Visit',
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
            },
            period: {
              start: CurrDate,
            },
          },
        },
        {
          fullUrl: `urn:uuid:${OrgtID}`,
          resource: {
            resourceType: 'Organization',
            id: OrgtID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'PRN',
                      display: 'Provider number',
                    },
                  ],
                },
                system: 'https://facility.ndhm.gov.in',
                value: String(getHosDetails.plenome_id) || '4567823',
              },
            ],
            name: getHosDetails.hospital_name,
            telecom: [
              {
                system: 'phone',
                value: getHosDetails.contact_no,
                use: 'work',
              },
              {
                system: 'email',
                value: getHosDetails.email,
                use: 'work',
              },
            ],
          },
        },
      ],
    };

    if (followupDetails) {
      let FollowupID = uuidv4();
      wellnessBundle.entry[0].resource.section.push({
        title: 'Follow up',
        entry: [
          {
            reference: `urn:uuid:${FollowupID}`,
            display: 'Follow-up Instruction',
          },
        ],
      });

      wellnessBundle.entry.push({
        fullUrl: `urn:uuid:${FollowupID}`,
        resource: {
          resourceType: 'CarePlan',
          id: FollowupID,
          status: 'active',
          intent: 'plan',
          title: 'Follow-up Plan',
          description: `Patient needs to return on follow-up date ${followupDetails.followup_date}`,
          subject: { reference: `urn:uuid:${PatientID}` },
        },
      });
    }

    if (clinicalPresentation?.length > 0) {
      const refs = [];
      const entries = [];

      clinicalPresentation.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({
          reference: `urn:uuid:${obsId}`,
          display: obs.display || 'Observation',
        });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            status: 'final',
            code: { text: obs.display || 'note' },
            valueString: obs.value || '',
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Clinical Presentation',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (investigationsPerformed?.length > 0) {
      const refs = [];
      const entries = [];

      investigationsPerformed.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({
          reference: `urn:uuid:${obsId}`,
          display: obs.display || 'Observation',
        });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'exam',
                    display: 'Exam',
                  },
                ],
              },
            ],
            status: 'final',
            code: { text: obs.display || 'note' },
            valueString: obs.value || '',
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Investigations Performed',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (treatment_given?.length > 0) {
      const refs = [];
      const entries = [];

      treatment_given.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({
          reference: `urn:uuid:${obsId}`,
          display: obs.display || 'Observation',
        });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            status: 'final',
            code: { text: obs.display || 'note' },
            valueString: obs.value || '',
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Treatment Given',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (condition_at_discharge?.length > 0) {
      const refs = [];
      const entries = [];

      condition_at_discharge.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({
          reference: `urn:uuid:${obsId}`,
          display: obs.display || 'Observation',
        });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'survey',
                    display: 'Survey',
                  },
                ],
              },
            ],
            status: 'final',
            code: { text: obs.display || 'note' },
            valueString: obs.value,
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Condition at Discharge',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    if (discharge_advice?.length > 0) {
      const refs = [];
      const entries = [];

      discharge_advice.forEach((obs) => {
        const obsId = uuidv4();
        refs.push({
          reference: `urn:uuid:${obsId}`,
          display: obs.display || 'Observation',
        });

        entries.push({
          fullUrl: `urn:uuid:${obsId}`,
          resource: {
            resourceType: 'Observation',
            id: obsId,
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'activity',
                    display: 'Activity',
                  },
                ],
              },
            ],
            status: 'final',
            code: { text: obs.display || 'note' },
            valueString: obs.value,
            subject: { reference: `urn:uuid:${PatientID}` },
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Discharge Advice',
        entry: refs,
      });
      wellnessBundle.entry.push(...entries);
    }

    const uploadWellnessBody = {
      value: wellnessBundle,
    };

    const response1 = await axios.post(
      'https://abha-api.plenome.com/file_upload',
      uploadWellnessBody,
    );
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];

    const carecontext_reqbody = {
      abhaAddress: abhaAddress,
      patient_ref_no: await getPatDOB.aayush_unique_id,
      name: await this.normalizeSpaces(await getPatDOB.patient_name),
      gender: await getPatDOB.gender,
      year_of_birth: await yob,
      mobileno: await getPatDOB.mobileno,
      secondary_mobile: await getPatDOB.emergency_mobile_no,
      patient: [
        {
          display: 'Discharge Summary Record Linked',
          careContexts: [
            {
              display: 'Discharge Summary Record' + formattedDate,
              doc_key: response1.data.data,
            },
          ],

          hiType: 'DischargeSummary',
          count: 1,
        },
      ],
    };
    if (
      abhaAddress &&
      abhaAddress.trim() != '' &&
      abhaAddress.toLocaleLowerCase() != 'null'
    ) {
      if (getPatientID.patient_id == checkPatientAbhaAddress.patient_id) {
        const PatientDetails = await patientDetails;

        if (
          checkPatientAbhaAddress.link_token_updated_date &&
          checkPatientAbhaAddress.linkToken
        ) {
          const givenDate = new Date(
            checkPatientAbhaAddress.link_token_updated_date,
          );
          const currentDate = new Date();

          currentDate.setHours(0, 0, 0, 0);
          givenDate.setHours(0, 0, 0, 0);

          const monthDifference =
            (currentDate.getFullYear() - givenDate.getFullYear()) * 12 +
            currentDate.getMonth() -
            givenDate.getMonth();

          if (monthDifference > 5) {
            const getPatnameBody = {
              abhaAddress: abhaAddress,
            };

            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };
            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };

            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }
        } else {
          const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
            `select * from patient_abha_address where abhaAddress = ?`,
            [abhaAddress],
          );
          if (!checkPatientAbhaAddress.linkToken && !checkPatientAbhaAddress.link_token_updated_date) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const [getHosHipId] = await this.connection.query(
              `select hip_id from hospitals where plenome_id = ?`,
              [hospital_id],
            );

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };

            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };
            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }


        }
        const existing_link_token: any = await this.getexistingLinkToken(
          hospital_id,
          abhaAddress,
        );

        if (existing_link_token.linkToken) {
          const cc_headers = {
            'X-LINK-TOKEN': await existing_link_token.linkToken,
            'X-HIP-ID': await getHosHipId.hip_id,
            'Content-Type': 'application/json',
          };
          await axios.post(
            'https://abha-api.plenome.com/link/carecontext',
            carecontext_reqbody,
            { headers: cc_headers },
          );
        }
      }
    } else {
      const cc_headers = {
        'X-LINK-TOKEN': 'Temp_linktoken',
        'X-HIP-ID': await getHosHipId.hip_id,
        'Content-Type': 'application/json',
      };
      try {
        await axios.post(
          'https://abha-api.plenome.com/link/carecontext',
          carecontext_reqbody,
          { headers: cc_headers },
        );
        await this.send_sms(
          patientDetails.emergency_mobile_no?.trim() || patientDetails.mobileno,
          getHosHipId.hip_id,
          getHosHipId.hip_name,
        );
      } catch (error) {
        console.log(error, 'error1111');
      }

    }
    return wellnessBundle;
  }

  async createPrescription(
    prescriptionDetails: any[],
    hospital_id: any,
    opd_id: any,
    abhaAddress: string,
    file: any,
  ) {
    const isBlank = (v: any) => {
      if (v === null || v === undefined) return true;
      if (typeof v === 'string') {
        const t = v.trim().toLowerCase();
        return (
          t === '' || t === 'na' || t === 'n/a' || t === 'null' || t === '-'
        );
      }
      return false;
    };
    const clean = <T = any>(v: T | undefined | null): T | undefined =>
      isBlank(v) ? undefined : (v as T);
    const cleanText = (v: any, fallback?: string) =>
      isBlank(v) ? fallback ?? undefined : String(v).trim();
    const cleanNumber = (v: any): number | undefined => {
      if (v === null || v === undefined) return undefined;
      const n = Number(v);
      return Number.isFinite(n) ? n : undefined;
    };
    const cleanGender = (g: any): 'male' | 'female' | 'other' | undefined => {
      const t = (g ?? '').toString().trim().toLowerCase();
      if (t === 'male' || t === 'm') return 'male';
      if (t === 'female' || t === 'f') return 'female';
      if (t === 'other' || t === 'o') return 'other';
      return undefined;
    };

    if (!hospital_id) {
      return {
        status: 'failed',
        message: 'enter hospital_id to post clinical notes',
      };
    }
    const docs = await this.findAll(await file);

    const [getPatientID] = await this.dynamicConnection.query(
      `select patient_id from opd_details where id = ?`,
      [opd_id],
    );

    const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
      `select * from patient_abha_address where abhaAddress = ?`,
      [abhaAddress],
    );

    const [getPatDOB] = await this.dynamicConnection.query(
      `select * from patients where id = ?`,
      [getPatientID.patient_id],
    );

    let yob;
    if (getPatDOB.dob) {
      const [getYob] = await this.dynamicConnection.query(
        `SELECT YEAR(dob) AS year FROM patients where id = ?`,
        [getPatientID.patient_id],
      );
      yob = getYob.year;
    }

    const [patientDetails] = await this.dynamicConnection.query(
      `select patients.id,
      emergency_mobile_no,
      coalesce(patients.patient_name,"-") patientName,
      coalesce(DATE_FORMAT(patients.dob, '%D %b %Y'),"-") dob,
      date(patients.dob) bundleDate,
      coalesce(patients.age,"-") age,
      coalesce(patients.mobileno,"-") mobileno,
      coalesce(patients.email,"-") email,
      coalesce(patients.gender,"-") gender,
      coalesce(patients.abha_address,"-") abha_address,
      coalesce(patients.address,"-") address,
      coalesce(blood_bank_products.name,"-") patient_blood_group 
    from patients 
    left join blood_bank_products 
      on patients.blood_bank_product_id = blood_bank_products.id 
    where patients.id = ?`,
      [getPatientID.patient_id],
    );
    if (patientDetails.gender.toLocaleLowerCase() == 'm' || patientDetails.gender.toLocaleLowerCase() == 'male') {
      patientDetails.gender = 'male';
    } else if (patientDetails.gender.toLocaleLowerCase() == 'f' || patientDetails.gender.toLocaleLowerCase() == 'female') {
      patientDetails.gender = 'female';
    } else {
      patientDetails.gender = 'other';
    }
    const [getDocId] = await this.dynamicConnection.query(
      `select cons_doctor from visit_details where opd_details_id = ?`,
      [opd_id],
    );

    const [doctorDetails] = await this.dynamicConnection.query(
      `select concat(staff.name," ",staff.surname) doctorName,staff.employee_id,staff.gender 
    from staff where id = ?`,
      [getDocId.cons_doctor],
    );

    const bundleDate = new Date(patientDetails.bundleDate);
    const options = {
      year: 'numeric' as const,
      month: '2-digit' as const,
      day: '2-digit' as const,
      hour: '2-digit' as const,
      minute: '2-digit' as const,
      second: '2-digit' as const,
      hourCycle: 'h23' as const,
      timeZone: 'Asia/Kolkata',
    };

    const new_bundle_Date = new Intl.DateTimeFormat('en-CA', options).format(
      bundleDate,
    );
    const [date, time] = new_bundle_Date.split(', ');
    const isoDate = `${date}T${time}`;
    const finaldob = isoDate.split('T')[0];
    patientDetails.bundleDate = finaldob;

    const [getHosDetails] = await this.connection.query(
      `select * from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    const [getHosHipId] = await this.connection.query(
      `select hip_id from hospitals where plenome_id = ?`,
      [hospital_id],
    );

    let CurrDate = new Date().toISOString();
    let CompositionID = uuidv4();
    let PractitionerID = uuidv4();
    let PatientID = uuidv4();
    let OrgtID = uuidv4();
    let EncounterID = uuidv4();
    let docRefId = uuidv4();

    const docTypeText =
      typeof file === 'string'
        ? cleanText(file.split('.').slice(0, -1).join('.')) ?? 'Document'
        : cleanText(file?.originalname?.split('.').slice(0, -1).join('.')) ??
        'Document';

    const patientNameClean = cleanText(patientDetails.patientName);
    const doctorNameClean = cleanText(doctorDetails?.doctorName);
    const hospNameClean = cleanText(getHosDetails?.hospital_name);

    let wellnessBundle: any = {
      resourceType: 'Bundle',
      id: uuidv4(),
      meta: {
        versionId: '1',
        lastUpdated: CurrDate,
        profile: [
          'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle',
        ],
        security: [
          {
            system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality',
            code: 'V',
            display: 'very restricted',
          },
        ],
      },
      identifier: {
        system: 'http://hip.in',
        value: uuidv4(),
      },
      type: 'document',
      timestamp: CurrDate,
      entry: [
        {
          fullUrl: `urn:uuid:${CompositionID}`,
          resource: {
            resourceType: 'Composition',
            id: CompositionID,
            language: 'en-IN',
            identifier: [
              {
                system: 'https://ndhm.in/phr',
                value: uuidv4(),
              },
            ],
            status: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '736373009',
                  display: 'Prescription Record',
                },
              ],
              text: 'Prescription Record',
            },
            encounter: {
              reference: `urn:uuid:${EncounterID}`,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientNameClean,
            },
            date: CurrDate,
            author: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: doctorNameClean ? `Dr. ${doctorNameClean}` : undefined,
              },
            ],
            title: 'Prescription',
            custodian: {
              reference: `urn:uuid:${OrgtID}`,
              display: hospNameClean,
            },
            section: [
              {
                title: 'Document Reference',
                code: {
                  coding: [
                    {
                      system: 'http://snomed.info/sct',
                      code: '371530004',
                      display: 'Clinical consultation report',
                    },
                  ],
                },
                entry: [
                  {
                    reference: `urn:uuid:${docRefId}`,
                    display: 'DocumentReference',
                  },
                ],
              },
            ],
          },
        },

        {
          fullUrl: `urn:uuid:${PractitionerID}`,
          resource: {
            resourceType: 'Practitioner',
            id: PractitionerID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MD',
                      display: 'Medical License number',
                    },
                  ],
                },
                system: 'https://doctor.ndhm.gov.in',
                value:
                  cleanText(doctorDetails?.employee_id) || '21-1521-3828-3227',
              },
            ],
            name: [
              {
                text: doctorNameClean ? `Dr. ${doctorNameClean}` : undefined,
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PatientID}`,
          resource: {
            resourceType: 'Patient',
            id: PatientID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MR',
                      display: 'Medical record number',
                    },
                  ],
                },
                system: 'https://healthid.ndhm.gov.in',
                value: cleanText(patientDetails?.abha_address) || uuidv4(),
              },
            ],
            name: [
              {
                text: patientNameClean,
              },
            ],
            telecom: [
              {
                system: 'phone',
                value: cleanText(patientDetails?.mobileno),
                use: 'home',
              },
            ],
            gender: cleanGender(patientDetails?.gender),
            birthDate: cleanText(patientDetails?.bundleDate),
          },
        },
        {
          fullUrl: `urn:uuid:${EncounterID}`,
          resource: {
            resourceType: 'Encounter',
            id: EncounterID,
            status: 'finished',
            class: {
              system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
              code: 'AMB',
              display: 'OPD Visit',
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
            },
            period: {
              start: CurrDate,
            },
          },
        },
        {
          fullUrl: `urn:uuid:${OrgtID}`,
          resource: {
            resourceType: 'Organization',
            id: OrgtID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'PRN',
                      display: 'Provider number',
                    },
                  ],
                },
                system: 'https://facility.ndhm.gov.in',
                value: cleanText(getHosDetails?.plenome_id) || '4567823',
              },
            ],
            name: hospNameClean,
            telecom: [
              {
                system: 'phone',
                value: cleanText(getHosDetails?.contact_no),
                use: 'work',
              },
              {
                system: 'email',
                value: cleanText(getHosDetails?.email),
                use: 'work',
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${docRefId}`,
          resource: {
            resourceType: 'DocumentReference',
            id: docRefId,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference',
              ],
            },
            status: 'current',
            docStatus: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '4241000179101',
                  display: 'consult note',
                },
              ],
              text: file.split('.')[0],
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: 'Patient',
            },
            content: [
              {
                attachment: {
                  contentType: 'application/pdf',
                  language: 'en-IN',
                  title: file.originalname || 'Prescription.pdf',
                  creation: CurrDate,
                  url: `urn:uuid:${docRefId}-binary`,
                },
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${docRefId}-binary`,
          resource: {
            resourceType: 'Binary',
            id: `${docRefId}-binary`,
            contentType: 'application/pdf',
            data: docs,
          },
        },
      ],
    };

    if (prescriptionDetails && prescriptionDetails?.length > 0) {
      const refs: any[] = [];
      const entries: any[] = [];

      prescriptionDetails.forEach((med) => {
        const medId = uuidv4();
        refs.push({ reference: `urn:uuid:${medId}` });

        const medName = cleanText(med.medicineName);
        const medRemarks = cleanText(med.remarks);
        const medInstruction = cleanText(med.instruction, medRemarks);
        const medTiming = cleanText(med.timing);
        const medRoute = cleanText(med.route);
        const medMethod = cleanText(med.method);

        const freq = cleanNumber(med.frequency);
        const duration = cleanNumber(med.duration);
        const durationUnit = cleanText(med.duration_unit);
        const doseValue = cleanNumber(med.dosage);
        const doseUnit = cleanText(med.unit);
        const qtyValue = cleanNumber(med.quantity);
        const qtyUnit = cleanText(med.medicine_type);

        entries.push({
          fullUrl: `urn:uuid:${medId}`,
          resource: {
            resourceType: 'MedicationRequest',
            id: medId,
            status: 'active',
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/MedicationRequest',
              ],
            },
            intent: 'order',

            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/medicationrequest-category',
                    code: 'outpatient',
                    display: 'Outpatient',
                  },
                ],
              },
            ],

            reasonCode: cleanText(med.indication)
              ? [{ text: cleanText(med.indication) }]
              : undefined,

            courseOfTherapyType: cleanNumber(med.duration)
              ? {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy',
                    code: 'acute',
                    display: 'Short course (acute)',
                  },
                ],
              }
              : undefined,

            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientNameClean,
            },
            authoredOn: CurrDate,
            requester: {
              reference: `urn:uuid:${PractitionerID}`,
              display: doctorNameClean,
            },
            medicationCodeableConcept: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '1145423002',
                  display: medName,
                },
              ],
              text: medName,
            },

            dosageInstruction: [
              {
                text: medRemarks ?? medInstruction,
                patientInstruction: medInstruction,
                route: medRoute ? { text: medRoute } : undefined,
                method: medMethod ? { text: medMethod } : undefined,
                timing: {
                  repeat: {
                    frequency: freq,
                    period: duration,
                    periodUnit: durationUnit as any,
                    duration: duration,
                    durationUnit: durationUnit as any,
                  },
                  code: { text: medTiming },
                },
                doseAndRate: [
                  {
                    doseQuantity: {
                      value: doseValue,
                      unit: doseUnit,
                    },
                  },
                ],
              },
            ],

            dispenseRequest: {
              quantity: {
                value: qtyValue,
                unit: qtyUnit,
              },
            },

            note: cleanText(med.note)
              ? [{ text: cleanText(med.note) }]
              : undefined,
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Medications',
        code: {
          coding: [
            {
              system: 'http://loinc.org',
              code: '10160-0',
              display: 'History of Medication use',
            },
          ],
        },
        entry: refs,
      });

      wellnessBundle.entry.push(...entries);
    }

    const uploadWellnessBody = {
      value: wellnessBundle,
    };

    const response1 = await axios.post(
      'https://abha-api.plenome.com/file_upload',
      uploadWellnessBody,
    );
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];

    const carecontext_reqbody = {
      abhaAddress: abhaAddress,
      patient_ref_no: await getPatDOB.aayush_unique_id,
      name: await this.normalizeSpaces(await getPatDOB.patient_name),
      gender: await getPatDOB.gender,
      year_of_birth: await yob,
      mobileno: await getPatDOB.mobileno,
      secondary_mobile: await getPatDOB.emergency_mobile_no,
      patient: [
        {
          display: 'Prescription Record Linked',
          careContexts: [
            {
              display: 'Prescription Record' + formattedDate,
              doc_key: response1.data.data,
            },
          ],

          hiType: 'Prescription',
          count: 1,
        },
      ],
    };
    if (
      abhaAddress &&
      abhaAddress.trim() != '' &&
      abhaAddress.toLocaleLowerCase() != 'null'
    ) {
      if (getPatientID.patient_id == checkPatientAbhaAddress.patient_id) {
        const PatientDetails = await patientDetails;

        if (
          checkPatientAbhaAddress.link_token_updated_date &&
          checkPatientAbhaAddress.linkToken
        ) {
          const givenDate = new Date(
            checkPatientAbhaAddress.link_token_updated_date,
          );
          const currentDate = new Date();

          currentDate.setHours(0, 0, 0, 0);
          givenDate.setHours(0, 0, 0, 0);

          const monthDifference =
            (currentDate.getFullYear() - givenDate.getFullYear()) * 12 +
            currentDate.getMonth() -
            givenDate.getMonth();

          if (monthDifference > 5) {
            const getPatnameBody = {
              abhaAddress: abhaAddress,
            };

            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };
            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };

            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }
        } else {
          const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
            `select * from patient_abha_address where abhaAddress = ?`,
            [abhaAddress],
          );
          if (!checkPatientAbhaAddress.linkToken && !checkPatientAbhaAddress.link_token_updated_date) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const [getHosHipId] = await this.connection.query(
              `select hip_id from hospitals where plenome_id = ?`,
              [hospital_id],
            );

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };

            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };
            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }


        }
        const existing_link_token: any = await this.getexistingLinkToken(
          hospital_id,
          abhaAddress,
        );

        if (existing_link_token.linkToken) {
          const cc_headers = {
            'X-LINK-TOKEN': await existing_link_token.linkToken,
            'X-HIP-ID': await getHosHipId.hip_id,
            'Content-Type': 'application/json',
          };
          await axios.post(
            'https://abha-api.plenome.com/link/carecontext',
            carecontext_reqbody,
            { headers: cc_headers },
          );
        }
      }
    } else {
      const cc_headers = {
        'X-LINK-TOKEN': 'Temp_linktoken',
        'X-HIP-ID': await getHosHipId.hip_id,
        'Content-Type': 'application/json',
      };
      try {
        await axios.post(
          'https://abha-api.plenome.com/link/carecontext',
          carecontext_reqbody,
          { headers: cc_headers },
        );
        await this.send_sms(
          patientDetails.emergency_mobile_no?.trim() || patientDetails.mobileno,
          getHosHipId.hip_id,
          getHosHipId.hip_name,
        );
      } catch (error) {
        console.log(error, 'error1111');
      }

    }
    return wellnessBundle;
  }

  async createImmunization(
    immunizationDetails: any[],
    hospital_id: any,
    opd_id: any,
    abhaAddress: string,
    file: any,
  ) {
    if (!hospital_id) {
      return {
        status: 'failed',
        message: 'enter hospital_id to post clinical notes',
      };
    }
    const docs = await this.findAll(await file);
    let [a] = await this.connection.query(`select date(now()) date`)

    const [voice_data] = await this.connection.query(
      `SELECT * FROM opd_voice_data where opd_details_id = ? and hospital_id = ?`,
      [opd_id, hospital_id],
    );
    let check = voice_data?.data?.medical_report?.immunisation?.vaccine
    const formatDateOfImmunisation = (dateStr: string): string => {
      try {

        if (!dateStr) return '';
        console.log(dateStr);

        const [datePart, timePart, meridian] = dateStr.split(' ');
        console.log(datePart, timePart, meridian, "datePart, timePart, meridian");

        const [day, month, year] = datePart.split('/').map(Number);
        let [hours, minutes] = timePart.split(':').map(Number);

        if (meridian === 'PM' && hours < 12) hours += 12;
        if (meridian === 'AM' && hours === 12) hours = 0;

        return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(
          2,
          '0',
        )} ${String(hours).padStart(2, '0')}:${String(minutes).padStart(
          2,
          '0',
        )}:00`;
      } catch (error) {
        return a.date
      }
    };

    immunizationDetails = immunizationDetails.map((item, index) => ({
      ...item,
      dateOfImmunization:
        item.dateOfImmunization === '' && check?.[index]?.dateofimmunisation
          ? formatDateOfImmunisation(check[index].dateofimmunisation)
          : item.dateOfImmunization,
    }));

    console.log(immunizationDetails, "immunizationDetailsUpdated");

    const [getPatientID] = await this.dynamicConnection.query(
      `select patient_id from opd_details where id = ?`,
      [opd_id],
    );

    const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
      `select * from patient_abha_address where abhaAddress = ?`,
      [abhaAddress],
    );

    const [getPatDOB] = await this.dynamicConnection.query(
      `select * from patients where id = ?`,
      [getPatientID.patient_id],
    );

    let yob;
    if (getPatDOB.dob) {
      const [getYob] = await this.dynamicConnection.query(
        `SELECT YEAR(dob) AS year FROM patients where id = ?`,
        [getPatientID.patient_id],
      );
      yob = getYob.year;
    }

    const [patientDetails] = await this.dynamicConnection.query(
      `select patients.id,
      emergency_mobile_no,
      coalesce(patients.patient_name,"-") patientName,
      coalesce(DATE_FORMAT(patients.dob, '%D %b %Y'),"-") dob,
      date(patients.dob) bundleDate,
      coalesce(patients.age,"-") age,
      coalesce(patients.mobileno,"-") mobileno,
      coalesce(patients.email,"-") email,
      coalesce(patients.gender,"-") gender,
      coalesce(patients.abha_address,"-") abha_address,
      coalesce(patients.address,"-") address,
      coalesce(blood_bank_products.name,"-") patient_blood_group 
    from patients 
    left join blood_bank_products 
      on patients.blood_bank_product_id = blood_bank_products.id 
    where patients.id = ?`,
      [getPatientID.patient_id],
    );
    if (patientDetails.gender.toLocaleLowerCase() == 'm' || patientDetails.gender.toLocaleLowerCase() == 'male') {
      patientDetails.gender = 'male';
    } else if (patientDetails.gender.toLocaleLowerCase() == 'f' || patientDetails.gender.toLocaleLowerCase() == 'female') {
      patientDetails.gender = 'female';
    } else {
      patientDetails.gender = 'other';
    }
    const [getDocId] = await this.dynamicConnection.query(
      `select cons_doctor from visit_details where opd_details_id = ?`,
      [opd_id],
    );

    const [doctorDetails] = await this.dynamicConnection.query(
      `select concat(staff.name," ",staff.surname) doctorName,staff.employee_id,staff.gender 
    from staff where id = ?`,
      [getDocId.cons_doctor],
    );

    const bundleDate = new Date(patientDetails.bundleDate);
    const options = {
      year: 'numeric' as const,
      month: '2-digit' as const,
      day: '2-digit' as const,
      hour: '2-digit' as const,
      minute: '2-digit' as const,
      second: '2-digit' as const,
      hourCycle: 'h23' as const,
      timeZone: 'Asia/Kolkata',
    };

    const new_bundle_Date = new Intl.DateTimeFormat('en-CA', options).format(
      bundleDate,
    );
    const [date, time] = new_bundle_Date.split(', ');
    const isoDate = `${date}T${time}`;
    const finaldob = isoDate.split('T')[0];
    patientDetails.bundleDate = finaldob;

    const [getHosDetails] = await this.connection.query(
      `select * from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    const [getHosHipId] = await this.connection.query(
      `select hip_id from hospitals where plenome_id = ?`,
      [hospital_id],
    );

    let CurrDate = new Date().toISOString();
    let CompositionID = uuidv4();
    let PractitionerID = uuidv4();
    let PatientID = uuidv4();
    let OrgtID = uuidv4();
    let EncounterID = uuidv4();
    let docRefId = uuidv4();
    let wellnessBundle: any = {
      resourceType: 'Bundle',
      id: uuidv4(),
      meta: {
        versionId: '1',
        lastUpdated: CurrDate,
        profile: [
          'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle',
        ],
        security: [
          {
            system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality',
            code: 'V',
            display: 'very restricted',
          },
        ],
      },
      identifier: {
        system: 'http://hip.in',
        value: uuidv4(),
      },
      type: 'document',
      timestamp: CurrDate,
      entry: [
        {
          fullUrl: `urn:uuid:${CompositionID}`,
          resource: {
            resourceType: 'Composition',
            id: CompositionID,
            language: 'en-IN',
            identifier: [
              {
                system: 'https://ndhm.in/phr',
                value: uuidv4(),
              },
            ],
            status: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '736373009',
                  display: 'ImmunizationRecord',
                },
              ],
              text: 'ImmunizationRecord',
            },
            encounter: {
              reference: `urn:uuid:${EncounterID}`,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            date: CurrDate,
            author: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
            title: 'ImmunizationRecord',
            custodian: {
              reference: `urn:uuid:${OrgtID}`,
              display: getHosDetails.hospital_name,
            },
            section: [
              {
                title: 'Document Reference',
                code: {
                  coding: [
                    {
                      system: 'http://snomed.info/sct',
                      code: '371530004',
                      display: 'Clinical consultation report',
                    },
                  ],
                },
                entry: [
                  {
                    reference: `urn:uuid:${docRefId}`,
                    display: 'DocumentReference',
                  },
                ],
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PractitionerID}`,
          resource: {
            resourceType: 'Practitioner',
            id: PractitionerID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MD',
                      display: 'Medical License number',
                    },
                  ],
                },
                system: 'https://doctor.ndhm.gov.in',
                value: doctorDetails.employee_id || '21-1521-3828-3227',
              },
            ],
            name: [
              {
                text: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${docRefId}`,
          resource: {
            resourceType: 'DocumentReference',
            id: docRefId,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference',
              ],
            },
            status: 'current',
            docStatus: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '4241000179101',
                  display: 'consult note',
                },
              ],
              text: file.split('.')[0],
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: 'Patient',
            },
            content: [
              {
                attachment: {
                  contentType: 'application/pdf',
                  language: 'en-IN',
                  data: docs,
                  title: file.originalname,
                  creation: CurrDate,
                },
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PatientID}`,
          resource: {
            resourceType: 'Patient',
            id: PatientID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MR',
                      display: 'Medical record number',
                    },
                  ],
                },
                system: 'https://healthid.ndhm.gov.in',
                value: patientDetails.abha_address || uuidv4(),
              },
            ],
            name: [
              {
                text: patientDetails.patientName,
              },
            ],
            telecom: [
              {
                system: 'phone',
                value: String(patientDetails.mobileno),
                use: 'home',
              },
            ],
            gender: patientDetails.gender?.toLowerCase(),
            birthDate: patientDetails.bundleDate,
          },
        },
        {
          fullUrl: `urn:uuid:${EncounterID}`,
          resource: {
            resourceType: 'Encounter',
            id: EncounterID,
            status: 'finished',
            class: {
              system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
              code: 'AMB',
              display: 'OPD Visit',
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
            },
            period: {
              start: CurrDate,
            },
          },
        },
        {
          fullUrl: `urn:uuid:${OrgtID}`,
          resource: {
            resourceType: 'Organization',
            id: OrgtID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'PRN',
                      display: 'Provider number',
                    },
                  ],
                },
                system: 'https://facility.ndhm.gov.in',
                value: String(getHosDetails.plenome_id) || '4567823',
              },
            ],
            name: getHosDetails.hospital_name,
            telecom: [
              {
                system: 'phone',
                value: getHosDetails.contact_no,
                use: 'work',
              },
              {
                system: 'email',
                value: getHosDetails.email,
                use: 'work',
              },
            ],
          },
        },
      ],
    };

    if (immunizationDetails && immunizationDetails?.length > 0) {
      const refs = [];
      const entries = [];

      immunizationDetails.forEach((imm) => {
        const immId = uuidv4();
        refs.push({ reference: `urn:uuid:${immId}` });

        entries.push({
          fullUrl: `urn:uuid:${immId}`,
          resource: {
            resourceType: 'Immunization',
            id: immId,
            status: 'completed',
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Immunization',
              ],
            },
            vaccineCode: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  display: imm.vaccineName,
                },
              ],
              text: imm.vaccineName,
            },
            patient: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails?.patientName,
            },
            occurrenceDateTime: new Date(imm.dateOfImmunization).toISOString(),
            manufacturer: {
              display: imm.manufacturer,
            },
            lotNumber: imm.lotNumber,
            protocolApplied: [
              {
                doseNumberPositiveInt: Number(imm.doseNumber)
                  ? Number(imm.doseNumber)
                  : undefined,
              },
            ],
            performer: [
              {
                actor: {
                  reference: `urn:uuid:${PractitionerID}`,
                  display: doctorDetails?.doctorName,
                },
              },
            ],
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Immunizations',
        code: {
          coding: [
            {
              system: 'http://loinc.org',
              code: '11369-6',
              display: 'History of Immunization',
            },
          ],
        },
        entry: refs,
      });

      wellnessBundle.entry.push(...entries);
    }

    const uploadWellnessBody = {
      value: wellnessBundle,
    };

    const response1 = await axios.post(
      'https://abha-api.plenome.com/file_upload',
      uploadWellnessBody,
    );
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];

    const carecontext_reqbody = {
      abhaAddress: abhaAddress,
      patient_ref_no: await getPatDOB.aayush_unique_id,
      name: await this.normalizeSpaces(await getPatDOB.patient_name),
      gender: await getPatDOB.gender,
      year_of_birth: await yob,
      mobileno: await getPatDOB.mobileno,
      secondary_mobile: await getPatDOB.emergency_mobile_no,
      patient: [
        {
          display: 'Immunization Record Linked',
          careContexts: [
            {
              display: 'Immunization Record' + formattedDate,
              doc_key: response1.data.data,
            },
          ],

          hiType: 'ImmunizationRecord',
          count: 1,
        },
      ],
    };
    if (
      abhaAddress &&
      abhaAddress.trim() != '' &&
      abhaAddress.toLocaleLowerCase() != 'null'
    ) {
      if (getPatientID.patient_id == checkPatientAbhaAddress.patient_id) {
        const PatientDetails = await patientDetails;

        if (
          checkPatientAbhaAddress.link_token_updated_date &&
          checkPatientAbhaAddress.linkToken
        ) {
          const givenDate = new Date(
            checkPatientAbhaAddress.link_token_updated_date,
          );
          const currentDate = new Date();

          currentDate.setHours(0, 0, 0, 0);
          givenDate.setHours(0, 0, 0, 0);

          const monthDifference =
            (currentDate.getFullYear() - givenDate.getFullYear()) * 12 +
            currentDate.getMonth() -
            givenDate.getMonth();

          if (monthDifference > 5) {
            const getPatnameBody = {
              abhaAddress: abhaAddress,
            };

            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };
            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };

            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }
        } else {
          const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
            `select * from patient_abha_address where abhaAddress = ?`,
            [abhaAddress],
          );
          if (!checkPatientAbhaAddress.linkToken && !checkPatientAbhaAddress.link_token_updated_date) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const [getHosHipId] = await this.connection.query(
              `select hip_id from hospitals where plenome_id = ?`,
              [hospital_id],
            );

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };

            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };
            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }


        }
        const existing_link_token: any = await this.getexistingLinkToken(
          hospital_id,
          abhaAddress,
        );

        if (existing_link_token.linkToken) {
          const cc_headers = {
            'X-LINK-TOKEN': await existing_link_token.linkToken,
            'X-HIP-ID': await getHosHipId.hip_id,
            'Content-Type': 'application/json',
          };
          await axios.post(
            'https://abha-api.plenome.com/link/carecontext',
            carecontext_reqbody,
            { headers: cc_headers },
          );
        }
      }
    } else {
      const cc_headers = {
        'X-LINK-TOKEN': 'Temp_linktoken',
        'X-HIP-ID': await getHosHipId.hip_id,
        'Content-Type': 'application/json',
      };
      try {
        await axios.post(
          'https://abha-api.plenome.com/link/carecontext',
          carecontext_reqbody,
          { headers: cc_headers },
        );
        await this.send_sms(
          patientDetails.emergency_mobile_no?.trim() || patientDetails.mobileno,
          getHosHipId.hip_id,
          getHosHipId.hip_name,
        );
      } catch (error) {
        console.log(error, 'error1111');
      }

    }
    return wellnessBundle;
  }

  async createLabresults(
    labResults: any[],
    hospital_id: any,
    opd_id: any,
    abhaAddress: string,
    file: any,
  ) {
    if (!hospital_id) {
      return {
        status: 'failed',
        message: 'enter hospital_id to post clinical notes',
      };
    }
    const docs = await this.findAll(await file);

    const [getPatientID] = await this.dynamicConnection.query(
      `select patient_id from opd_details where id = ?`,
      [opd_id],
    );

    const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
      `select * from patient_abha_address where abhaAddress = ?`,
      [abhaAddress],
    );

    const [getPatDOB] = await this.dynamicConnection.query(
      `select * from patients where id = ?`,
      [getPatientID.patient_id],
    );

    let yob;
    if (getPatDOB.dob) {
      const [getYob] = await this.dynamicConnection.query(
        `SELECT YEAR(dob) AS year FROM patients where id = ?`,
        [getPatientID.patient_id],
      );
      yob = getYob.year;
    }

    const [patientDetails] = await this.dynamicConnection.query(
      `select patients.id,
      emergency_mobile_no,
      coalesce(patients.patient_name,"-") patientName,
      coalesce(DATE_FORMAT(patients.dob, '%D %b %Y'),"-") dob,
      date(patients.dob) bundleDate,
      coalesce(patients.age,"-") age,
      coalesce(patients.mobileno,"-") mobileno,
      coalesce(patients.email,"-") email,
      coalesce(patients.gender,"-") gender,
      coalesce(patients.abha_address,"-") abha_address,
      coalesce(patients.address,"-") address,
      coalesce(blood_bank_products.name,"-") patient_blood_group 
    from patients 
    left join blood_bank_products 
      on patients.blood_bank_product_id = blood_bank_products.id 
    where patients.id = ?`,
      [getPatientID.patient_id],
    );
    if (patientDetails.gender.toLocaleLowerCase() == 'm' || patientDetails.gender.toLocaleLowerCase() == 'male') {
      patientDetails.gender = 'male';
    } else if (patientDetails.gender.toLocaleLowerCase() == 'f' || patientDetails.gender.toLocaleLowerCase() == 'female') {
      patientDetails.gender = 'female';
    } else {
      patientDetails.gender = 'other';
    }
    const [getDocId] = await this.dynamicConnection.query(
      `select cons_doctor from visit_details where opd_details_id = ?`,
      [opd_id],
    );

    const [doctorDetails] = await this.dynamicConnection.query(
      `select concat(staff.name," ",staff.surname) doctorName,staff.employee_id,staff.gender 
    from staff where id = ?`,
      [getDocId.cons_doctor],
    );

    const bundleDate = new Date(patientDetails.bundleDate);
    const options = {
      year: 'numeric' as const,
      month: '2-digit' as const,
      day: '2-digit' as const,
      hour: '2-digit' as const,
      minute: '2-digit' as const,
      second: '2-digit' as const,
      hourCycle: 'h23' as const,
      timeZone: 'Asia/Kolkata',
    };

    const new_bundle_Date = new Intl.DateTimeFormat('en-CA', options).format(
      bundleDate,
    );
    const [date, time] = new_bundle_Date.split(', ');
    const isoDate = `${date}T${time}`;
    const finaldob = isoDate.split('T')[0];
    patientDetails.bundleDate = finaldob;

    const [getHosDetails] = await this.connection.query(
      `select * from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    const [getHosHipId] = await this.connection.query(
      `select hip_id from hospitals where plenome_id = ?`,
      [hospital_id],
    );

    let CurrDate = new Date().toISOString();
    let CompositionID = uuidv4();
    let PractitionerID = uuidv4();
    let PatientID = uuidv4();
    let OrgtID = uuidv4();
    let EncounterID = uuidv4();
    let docRefId = uuidv4();
    let wellnessBundle: any = {
      resourceType: 'Bundle',
      id: uuidv4(),
      meta: {
        versionId: '1',
        lastUpdated: CurrDate,
        profile: [
          'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle',
        ],
        security: [
          {
            system: 'http://terminology.hl7.org/CodeSystem/v3-Confidentiality',
            code: 'V',
            display: 'very restricted',
          },
        ],
      },
      identifier: {
        system: 'http://hip.in',
        value: uuidv4(),
      },
      type: 'document',
      timestamp: CurrDate,
      entry: [
        {
          fullUrl: `urn:uuid:${CompositionID}`,
          resource: {
            resourceType: 'Composition',
            id: CompositionID,
            language: 'en-IN',
            identifier: [
              {
                system: 'https://ndhm.in/phr',
                value: uuidv4(),
              },
            ],
            status: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '736373009',
                  display: 'HealthDocumentRecord',
                },
              ],
              text: 'HealthDocumentRecord',
            },
            encounter: {
              reference: `urn:uuid:${EncounterID}`,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            date: CurrDate,
            author: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
            title: 'Diagnostic Report',
            custodian: {
              reference: `urn:uuid:${OrgtID}`,
              display: getHosDetails.hospital_name,
            },
            section: [
              {
                title: 'Document Reference',
                code: {
                  coding: [
                    {
                      system: 'http://snomed.info/sct',
                      code: '371530004',
                      display: 'Clinical consultation report',
                    },
                  ],
                },
                entry: [
                  {
                    reference: `urn:uuid:${docRefId}`,
                    display: 'DocumentReference',
                  },
                ],
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PractitionerID}`,
          resource: {
            resourceType: 'Practitioner',
            id: PractitionerID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MD',
                      display: 'Medical License number',
                    },
                  ],
                },
                system: 'https://doctor.ndhm.gov.in',
                value: doctorDetails.employee_id || '21-1521-3828-3227',
              },
            ],
            name: [
              {
                text: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PatientID}`,
          resource: {
            resourceType: 'Patient',
            id: PatientID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MR',
                      display: 'Medical record number',
                    },
                  ],
                },
                system: 'https://healthid.ndhm.gov.in',
                value: patientDetails.abha_address || uuidv4(),
              },
            ],
            name: [
              {
                text: patientDetails.patientName,
              },
            ],
            telecom: [
              {
                system: 'phone',
                value: String(patientDetails.mobileno),
                use: 'home',
              },
            ],
            gender: patientDetails.gender?.toLowerCase(),
            birthDate: patientDetails.bundleDate,
          },
        },
        {
          fullUrl: `urn:uuid:${EncounterID}`,
          resource: {
            resourceType: 'Encounter',
            id: EncounterID,
            status: 'finished',
            class: {
              system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
              code: 'AMB',
              display: 'OPD Visit',
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
            },
            period: {
              start: CurrDate,
            },
          },
        },
        {
          fullUrl: `urn:uuid:${OrgtID}`,
          resource: {
            resourceType: 'Organization',
            id: OrgtID,
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'PRN',
                      display: 'Provider number',
                    },
                  ],
                },
                system: 'https://facility.ndhm.gov.in',
                value: String(getHosDetails.plenome_id) || '4567823',
              },
            ],
            name: getHosDetails.hospital_name,
            telecom: [
              {
                system: 'phone',
                value: getHosDetails.contact_no,
                use: 'work',
              },
              {
                system: 'email',
                value: getHosDetails.email,
                use: 'work',
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${docRefId}`,
          resource: {
            resourceType: 'DocumentReference',
            id: docRefId,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference',
              ],
            },
            status: 'current',
            docStatus: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '4241000179101',
                  display: 'consult note',
                },
              ],
              text: file.split('.')[0],
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: 'Patient',
            },
            content: [
              {
                attachment: {
                  contentType: 'application/pdf',
                  language: 'en-IN',
                  data: docs,
                  title: file.originalname,
                  creation: CurrDate,
                },
              },
            ],
          },
        },
      ],
    };

    if (labResults && labResults?.length > 0) {
      const refs = [];
      const entries = [];

      labResults.forEach((lab) => {
        const labId = uuidv4();
        refs.push({ reference: `urn:uuid:${labId}` });

        const numericVal = Number(lab.observations);

        const valueBlock: any = {};
        if (lab.unit && !isNaN(numericVal)) {
          valueBlock.valueQuantity = {
            value: numericVal,
            unit: lab.unit,
            system: 'http://unitsofmeasure.org',
            code: lab.unit,
          };
        } else if (!isNaN(numericVal)) {
          valueBlock.valueQuantity = {
            value: numericVal,
          };
        } else {
          valueBlock.valueString = lab.observations;
        }

        entries.push({
          fullUrl: `urn:uuid:${labId}`,
          resource: {
            resourceType: 'Observation',
            id: labId,
            status: 'final',
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Observation',
              ],
            },
            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/observation-category',
                    code: 'laboratory',
                    display: 'Laboratory',
                  },
                ],
              },
            ],
            code: {
              coding: [
                {
                  system: 'http://loinc.org',
                  display: lab.investigationName,
                },
              ],
              text: lab.investigationName,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails?.patientName,
            },
            effectiveDateTime: new Date().toISOString(),
            ...valueBlock,
            interpretation: lab.interpretation
              ? [
                {
                  coding: [
                    {
                      system:
                        'http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation',
                      display: lab.interpretation,
                    },
                  ],
                  text: lab.interpretation,
                },
              ]
              : undefined,
            note: lab.additionalNotes
              ? [
                {
                  text: lab.additionalNotes,
                },
              ]
              : undefined,
            performer: [
              {
                actor: {
                  reference: `urn:uuid:${PractitionerID}`,
                  display: doctorDetails?.doctorName,
                },
              },
            ],
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Lab Results',
        code: {
          coding: [
            {
              system: 'http://loinc.org',
              code: '11502-2',
              display: 'Laboratory studies',
            },
          ],
        },
        entry: refs,
      });

      wellnessBundle.entry.push(...entries);
    }

    const uploadWellnessBody = {
      value: wellnessBundle,
    };

    const response1 = await axios.post(
      'https://abha-api.plenome.com/file_upload',
      uploadWellnessBody,
    );
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];

    const carecontext_reqbody = {
      abhaAddress: abhaAddress,
      patient_ref_no: await getPatDOB.aayush_unique_id,
      name: await this.normalizeSpaces(await getPatDOB.patient_name),
      gender: await getPatDOB.gender,
      year_of_birth: await yob,
      mobileno: await getPatDOB.mobileno,
      secondary_mobile: await getPatDOB.emergency_mobile_no,
      patient: [
        {
          display: 'HealthDocumentRecord Linked',
          careContexts: [
            {
              display: 'HealthDocumentRecord' + formattedDate,
              doc_key: response1.data.data,
            },
          ],

          hiType: 'HealthDocumentRecord',
          count: 1,
        },
      ],
    };
    if (
      abhaAddress &&
      abhaAddress.trim() != '' &&
      abhaAddress.toLocaleLowerCase() != 'null'
    ) {
      if (getPatientID.patient_id == checkPatientAbhaAddress.patient_id) {
        const PatientDetails = await patientDetails;

        if (
          checkPatientAbhaAddress.link_token_updated_date &&
          checkPatientAbhaAddress.linkToken
        ) {
          const givenDate = new Date(
            checkPatientAbhaAddress.link_token_updated_date,
          );
          const currentDate = new Date();

          currentDate.setHours(0, 0, 0, 0);
          givenDate.setHours(0, 0, 0, 0);

          const monthDifference =
            (currentDate.getFullYear() - givenDate.getFullYear()) * 12 +
            currentDate.getMonth() -
            givenDate.getMonth();

          if (monthDifference > 5) {
            const getPatnameBody = {
              abhaAddress: abhaAddress,
            };

            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };
            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };

            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }
        } else {
          const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
            `select * from patient_abha_address where abhaAddress = ?`,
            [abhaAddress],
          );
          if (!checkPatientAbhaAddress.linkToken && !checkPatientAbhaAddress.link_token_updated_date) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const [getHosHipId] = await this.connection.query(
              `select hip_id from hospitals where plenome_id = ?`,
              [hospital_id],
            );

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };

            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };
            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }


        }
        const existing_link_token: any = await this.getexistingLinkToken(
          hospital_id,
          abhaAddress,
        );

        if (existing_link_token.linkToken) {
          const cc_headers = {
            'X-LINK-TOKEN': await existing_link_token.linkToken,
            'X-HIP-ID': await getHosHipId.hip_id,
            'Content-Type': 'application/json',
          };
          await axios.post(
            'https://abha-api.plenome.com/link/carecontext',
            carecontext_reqbody,
            { headers: cc_headers },
          );
        }
      }
    } else {
      const cc_headers = {
        'X-LINK-TOKEN': 'Temp_linktoken',
        'X-HIP-ID': await getHosHipId.hip_id,
        'Content-Type': 'application/json',
      };
      try {
        await axios.post(
          'https://abha-api.plenome.com/link/carecontext',
          carecontext_reqbody,
          { headers: cc_headers },
        );
        await this.send_sms(
          patientDetails.emergency_mobile_no?.trim() || patientDetails.mobileno,
          getHosHipId.hip_id,
          getHosHipId.hip_name,
        );
      } catch (error) {
        console.log(error, 'error1111');
      }

    }
    return wellnessBundle;
  }

  async createInvoice(
    invoiceDetails: any[],
    hospital_id: any,
    opd_id: any,
    abhaAddress: string,
  ) {
    if (!hospital_id) {
      return {
        status: 'failed',
        message: 'enter hospital_id to post clinical notes',
      };
    }

    const [getPatientID] = await this.dynamicConnection.query(
      `select patient_id from opd_details where id = ?`,
      [opd_id],
    );

    const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
      `select * from patient_abha_address where abhaAddress = ?`,
      [abhaAddress],
    );

    const [getPatDOB] = await this.dynamicConnection.query(
      `select * from patients where id = ?`,
      [getPatientID.patient_id],
    );

    let yob;
    if (getPatDOB.dob) {
      const [getYob] = await this.dynamicConnection.query(
        `SELECT YEAR(dob) AS year FROM patients where id = ?`,
        [getPatientID.patient_id],
      );
      yob = getYob.year;
    }

    const [patientDetails] = await this.dynamicConnection.query(
      `select patients.id,
      emergency_mobile_no,
coalesce(patients.patient_name,"-") patientName,
coalesce(DATE_FORMAT(patients.dob, '%D %b %Y'),"-") dob,
date(patients.dob) bundleDate,
coalesce(patients.age,"-") age,
coalesce(patients.mobileno,"-") mobileno,
coalesce(patients.email,"-") email,
coalesce(patients.gender,"-") gender,
coalesce(patients.abha_address,"-") abha_address,
coalesce(patients.address,"-") address,
coalesce(blood_bank_products.name,"-") patient_blood_group
from patients
left join blood_bank_products
on patients.blood_bank_product_id = blood_bank_products.id
where patients.id = ?`,
      [getPatientID.patient_id],
    );
    if (patientDetails.gender.toLocaleLowerCase() == 'm' || patientDetails.gender.toLocaleLowerCase() == 'male') {
      patientDetails.gender = 'male';
    } else if (patientDetails.gender.toLocaleLowerCase() == 'f' || patientDetails.gender.toLocaleLowerCase() == 'female') {
      patientDetails.gender = 'female';
    } else {
      patientDetails.gender = 'other';
    }
    const [getDocId] = await this.dynamicConnection.query(
      `select cons_doctor from visit_details where opd_details_id = ?`,
      [opd_id],
    );

    const [doctorDetails] = await this.dynamicConnection.query(
      `select concat(staff.name," ",staff.surname) doctorName,staff.employee_id,staff.gender
from staff where id = ?`,
      [getDocId.cons_doctor],
    );

    const bundleDate = new Date(patientDetails.bundleDate);
    const options = {
      year: 'numeric' as const,
      month: '2-digit' as const,
      day: '2-digit' as const,
      hour: '2-digit' as const,
      minute: '2-digit' as const,
      second: '2-digit' as const,
      hourCycle: 'h23' as const,
      timeZone: 'Asia/Kolkata',
    };

    const new_bundle_Date = new Intl.DateTimeFormat('en-CA', options).format(
      bundleDate,
    );
    const [date, time] = new_bundle_Date.split(', ');
    const isoDate = `${date}T${time}`;
    const finaldob = isoDate.split('T')[0];
    patientDetails.bundleDate = finaldob;

    const [getHosDetails] = await this.connection.query(
      `select * from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    const [getHosHipId] = await this.connection.query(
      `select hip_id from hospitals where plenome_id = ?`,
      [hospital_id],
    );

    let CurrDate = new Date().toISOString();
    let CompositionID = uuidv4();
    let PractitionerID = uuidv4();
    let PatientID = uuidv4();
    let OrgtID = uuidv4();
    let EncounterID = uuidv4();

    let wellnessBundle: any = {
      id: `Invoice-${uuidv4()}`,
      meta: {
        versionId: '1',
        lastUpdated: CurrDate,
        profile: [
          'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle',
        ],
      },
      resourceType: 'Bundle',
      identifier: {
        system: getHosDetails?.website || 'https://abha-api.plenome.com',
        value: `INV-${opd_id}`,
      },
      type: 'document',
      timestamp: CurrDate,
      entry: [
        {
          fullUrl: `urn:uuid:${CompositionID}`,
          resource: {
            id: CompositionID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/InvoiceRecord',
              ],
            },
            language: 'en-IN',
            resourceType: 'Composition',
            text: {
              status: 'generated',
              div: '<div xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-IN" lang="en-IN">Invoice</div>',
            },
            status: 'final',
            type: { text: 'Invoice Record' },
            subject: {
              id: PatientID,
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            encounter: {
              id: EncounterID,
              reference: `urn:uuid:${EncounterID}`,
              display: `OPD-${opd_id}`,
            },
            date: CurrDate,
            author: [
              {
                id: PractitionerID,
                reference: `urn:uuid:${PractitionerID}`,
                display: doctorDetails.doctorName || 'Attending Practitioner',
              },
            ],
            title: 'Invoice',
            custodian: {
              id: OrgtID,
              reference: `urn:uuid:${OrgtID}`,
              display: getHosDetails.hospital_name,
            },
            section: [
              {
                title: 'Invoice Record',
                entry: [
                ],
              },
            ],
          },
        },

        {
          fullUrl: `urn:uuid:${PatientID}`,
          resource: {
            id: PatientID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Patient',
              ],
            },
            resourceType: 'Patient',
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MR',
                      display: 'Medical record number',
                    },
                  ],
                },
                system:
                  getHosDetails?.website || 'https://abha-api.plenome.com',
                value: `INV-${opd_id}`,
              },
            ],
            name: [
              {
                use: 'official',
                text: patientDetails.patientName,
                family:
                  patientDetails.patientName.split(' ').slice(1).join(' ') ||
                  patientDetails.patientName,
                given: [
                  patientDetails.patientName.split(' ')[0] ||
                  patientDetails.patientName,
                ],
              },
            ],
            gender: (patientDetails.gender || '').toLowerCase(),
            birthDate: patientDetails.bundleDate,
          },
        },

        {
          fullUrl: `urn:uuid:${EncounterID}`,
          resource: {
            id: EncounterID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Encounter',
              ],
            },
            resourceType: 'Encounter',
            text: {
              status: 'generated',
              div: '<div xmlns="http://www.w3.org/1999/xhtml"> encounter </div>',
            },
            status: 'arrived',
            class: {
              system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
              code: 'AMB',
              display: 'OPD Visit',
            },
            type: [
              {
                coding: [
                  {
                    system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
                    code: 'AMB',
                    display: 'OPD Visit',
                  },
                ],
                text: 'OPD Visit',
              },
            ],
            subject: {
              id: PatientID,
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
          },
        },

        {
          fullUrl: `urn:uuid:${PractitionerID}`,
          resource: {
            id: PractitionerID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Practitioner',
              ],
            },
            resourceType: 'Practitioner',
            text: {
              status: 'generated',
              div: `<div xmlns="http://www.w3.org/1999/xhtml"> Practitioner ${doctorDetails.doctorName || ''
                } </div>`,
            },
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MD',
                      display: 'Medical License number',
                    },
                  ],
                },
                system:
                  getHosDetails?.website || 'https://abha-api.plenome.com',
                value: doctorDetails.employee_id || '12345',
              },
            ],
            name: [
              {
                use: 'official',
                text: doctorDetails.doctorName || 'Attending Practitioner',
                family: doctorDetails.doctorName || 'Attending Practitioner',
                given: [doctorDetails.doctorName || 'Attending Practitioner'],
              },
            ],
          },
        },

        {
          fullUrl: `urn:uuid:${OrgtID}`,
          resource: {
            id: OrgtID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Organization',
              ],
            },
            resourceType: 'Organization',
            text: {
              status: 'generated',
              div: '<div xmlns="http://www.w3.org/1999/xhtml"> Organization </div>',
            },
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'PRN',
                      display: 'Provider number',
                    },
                  ],
                },
                system: 'https://healthid.ndhm.gov.in',
                value:
                  String(getHosDetails.hip_id || getHosDetails.plenome_id) ||
                  '22-7225-4829-5255',
              },
            ],
            name: getHosDetails.hospital_name,
          },
        },
      ],
    };
    if (invoiceDetails && invoiceDetails.length > 0) {
      const chargeItemEntries: any[] = [];
      const lineItems: any[] = [];

      const NDHM_PRICE_COMPONENT = {
        rate: {
          coding: [
            {
              system:
                'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components',
              code: '01',
              display: 'Rate',
            },
          ],
        },
        discount: {
          coding: [
            {
              system:
                'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components',
              code: '02',
              display: 'Discount',
            },
          ],
        },
        tax: {
          coding: [
            {
              system:
                'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components',
              code: '03',
              display: 'Tax',
            },
          ],
        },
        mrp: {
          coding: [
            {
              system:
                'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-price-components',
              code: '04',
              display: 'MRP',
            },
          ],
        },
      };

      const getBillingCode = (inv: any) => ({
        coding: [
          {
            system:
              'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-billing-codes',
            code: inv?.ndhmCode ?? '99',
            display: inv?.ndhmDisplay ?? 'Others',
          },
        ],
      });

      let totalBase = 0;
      let totalDiscount = 0;
      let totalTax = 0;

      invoiceDetails.forEach((inv, idx) => {
        const chargeItemId = uuidv4();
        const chargeItemFullUrl = `urn:uuid:${chargeItemId}`;

        const qty = Number(inv.quantity ?? 1) || 1;
        const unitPrice = Number(inv.unitPrice ?? 0) || 0;
        const discount = Math.max(0, Number(inv.discount ?? 0) || 0);
        let mrp =
          inv.mrp !== undefined && inv.mrp !== null ? Number(inv.mrp) : null;

        const lineBase = Number((unitPrice * qty).toFixed(2));
        const lineDiscount = Math.min(discount, lineBase);

        const taxes = Array.isArray(inv.tax) ? inv.tax : [];
        const taxableAmount = lineBase - lineDiscount;

        const lineTax = taxes.reduce((sum: number, t: any) => {
          const taxPct = Number(t.taxAmount ?? 0) || 0;
          const taxAmt = taxPct;
          return sum + taxAmt;
        }, 0);
        mrp = mrp + lineTax - lineDiscount;
        totalBase += lineBase;
        totalDiscount += lineDiscount;
        totalTax += lineTax;

        const chargeItemResource: any = {
          id: chargeItemId,
          meta: {
            profile: [
              'https://nrces.in/ndhm/fhir/r4/StructureDefinition/ChargeItem',
            ],
          },
          resourceType: 'ChargeItem',
          status: 'billed',
          code: getBillingCode(inv),
          subject: {
            reference: `urn:uuid:${PatientID}`,
            display: patientDetails.patientName,
          },
          quantity: { value: qty, unit: ' ' },
          productCodeableConcept: { text: inv.itemName || 'Item' },
        };

        if (mrp !== null && !Number.isNaN(mrp)) {
          chargeItemResource.note = [
            {
              text: `MRP: Rs ${mrp.toFixed(2)}`,
            },
          ];
        }

        chargeItemEntries.push({
          id: chargeItemId,
          fullUrl: chargeItemFullUrl,
          resource: chargeItemResource,
        });

        const priceComponent: any[] = [
          {
            type: 'base',
            amount: { value: lineBase, currency: 'INR' },
            code: NDHM_PRICE_COMPONENT.rate,
          },
        ];

        if (lineDiscount > 0) {
          priceComponent.push({
            type: 'discount',
            amount: { value: Number(lineDiscount.toFixed(2)), currency: 'INR' },
            code: NDHM_PRICE_COMPONENT.discount,
          });
        }

        if (lineTax > 0) {
          priceComponent.push({
            type: 'tax',
            amount: { value: Number(lineTax.toFixed(2)), currency: 'INR' },
            code: NDHM_PRICE_COMPONENT.tax,
          });
        }
        if (mrp !== null && !Number.isNaN(mrp)) {
          priceComponent.push({
            type: 'informational',
            amount: { value: Number(mrp.toFixed(2)), currency: 'INR' },
            code: NDHM_PRICE_COMPONENT.mrp,
          });
        }
        lineItems.push({
          sequence: idx + 1,
          chargeItemReference: { reference: chargeItemFullUrl },
          priceComponent,
        });
      });

      const invId = uuidv4();
      const invFullUrl = `urn:uuid:${invId}`;

      const totalNet = Number((totalBase - totalDiscount).toFixed(2));
      const totalGross = Number((totalNet + totalTax).toFixed(2));
      const finalNet = Number((totalGross - totalDiscount).toFixed(2))
      const invoiceResourceEntry = {
        fullUrl: invFullUrl,
        resource: {
          resourceType: 'Invoice',
          id: `Consultation-${invId}`,
          meta: {
            profile: [
              'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Invoice',
            ],
          },
          text: {
            status: 'generated',
            div: '<div xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-IN" lang="en-IN">Invoice Record</div>',
          },
          identifier: [
            {
              system: getHosDetails?.website || 'https://abha-api.plenome.com',
              value: `INV-${opd_id}-${Date.now()}`,
            },
          ],
          status: 'issued',
          type: {
            coding: [
              {
                system:
                  'https://nrces.in/ndhm/fhir/r4/CodeSystem/ndhm-billing-codes',
                code: '00',
                display: 'Consultation',
              },
            ],
          },
          subject: {
            reference: `urn:uuid:${PatientID}`,
            display: patientDetails.patientName,
          },
          date: CurrDate,
          participant: [{ actor: { reference: `urn:uuid:${PractitionerID}` } }],
          lineItem: lineItems,
          totalPriceComponent: [
            {
              type: 'base',
              amount: { value: Number(totalBase.toFixed(2)), currency: 'INR' },
              code: NDHM_PRICE_COMPONENT.rate,
            },
            {
              type: 'discount',
              amount: {
                value: Number(totalDiscount.toFixed(2)),
                currency: 'INR',
              },
              code: NDHM_PRICE_COMPONENT.discount,
            },
            {
              type: 'tax',
              amount: {
                value: Number(totalTax.toFixed(2)),
                currency: 'INR',
              },
              code: NDHM_PRICE_COMPONENT.tax,
            },
          ],
          totalNet: { value: finalNet, currency: 'INR' },
          totalGross: { value: totalGross, currency: 'INR' },
          paymentTerms: `Amount Paid: Rs ${totalGross.toFixed(
            2,
          )} Balance: Rs ${(0).toFixed(2)}`,
          note: [{ text: `Amount Chargeable (in words) :${totalGross}` }],
        },
      };

      wellnessBundle.entry.push(invoiceResourceEntry);
      wellnessBundle.entry.push(...chargeItemEntries);

      const compRes = wellnessBundle.entry[0].resource;
      compRes.section[0].entry = [
        {
          id: invId,
          reference: invFullUrl,
          type: 'Invoice',
          display: 'Invoice',
        },
      ];
    }

    const uploadWellnessBody = {
      value: wellnessBundle,
    };

    const response1 = await axios.post(
      'https://abha-api.plenome.com/file_upload',
      uploadWellnessBody,
    );
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];

    const carecontext_reqbody = {
      abhaAddress: abhaAddress,
      patient_ref_no: await getPatDOB.aayush_unique_id,
      name: await this.normalizeSpaces(await getPatDOB.patient_name),
      gender: await getPatDOB.gender,
      year_of_birth: await yob,
      mobileno: await getPatDOB.mobileno,
      secondary_mobile: await getPatDOB.emergency_mobile_no,
      patient: [
        {
          display: 'Invoice',
          careContexts: [
            {
              display: 'Invoice' + formattedDate,
              doc_key: response1.data.data,
            },
          ],

          hiType: 'Invoice',
          count: 1,
        },
      ],
    };
    if (
      abhaAddress &&
      abhaAddress.trim() != '' &&
      abhaAddress.toLocaleLowerCase() != 'null'
    ) {
      if (getPatientID.patient_id == checkPatientAbhaAddress.patient_id) {
        const PatientDetails = await patientDetails;

        if (
          checkPatientAbhaAddress.link_token_updated_date &&
          checkPatientAbhaAddress.linkToken
        ) {
          const givenDate = new Date(
            checkPatientAbhaAddress.link_token_updated_date,
          );
          const currentDate = new Date();

          currentDate.setHours(0, 0, 0, 0);
          givenDate.setHours(0, 0, 0, 0);

          const monthDifference =
            (currentDate.getFullYear() - givenDate.getFullYear()) * 12 +
            currentDate.getMonth() -
            givenDate.getMonth();

          if (monthDifference > 5) {
            const getPatnameBody = {
              abhaAddress: abhaAddress,
            };

            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };
            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };

            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }
        } else {
          const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
            `select * from patient_abha_address where abhaAddress = ?`,
            [abhaAddress],
          );
          if (!checkPatientAbhaAddress.linkToken && !checkPatientAbhaAddress.link_token_updated_date) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const [getHosHipId] = await this.connection.query(
              `select hip_id from hospitals where plenome_id = ?`,
              [hospital_id],
            );

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };

            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };
            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }


        }
        const existing_link_token: any = await this.getexistingLinkToken(
          hospital_id,
          abhaAddress,
        );

        if (existing_link_token.linkToken) {
          const cc_headers = {
            'X-LINK-TOKEN': await existing_link_token.linkToken,
            'X-HIP-ID': await getHosHipId.hip_id,
            'Content-Type': 'application/json',
          };
          await axios.post(
            'https://abha-api.plenome.com/link/carecontext',
            carecontext_reqbody,
            { headers: cc_headers },
          );
        }
      }
    } else {
      const cc_headers = {
        'X-LINK-TOKEN': 'Temp_linktoken',
        'X-HIP-ID': await getHosHipId.hip_id,
        'Content-Type': 'application/json',
      };
      try {
        await axios.post(
          'https://abha-api.plenome.com/link/carecontext',
          carecontext_reqbody,
          { headers: cc_headers },
        );
        console.log(patientDetails.emergency_mobile_no?.trim(), "asd", patientDetails.mobileno);

        await this.send_sms(
          patientDetails.emergency_mobile_no?.trim() || patientDetails.mobileno,
          getHosHipId.hip_id,
          getHosHipId.hip_name,
        );
      } catch (error) {
        console.log(error, 'error1111');
      }

    }
    return wellnessBundle;
  }

  async createOpConsultation(
    chiefComplaintsBasic: any[],
    getPastTreatHis: any,
    followupDetails: any,
    hospital_id: any,
    opd_id: any,
    file: any,
    abhaAddress: string,
    diet_plan: any,
    treatmentAdvice: any,
    prescriptionDetails: any,
    investigationAdvice: any,

    physicalExam?: { summary?: string; findings?: string[] },
    allergies?: Array<{
      substance: string;
      criticality?: 'low' | 'high' | 'unable-to-assess';
      status?: 'active' | 'inactive' | 'resolved';
      note?: string;
    }>,
    familyHistory?: Array<{
      relationship: string;
      condition?: string;
      sex?: 'male' | 'female' | 'other' | 'unknown' | string;
      ageYears?: number;
      contributeToDeath?: boolean;
      note?: string;
    }>,
  ) {
    if (!hospital_id) {
      return {
        status: 'failed',
        message: 'enter hospital_id to post clinical notes',
      };
    }

    const isBlank = (v: any) => {
      if (v === null || v === undefined) return true;
      if (typeof v === 'string') {
        const t = v.trim().toLowerCase();
        return (
          t === '' || t === 'na' || t === 'n/a' || t === 'null' || t === '-'
        );
      }
      return false;
    };
    let fileParam: any = file;
    if (typeof file === 'string') {
      fileParam = new String(file);
      (fileParam as any).originalname = file;
    }
    const clean = <T = any>(v: T | undefined | null): T | undefined =>
      isBlank(v) ? undefined : (v as T);
    const cleanText = (v: any, fallback?: string) =>
      isBlank(v) ? fallback ?? undefined : String(v).trim();
    const cleanNumber = (v: any): number | undefined => {
      if (v === null || v === undefined) return undefined;
      const n = Number(v);
      return Number.isFinite(n) ? n : undefined;
    };
    const cleanGender = (g: any): 'male' | 'female' | 'other' | undefined => {
      const t = (g ?? '').toString().trim().toLowerCase();
      if (t === 'male' || t === 'm') return 'male';
      if (t === 'female' || t === 'f') return 'female';
      if (t === 'other' || t === 'o') return 'other';
      return undefined;
    };
    const [getPatientID] = await this.dynamicConnection.query(
      `select patient_id from opd_details where id = ?`,
      [opd_id],
    );

    const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
      `select * from patient_abha_address where abhaAddress = ?`,
      [abhaAddress],
    );

    const [getPatDOB] = await this.dynamicConnection.query(
      `select * from patients where id = ?`,
      [getPatientID.patient_id],
    );

    let yob;
    if (getPatDOB.dob) {
      const [getYob] = await this.dynamicConnection.query(
        `SELECT YEAR(dob) AS year FROM patients where id = ?`,
        [getPatientID.patient_id],
      );
      yob = getYob.year;
    }

    const [patientDetails] = await this.dynamicConnection.query(
      `select patients.id,
      emergency_mobile_no,
      coalesce(patients.patient_name,"-") patientName,
      coalesce(DATE_FORMAT(patients.dob, '%D %b %Y'),"-") dob,
      date(patients.dob) bundleDate,
      coalesce(patients.age,"-") age,
      coalesce(patients.mobileno,"-") mobileno,
      coalesce(patients.email,"-") email,
      coalesce(patients.gender,"-") gender,
      coalesce(patients.abha_address,"-") abha_address,
      coalesce(patients.address,"-") address,
      coalesce(blood_bank_products.name,"-") patient_blood_group 
    from patients 
    left join blood_bank_products 
      on patients.blood_bank_product_id = blood_bank_products.id 
    where patients.id = ?`,
      [getPatientID.patient_id],
    );
    if (patientDetails.gender.toLocaleLowerCase() == 'm' || patientDetails.gender.toLocaleLowerCase() == 'male') {
      patientDetails.gender = 'male';
    } else if (patientDetails.gender.toLocaleLowerCase() == 'f' || patientDetails.gender.toLocaleLowerCase() == 'female') {
      patientDetails.gender = 'female';
    } else {
      patientDetails.gender = 'other';
    }
    const [getDocId] = await this.dynamicConnection.query(
      `select cons_doctor from visit_details where opd_details_id = ?`,
      [opd_id],
    );

    const [doctorDetails] = await this.dynamicConnection.query(
      `select concat(staff.name," ",staff.surname) doctorName,staff.employee_id,staff.gender 
    from staff where id = ?`,
      [getDocId.cons_doctor],
    );

    const bundleDate = new Date(patientDetails.bundleDate);
    const options = {
      year: 'numeric' as const,
      month: '2-digit' as const,
      day: '2-digit' as const,
      hour: '2-digit' as const,
      minute: '2-digit' as const,
      second: '2-digit' as const,
      hourCycle: 'h23' as const,
      timeZone: 'Asia/Kolkata',
    };

    const new_bundle_Date = new Intl.DateTimeFormat('en-CA', options).format(
      bundleDate,
    );
    const [date, time] = new_bundle_Date.split(', ');
    const isoDate = `${date}T${time}`;
    const finaldob = isoDate.split('T')[0];
    patientDetails.bundleDate = finaldob;

    const [getHosDetails] = await this.connection.query(
      `select * from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    const [getHosHipId] = await this.connection.query(
      `select hip_id from hospitals where plenome_id = ?`,
      [hospital_id],
    );

    let CurrDate = new Date().toISOString();
    let CurrDatea = new Date(followupDetails?.bundleDate).toISOString();

    let currDate = new Date(followupDetails?.bundleDate || CurrDate);
    let oneHourBefore = new Date(currDate.getTime() + 60 * 60 * 1000);
    let CompositionID = uuidv4();
    let PractitionerID = uuidv4();
    let PatientID = uuidv4();
    let OrgtID = uuidv4();
    let EncounterID = uuidv4();
    let ChifeCompIDs: string[] = [];
    let treatHisID = uuidv4();
    let followupId = uuidv4();
    let docRefId = uuidv4();

    const physicalExamIds: string[] = [];
    const allergyIds: string[] = [];
    const familyHistoryIds: string[] = [];

    let selectedSymptoms: any[] = [];

    if (chiefComplaintsBasic) {
      selectedSymptoms = await chiefComplaintsBasic;
    }
    const docs = await this.findAll(await fileParam);

    if (selectedSymptoms) {
      selectedSymptoms.forEach((_elem: any) => {
        ChifeCompIDs.push(uuidv4());
      });
    }
    let currDateObj = new Date(CurrDate);
    currDateObj.setDate(currDateObj.getDate() + 2);
    let updatedDate = currDateObj.toISOString();

    if (
      physicalExam &&
      (physicalExam.summary ||
        (physicalExam.findings && physicalExam.findings.length))
    ) {
      const count =
        physicalExam.findings && physicalExam.findings.length
          ? physicalExam.findings.length
          : 1;
      for (let i = 0; i < count; i++) physicalExamIds.push(uuidv4());
    }
    if (allergies && allergies.length) {
      for (let i = 0; i < allergies.length; i++) allergyIds.push(uuidv4());
    }
    if (familyHistory && familyHistory.length) {
      for (let i = 0; i < familyHistory.length; i++)
        familyHistoryIds.push(uuidv4());
    }

    let wellnessBundle: any = {
      resourceType: 'Bundle',
      id: uuidv4(),

      identifier: {
        system: 'http://hip.in',
        value: uuidv4(),
      },
      type: 'document',
      timestamp: CurrDate,
      entry: [
        {
          fullUrl: `urn:uuid:${CompositionID}`,
          resource: {
            resourceType: 'Composition',
            id: `${CompositionID}`,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/OPConsultRecord',
              ],
            },
            language: 'en-IN',
            identifier: {
              system: 'https://ndhm.in/phr',
              value: uuidv4(),
            },
            status: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '371530004',
                  display: 'Clinical consultation report',
                },
              ],
              text: 'Clinical Consultation report',
            },
            encounter: {
              reference: `urn:uuid:${EncounterID}`,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            date: CurrDate,
            author: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: doctorDetails.doctorName,
              },
            ],
            title: 'Consultation Report',
            custodian: {
              reference: `urn:uuid:${OrgtID}`,
              display: await getHosDetails.hospital_name,
            },
            section: [
              {
                title: 'Chief complaints',
                code: {
                  coding: [
                    {
                      system: 'http://snomed.info/sct',
                      code: '422843007',
                      display: 'Chief complaint section',
                    },
                  ],
                },
                entry: [
                  ...ChifeCompIDs.map((comp: any) => ({
                    reference: `urn:uuid:${comp}`,
                    display: 'Condition',
                  })),
                ],
              },
              {
                title: 'Medical History',
                code: {
                  coding: [
                    {
                      system: 'http://snomed.info/sct',
                      code: '371529009',
                      display: 'History and physical report',
                    },
                  ],
                },
                entry: [
                  {
                    reference: `urn:uuid:${treatHisID}`,
                    display: 'Condition',
                  },
                ],
              },

              {
                title: 'Follow Up',
                code: {
                  coding: [
                    {
                      system: 'http://snomed.info/sct',
                      code: '736271009',
                      display: 'Outpatient care plan',
                    },
                  ],
                },
                entry: [
                  {
                    reference: `urn:uuid:${followupId}`,
                    display: 'Appointment',
                  },
                ],
              },
              {
                title: 'Document Reference',
                code: {
                  coding: [
                    {
                      system: 'http://snomed.info/sct',
                      code: '371530004',
                      display: 'Clinical consultation report',
                    },
                  ],
                },
                entry: [
                  {
                    reference: `urn:uuid:${docRefId}`,
                    display: 'DocumentReference',
                  },
                ],
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PractitionerID}`,
          resource: {
            resourceType: 'Practitioner',
            id: PractitionerID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Practitioner',
              ],
            },
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MD',
                      display: 'Medical License number',
                    },
                  ],
                },
                system: 'https://doctor.ndhm.gov.in',
                value: '21-1521-3828-3227',
              },
            ],
            name: [
              {
                text: doctorDetails.doctorName,
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${OrgtID}`,
          resource: {
            resourceType: 'Organization',
            id: OrgtID,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Organization',
              ],
            },
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'PRN',
                      display: 'Provider number',
                    },
                  ],
                },
                system: 'https://facility.ndhm.gov.in',
                value: '4567823',
              },
            ],
            name: await getHosDetails.hospital_name,
            telecom: [
              {
                system: 'phone',
                value: String(await getHosDetails.contact_no),
                use: 'work',
              },
              {
                system: 'email',
                value: await getHosDetails.email,
                use: 'work',
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${PatientID}`,
          resource: {
            resourceType: 'Patient',
            id: PatientID,
            meta: {
              versionId: '1',
              lastUpdated: '2020-07-09T14:58:58.181+05:30',
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Patient',
              ],
            },
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MR',
                      display: 'Medical record number',
                    },
                  ],
                },
                system: 'https://healthid.ndhm.gov.in',
                value: '22-7225-4829-5255',
              },
            ],
            name: [
              {
                text: patientDetails.patientName,
              },
            ],
            telecom: [
              {
                system: 'phone',
                value: patientDetails.mobileno,
                use: 'home',
              },
            ],
            gender: patientDetails?.gender.toLocaleLowerCase(),
            birthDate: patientDetails?.bundleDate,
          },
        },
        {
          fullUrl: `urn:uuid:${EncounterID}`,
          resource: {
            resourceType: 'Encounter',
            id: `${EncounterID}`,
            status: 'finished',
            class: {
              system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
              code: 'AMB',
              display: 'OPD Visit',
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
            },
            period: {
              start: CurrDate,
            },
          },
        },
        ...selectedSymptoms.map((symps: any, i: number) => ({
          fullUrl: `urn:uuid:${ChifeCompIDs[i]}`,
          resource: {
            resourceType: 'Condition',
            id: ChifeCompIDs[i],
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Condition',
              ],
            },
            clinicalStatus: {
              coding: [
                {
                  system:
                    'http://terminology.hl7.org/CodeSystem/condition-clinical',
                  code: 'active',
                  display: 'Active',
                },
              ],
            },
            code: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '297142003',
                  display:
                    symps?.complaints_name +
                    ' | ' +
                    symps?.duration +
                    ' | ' +
                    symps?.remarks,
                },
              ],
              text:
                symps?.complaints_name +
                ' | ' +
                symps?.duration +
                ' | ' +
                symps?.remarks,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: 'Patient',
            },
            recordedDate: CurrDate,
          },
        })),

        {
          fullUrl: `urn:uuid:${treatHisID}`,
          resource: {
            resourceType: 'Condition',
            id: treatHisID,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Condition',
              ],
            },
            clinicalStatus: {
              coding: [
                {
                  system:
                    'http://terminology.hl7.org/CodeSystem/condition-clinical',
                  code: 'recurrence',
                  display: 'Recurrence',
                },
              ],
            },
            code: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '46635009',
                  display: getPastTreatHis?.history || 'Past treatment history',
                },
              ],
              text: getPastTreatHis?.history || 'Past treatment history',
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: 'Patient',
            },
            recordedDate: CurrDate,
          },
        },
        {
          fullUrl: `urn:uuid:${followupId}`,
          resource: {
            resourceType: 'Appointment',
            id: followupId,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Appointment',
              ],
            },
            status: 'booked',
            serviceCategory: [
              {
                coding: [
                  {
                    system: 'http://snomed.info/sct',
                    code: '408443003',
                    display: 'General medical practice',
                  },
                ],
              },
            ],
            serviceType: [
              {
                coding: [
                  {
                    system: 'http://snomed.info/sct',
                    code: '11429006',
                    display: 'Consultation',
                  },
                ],
              },
            ],
            appointmentType: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '185389009',
                  display: 'Follow-up visit',
                },
              ],
            },
            reasonReference: [
              {
                reference: `urn:uuid:${uuidv4()}`,
                display: 'Condition',
              },
            ],
            description:
              (await followupDetails?.remarks) || 'remarks of the follow up',
            start: CurrDatea,
            end: oneHourBefore.toISOString(),
            created: CurrDate,
            basedOn: [
              {
                reference: `urn:uuid:${uuidv4()}`,
                display: 'ServiceRequest',
              },
            ],
            participant: [
              {
                actor: {
                  reference: `urn:uuid:${PatientID}`,
                  display: 'Patient',
                },
                status: 'accepted',
              },
              {
                actor: {
                  reference: `urn:uuid:${PractitionerID}`,
                  display: 'Practitioner',
                },
                status: 'accepted',
              },
            ],
          },
        },
        {
          fullUrl: `urn:uuid:${docRefId}`,
          resource: {
            resourceType: 'DocumentReference',
            id: docRefId,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference',
              ],
            },
            status: 'current',
            docStatus: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '4241000179101',
                  display: 'consult note',
                },
              ],
              text:
                (fileParam as any).toString().split('.')[0] || 'consult_note',
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: 'Patient',
            },
            content: [
              {
                attachment: {
                  contentType: 'application/pdf',
                  language: 'en-IN',
                  data: docs,
                  title: (fileParam as any).originalname || 'consult_note.pdf',
                  creation: CurrDate,
                },
              },
            ],
          },
        },
      ],
    };

    if (physicalExamIds.length) {
      wellnessBundle.entry[0].resource.section.push({
        title: 'Physical Examination',
        code: {
          coding: [
            {
              system: 'http://snomed.info/sct',
              code: '78077002',
              display: 'Physical examination',
            },
          ],
        },
        entry: physicalExamIds.map((id) => ({
          reference: `urn:uuid:${id}`,
          display: 'Observation',
        })),
      });
    }

    if (allergyIds.length) {
      wellnessBundle.entry[0].resource.section.push({
        title: 'Allergies',
        code: {
          coding: [
            {
              system: 'http://snomed.info/sct',
              code: '420134006',
              display: 'Allergy record',
            },
          ],
        },
        entry: allergyIds.map((id) => ({
          reference: `urn:uuid:${id}`,
          display: 'AllergyIntolerance',
        })),
      });
    }

    if (familyHistoryIds.length) {
      wellnessBundle.entry[0].resource.section.push({
        title: 'Family History',
        code: {
          coding: [
            {
              system: 'http://snomed.info/sct',
              code: '422432008',
              display: 'Family history section',
            },
          ],
        },
        entry: familyHistoryIds.map((id) => ({
          reference: `urn:uuid:${id}`,
          display: 'FamilyMemberHistory',
        })),
      });
    }

    if (
      physicalExam &&
      (physicalExam.summary || physicalExam.findings?.length)
    ) {
      const sectionEntries: any[] = [];

      if (physicalExam.summary) {
        const summaryId = uuidv4();
        sectionEntries.push({
          reference: `urn:uuid:${summaryId}`,
          display: 'Physical Exam Summary',
        });

        wellnessBundle.entry.push({
          fullUrl: `urn:uuid:${summaryId}`,
          resource: {
            resourceType: 'Observation',
            id: summaryId,
            status: 'final',
            code: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '5880005',
                  display: 'Physical examination report',
                },
              ],
              text: 'Physical Examination Summary',
            },
            valueString: physicalExam.summary,
            subject: { reference: `urn:uuid:${PatientID}` },
            effectiveDateTime: CurrDate,
          },
        });
      }

      if (physicalExam.findings?.length) {
        physicalExam.findings.forEach((finding) => {
          const findingId = uuidv4();

          sectionEntries.push({
            reference: `urn:uuid:${findingId}`,
            display: 'Physical Exam Finding',
          });

          wellnessBundle.entry.push({
            fullUrl: `urn:uuid:${findingId}`,
            resource: {
              resourceType: 'Observation',
              id: findingId,
              status: 'final',
              code: {
                coding: [
                  {
                    system: 'http://snomed.info/sct',
                    code: '164443003',
                    display: 'Finding of physical examination',
                  },
                ],
                text: 'Physical Examination Finding',
              },
              valueString: finding,
              subject: { reference: `urn:uuid:${PatientID}` },
              effectiveDateTime: CurrDate,
            },
          });
        });
      }

      wellnessBundle.entry[0].resource.section.push({
        title: 'Physical Examination',
        code: {
          coding: [
            {
              system: 'http://snomed.info/sct',
              code: '78077002',
              display: 'Physical examination',
            },
          ],
        },
        entry: sectionEntries,
      });
    }

    if (allergyIds.length) {
      allergies!.forEach((alg, idx) => {
        const statusCode = alg.status || 'active';
        const statusDisplay =
          statusCode.charAt(0).toUpperCase() + statusCode.slice(1);

        const noteText = alg.criticality
          ? `Criticality: ${alg.criticality}${alg.note ? ' - ' + alg.note : ''}`
          : alg.note || undefined;

        wellnessBundle.entry.push({
          fullUrl: `urn:uuid:${allergyIds[idx]}`,
          resource: {
            resourceType: 'AllergyIntolerance',
            id: allergyIds[idx],

            clinicalStatus: {
              text: statusDisplay,
              coding: [
                {
                  system:
                    'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical',
                  code: statusCode,
                  display: statusDisplay,
                },
              ],
            },
            verificationStatus: {
              text: 'Confirmed',
              coding: [
                {
                  system:
                    'http://terminology.hl7.org/CodeSystem/allergyintolerance-verification',
                  code: 'confirmed',
                  display: 'Confirmed',
                },
              ],
            },

            type: 'allergy',
            category: /peanut|egg|milk|seafood|dust|pollen|shellfish/i.test(
              String(alg.substance || ''),
            )
              ? ['food']
              : ['medication'],
            criticality: alg.criticality || 'unable-to-assess',

            code: {
              text: alg.substance,
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '419199007',
                  display: `Allergy to ${alg.substance}`,
                },
              ],
            },

            patient: { reference: `urn:uuid:${PatientID}`, display: 'Patient' },
            recordedDate: CurrDate,
            note: noteText ? [{ text: noteText }] : undefined,
          },
        });
      });
    }

    if (familyHistoryIds.length) {
      familyHistory!.forEach((fh, idx) => {
        const raw = String(fh.sex || 'unknown').toLowerCase();
        const sexCode =
          raw === 'male'
            ? 'male'
            : raw === 'female'
              ? 'female'
              : raw === 'other'
                ? 'other'
                : 'unknown';
        const sexDisplay = sexCode.charAt(0).toUpperCase() + sexCode.slice(1);

        const hasAge =
          fh.ageYears != null && !Number.isNaN(Number(fh.ageYears));
        const ageVal = hasAge ? Number(fh.ageYears) : undefined;

        wellnessBundle.entry.push({
          fullUrl: `urn:uuid:${familyHistoryIds[idx]}`,
          resource: {
            resourceType: 'FamilyMemberHistory',
            id: familyHistoryIds[idx],
            status: 'completed',
            patient: { reference: `urn:uuid:${PatientID}`, display: 'Patient' },

            relationship: { text: fh.relationship },

            sex: {
              text: sexDisplay,
              coding: [
                {
                  system: 'http://hl7.org/fhir/administrative-gender',
                  code: sexCode,
                  display: sexDisplay,
                },
              ],
            },

            ...(hasAge ? { ageAge: { value: ageVal!, unit: 'years' } } : {}),

            condition: [
              fh.condition
                ? {
                  code: {
                    text: fh.condition,
                    coding: [
                      {
                        system: 'http://snomed.info/sct',
                        code: '404684003',
                        display: fh.condition,
                      },
                    ],
                  },
                  ...(hasAge
                    ? { onsetAge: { value: ageVal!, unit: 'years' } }
                    : {}),
                  contributedToDeath: fh.contributeToDeath ?? false,
                }
                : {
                  code: { text: 'Not reported' },
                  ...(hasAge
                    ? { onsetAge: { value: ageVal!, unit: 'years' } }
                    : {}),
                  contributedToDeath: fh.contributeToDeath ?? false,
                },
            ],

            note: fh.note ? [{ text: fh.note }] : undefined,
            date: CurrDate,
          },
        });
      });
    }

    if (diet_plan) {
      const dietPlanId = uuidv4();
      const dietText =
        typeof diet_plan === 'string'
          ? diet_plan
          : diet_plan?.dietPlan || 'General diet advice';

      wellnessBundle.entry[0].resource.section.push({
        title: 'Diet Plan',
        code: {
          coding: [
            {
              system: 'http://snomed.info/sct',
              code: '229065009',
              display: 'Dietary advice',
            },
          ],
        },
        entry: [
          { reference: `urn:uuid:${dietPlanId}`, display: 'Observation' },
        ],
      });

      wellnessBundle.entry.push({
        fullUrl: `urn:uuid:${dietPlanId}`,
        resource: {
          resourceType: 'Observation',
          id: dietPlanId,
          status: 'final',
          code: {
            coding: [
              {
                system: 'http://snomed.info/sct',
                code: '229065009',
                display: 'Dietary advice',
              },
            ],
            text: 'Diet Plan',
          },
          subject: { reference: `urn:uuid:${PatientID}`, display: 'Patient' },
          effectiveDateTime: CurrDate,
          valueString: dietText,
          note: [{ text: dietText }],
        },
      });
    }

    if (treatmentAdvice) {
      let treatmentAdviceId = uuidv4();

      wellnessBundle.entry[0].resource.section.push({
        title: 'Treatment Advice',
        code: {
          coding: [
            {
              system: 'http://snomed.info/sct',
              code: '281094005',
              display: 'Advice about treatment',
            },
          ],
        },
        entry: [
          {
            reference: `urn:uuid:${treatmentAdviceId}`,
            display: 'Observation',
          },
        ],
      });
      wellnessBundle.entry.push({
        fullUrl: `urn:uuid:${treatmentAdviceId}`,
        resource: {
          resourceType: 'Observation',
          id: treatmentAdviceId,
          status: 'final',
          code: {
            coding: [
              {
                system: 'http://snomed.info/sct',
                code: '281094005',
                display: 'Advice about treatment',
              },
            ],
            text: 'Treatment Advice',
          },
          subject: {
            reference: `urn:uuid:${PatientID}`,
            display: 'Patient',
          },
          effectiveDateTime: CurrDate,
          valueString: treatmentAdvice || 'General treatment advice',
        },
      });
    }
    if (prescriptionDetails && prescriptionDetails?.length > 0) {
      const refs: any[] = [];
      const entries: any[] = [];

      prescriptionDetails.forEach((med) => {
        const medId = uuidv4();
        refs.push({ reference: `urn:uuid:${medId}` });

        const medName = cleanText(med.medicineName);
        const medRemarks = cleanText(med.remarks);
        const medInstruction = cleanText(med.instruction, medRemarks);
        const medTiming = cleanText(med.timing);
        const medRoute = cleanText(med.route);
        const medMethod = cleanText(med.method);

        const freq = cleanNumber(med.frequency);
        const duration = cleanNumber(med.duration);
        const durationUnit = cleanText(med.duration_unit);
        const doseValue = cleanNumber(med.dosage);
        const doseUnit = cleanText(med.unit);
        const qtyValue = cleanNumber(med.quantity);
        const qtyUnit = cleanText(med.medicine_type);

        entries.push({
          fullUrl: `urn:uuid:${medId}`,
          resource: {
            resourceType: 'MedicationRequest',
            id: medId,
            status: 'active',
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/MedicationRequest',
              ],
            },
            intent: 'order',

            category: [
              {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/medicationrequest-category',
                    code: 'outpatient',
                    display: 'Outpatient',
                  },
                ],
              },
            ],

            reasonCode: cleanText(med.indication)
              ? [{ text: cleanText(med.indication) }]
              : undefined,

            courseOfTherapyType: cleanNumber(med.duration)
              ? {
                coding: [
                  {
                    system:
                      'http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy',
                    code: 'acute',
                    display: 'Short course (acute)',
                  },
                ],
              }
              : undefined,

            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            authoredOn: CurrDate,
            requester: {
              reference: `urn:uuid:${PractitionerID}`,
              display: doctorDetails.doctorName,
            },
            medicationCodeableConcept: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '1145423002',
                  display: medName,
                },
              ],
              text: medName,
            },

            dosageInstruction: [
              {
                text: medRemarks ?? medInstruction,
                patientInstruction: medInstruction,
                route: medRoute ? { text: medRoute } : undefined,
                method: medMethod ? { text: medMethod } : undefined,
                timing: {
                  repeat: {
                    frequency: freq,
                    period: duration,
                    periodUnit: durationUnit as any,
                    duration: duration,
                    durationUnit: durationUnit as any,
                  },
                  code: { text: medTiming },
                },
                doseAndRate: [
                  {
                    doseQuantity: {
                      value: doseValue,
                      unit: doseUnit,
                    },
                  },
                ],
              },
            ],

            dispenseRequest: {
              quantity: {
                value: qtyValue,
                unit: qtyUnit,
              },
            },

            note: cleanText(med.note)
              ? [{ text: cleanText(med.note) }]
              : undefined,
          },
        });
      });

      wellnessBundle.entry[0].resource.section.push({
        title: 'Medications',
        code: {
          coding: [
            {
              system: 'http://loinc.org',
              code: '10160-0',
              display: 'History of Medication use',
            },
          ],
        },
        entry: refs,
      });

      wellnessBundle.entry.push(...entries);
    }
    if (investigationAdvice && investigationAdvice.length > 0) {
      const refs: any[] = [];
      const entries: any[] = [];

      investigationAdvice.forEach((item: any) => {
        const invName =
          cleanText(
            typeof item === 'string'
              ? item
              : item?.name || item?.investigationName || item?.testName,
          ) || undefined;

        if (!invName) return;

        const srId = uuidv4();

        refs.push({
          reference: `urn:uuid:${srId}`,
          display: invName,
        });

        entries.push({
          fullUrl: `urn:uuid:${srId}`,
          resource: {
            resourceType: 'ServiceRequest',
            id: srId,
            status: 'active',
            intent: 'order',
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            requester: {
              reference: `urn:uuid:${PractitionerID}`,
              display: doctorDetails.doctorName,
            },
            authoredOn: CurrDate,
            code: {
              text: invName,
            },
          },
        });
      });

      if (refs.length) {
        wellnessBundle.entry[0].resource.section.push({
          title: 'Investigation Adviced',
          code: {
            coding: [
              {
                system: 'http://loinc.org',
                code: '30954-2',
                display: 'Relevant diagnostic tests/laboratory data Narrative',
              },
            ],
          },
          entry: refs,
        });

        wellnessBundle.entry.push(...entries);
      }
    }

    const uploadWellnessBody = { value: wellnessBundle };

    const response1 = await axios.post(
      'https://abha-api.plenome.com/file_upload',
      uploadWellnessBody,
    );
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];

    const carecontext_reqbody = {
      abhaAddress: abhaAddress,
      patient_ref_no: await getPatDOB.aayush_unique_id,
      name: await this.normalizeSpaces(await getPatDOB.patient_name),
      gender: await getPatDOB.gender,
      year_of_birth: await yob,
      mobileno: await getPatDOB.mobileno,
      secondary_mobile: await getPatDOB.emergency_mobile_no,
      patient: [
        {
          display: 'OPConsultation Record Linked',
          careContexts: [
            {
              display: 'OPConsultation Record' + formattedDate,
              doc_key: response1.data.data,
            },
          ],

          hiType: 'OPConsultation',
          count: 1,
        },
      ],
    };

    if (
      abhaAddress &&
      abhaAddress.trim() != '' &&
      abhaAddress.toLocaleLowerCase() != 'null'
    ) {
      if (getPatientID.patient_id == checkPatientAbhaAddress.patient_id) {
        const PatientDetails = await patientDetails;
        console.log(checkPatientAbhaAddress, "checkPatientAbhaAddress");

        if (
          checkPatientAbhaAddress.link_token_updated_date &&
          checkPatientAbhaAddress.linkToken
        ) {
          const givenDate = new Date(
            checkPatientAbhaAddress.link_token_updated_date,
          );
          const currentDate = new Date();

          currentDate.setHours(0, 0, 0, 0);
          givenDate.setHours(0, 0, 0, 0);

          const monthDifference =
            (currentDate.getFullYear() - givenDate.getFullYear()) * 12 +
            currentDate.getMonth() -
            givenDate.getMonth();

          if (monthDifference > 5) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };
            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };

            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }
        } else {
          const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
            `select * from patient_abha_address where abhaAddress = ?`,
            [abhaAddress],
          );
          if (!checkPatientAbhaAddress.linkToken && !checkPatientAbhaAddress.link_token_updated_date) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const [getHosHipId] = await this.connection.query(
              `select hip_id from hospitals where plenome_id = ?`,
              [hospital_id],
            );

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };

            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };
            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }

        }
        const existing_link_token: any = await this.getexistingLinkToken(
          hospital_id,
          abhaAddress,
        );

        if (existing_link_token.linkToken) {
          const cc_headers = {
            'X-LINK-TOKEN': await existing_link_token.linkToken,
            'X-HIP-ID': await getHosHipId.hip_id,
            'Content-Type': 'application/json',
          };
          await axios.post(
            'https://abha-api.plenome.com/link/carecontext',
            carecontext_reqbody,
            { headers: cc_headers },
          );
        }
      }
    } else {
      const cc_headers = {
        'X-LINK-TOKEN': 'Temp_linktoken',
        'X-HIP-ID': await getHosHipId.hip_id,
        'Content-Type': 'application/json',
      };
      try {
        await axios.post(
          'https://abha-api.plenome.com/link/carecontext',
          carecontext_reqbody,
          { headers: cc_headers },
        );
        await this.send_sms(
          patientDetails.emergency_mobile_no?.trim() || patientDetails.mobileno,
          getHosHipId.hip_id,
          getHosHipId.hip_name,
        );
      } catch (error) {
        console.log(error, 'error1111');
      }
    }
    return wellnessBundle;
  }

  async createDiagnosis(
    diagnosisDetails: any[],
    hospital_id: any,
    opd_id: any,
    abhaAddress: string,
    file: any,
  ) {
    if (!hospital_id) {
      return {
        status: 'failed',
        message: 'enter hospital_id to post clinical notes',
      };
    }

    const [getPatientID] = await this.dynamicConnection.query(
      `select patient_id from opd_details where id = ?`,
      [opd_id],
    );
    const docs = await this.findAll(await file);

    const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
      `select * from patient_abha_address where abhaAddress = ?`,
      [abhaAddress],
    );

    const [getPatDOB] = await this.dynamicConnection.query(
      `select * from patients where id = ?`,
      [getPatientID.patient_id],
    );

    let yob;
    if (getPatDOB.dob) {
      const [getYob] = await this.dynamicConnection.query(
        `SELECT YEAR(dob) AS year FROM patients where id = ?`,
        [getPatientID.patient_id],
      );
      yob = getYob.year;
    }

    const [patientDetails] = await this.dynamicConnection.query(
      `select patients.id,
      emergency_mobile_no,
      coalesce(patients.patient_name,"-") patientName,
      coalesce(DATE_FORMAT(patients.dob, '%D %b %Y'),"-") dob,
      date(patients.dob) bundleDate,
      coalesce(patients.age,"-") age,
      coalesce(patients.mobileno,"-") mobileno,
      coalesce(patients.email,"-") email,
      coalesce(patients.gender,"-") gender,
      coalesce(patients.abha_address,"-") abha_address,
      coalesce(patients.address,"-") address,
      coalesce(blood_bank_products.name,"-") patient_blood_group 
    from patients 
    left join blood_bank_products 
      on patients.blood_bank_product_id = blood_bank_products.id 
    where patients.id = ?`,
      [getPatientID.patient_id],
    );
    if (patientDetails.gender.toLocaleLowerCase() == 'm' || patientDetails.gender.toLocaleLowerCase() == 'male') {
      patientDetails.gender = 'male';
    } else if (patientDetails.gender.toLocaleLowerCase() == 'f' || patientDetails.gender.toLocaleLowerCase() == 'female') {
      patientDetails.gender = 'female';
    } else {
      patientDetails.gender = 'other';
    }
    const [getDocId] = await this.dynamicConnection.query(
      `select cons_doctor from visit_details where opd_details_id = ?`,
      [opd_id],
    );

    const [doctorDetails] = await this.dynamicConnection.query(
      `select concat(staff.name," ",staff.surname) doctorName,staff.employee_id,staff.gender 
    from staff where id = ?`,
      [getDocId.cons_doctor],
    );

    const bundleDate = new Date(patientDetails.bundleDate);
    const options = {
      year: 'numeric' as const,
      month: '2-digit' as const,
      day: '2-digit' as const,
      hour: '2-digit' as const,
      minute: '2-digit' as const,
      second: '2-digit' as const,
      hourCycle: 'h23' as const,
      timeZone: 'Asia/Kolkata',
    };

    const new_bundle_Date = new Intl.DateTimeFormat('en-CA', options).format(
      bundleDate,
    );
    const [date, time] = new_bundle_Date.split(', ');
    const isoDate = `${date}T${time}`;
    const finaldob = isoDate.split('T')[0];
    patientDetails.bundleDate = finaldob;

    const [getHosDetails] = await this.connection.query(
      `select * from hospitals where plenome_id = ?`,
      [hospital_id],
    );
    const [getHosHipId] = await this.connection.query(
      `select hip_id, hip_name from hospitals where plenome_id = ?`,
      [hospital_id],
    );

    let CurrDate = new Date().toISOString();
    let CompositionID = uuidv4();
    let PractitionerID = uuidv4();
    let PatientID = uuidv4();
    let OrgtID = uuidv4();
    let EncounterID = uuidv4();
    let docRefId = uuidv4();


    let wellnessBundle: any = {
      id: `DiagnosticReport-${uuidv4()}`,
      meta: {
        versionId: '1',
        lastUpdated: CurrDate,
        profile: [
          'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle',
        ],
      },
      resourceType: 'Bundle',
      identifier: {
        system: getHosDetails?.website || 'https://abha-api.plenome.com',
        value: `MR-${patientDetails?.id || uuidv4()}`,
      },
      type: 'document',
      timestamp: CurrDate,
      entry: [
        {
          fullUrl: `urn:uuid:${CompositionID}`,
          resource: {
            id: CompositionID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DiagnosticReportRecord',
              ],
            },
            language: 'en-IN',
            resourceType: 'Composition',
            text: {
              status: 'generated',
              div: '<div xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-IN" lang="en-IN">DiagnosticReport</div>',
            },
            status: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '721981007',
                  display: 'Diagnostic studies report',
                },
              ],
              text: 'Diagnostic studies report',
            },
            encounter: {
              id: EncounterID,
              reference: `urn:uuid:${EncounterID}`,
              display: `OPD-${patientDetails?.id || opd_id}`,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            date: CurrDate,
            author: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: doctorDetails.doctorName || 'Fellow Oncology',
              },
            ],
            title: 'DiagnosticReport',
            custodian: {
              reference: `urn:uuid:${OrgtID}`,
              display: getHosDetails.hospital_name,
            },
            section: [
              {
                title: ' report',
                entry: [],
              },
            ],
          },
        },

        {
          fullUrl: `urn:uuid:${PractitionerID}`,
          resource: {
            id: PractitionerID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Practitioner',
              ],
            },
            resourceType: 'Practitioner',
            text: {
              status: 'generated',
              div: `<div xmlns="http://www.w3.org/1999/xhtml"> Practitioner ${doctorDetails.doctorName || ''
                } </div>`,
            },
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MD',
                      display: 'Medical License number',
                    },
                  ],
                },
                system: getHosDetails?.website || 'https://doctor.ndhm.gov.in',
                value: doctorDetails.employee_id || '21-1521-3828-3227',
              },
            ],
            name: [
              {
                text: `Dr. ${doctorDetails.doctorName}`,
              },
            ],
          },
        },

        {
          fullUrl: `urn:uuid:${PatientID}`,
          resource: {
            id: PatientID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Patient',
              ],
            },
            resourceType: 'Patient',
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'MR',
                      display: 'Medical record number',
                    },
                  ],
                },
                system:
                  getHosDetails?.website || 'https://healthid.ndhm.gov.in',
                value: `MR-${patientDetails?.id || uuidv4()}`,
              },
            ],
            name: [
              {
                use: 'official',
                text: patientDetails.patientName,
                family:
                  patientDetails.patientName.split(' ').slice(1).join(' ') ||
                  patientDetails.patientName,
                given: [
                  patientDetails.patientName.split(' ')[0] ||
                  patientDetails.patientName,
                ],
              },
            ],
            telecom: [
              {
                system: 'phone',
                value: String(patientDetails.mobileno),
                use: 'home',
              },
            ],
            gender: patientDetails.gender?.toLowerCase(),
            birthDate: patientDetails.bundleDate,
          },
        },

        {
          fullUrl: `urn:uuid:${EncounterID}`,
          resource: {
            id: EncounterID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Encounter',
              ],
            },
            resourceType: 'Encounter',
            text: {
              status: 'generated',
              div: '<div xmlns="http://www.w3.org/1999/xhtml"> encounter </div>',
            },
            status: 'arrived',
            class: {
              system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
              code: 'AMB',
              display: 'OPD Visit',
            },
            type: [
              {
                coding: [
                  {
                    system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode',
                    code: 'AMB',
                    display: 'OPD Visit',
                  },
                ],
                text: 'OPD Visit',
              },
            ],
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
          },
        },

        {
          fullUrl: `urn:uuid:${OrgtID}`,
          resource: {
            id: OrgtID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Organization',
              ],
            },
            resourceType: 'Organization',
            text: {
              status: 'generated',
              div: '<div xmlns="http://www.w3.org/1999/xhtml"> Organization </div>',
            },
            identifier: [
              {
                type: {
                  coding: [
                    {
                      system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
                      code: 'PRN',
                      display: 'Provider number',
                    },
                  ],
                },
                system: 'https://healthid.ndhm.gov.in',
                value:
                  String(getHosDetails?.hip_id || getHosDetails?.plenome_id) ||
                  '22-7225-4829-5255',
              },
            ],
            name: getHosDetails.hospital_name,
            telecom: [
              {
                system: 'phone',
                value: getHosDetails.contact_no,
                use: 'work',
              },
              {
                system: 'email',
                value: getHosDetails.email,
                use: 'work',
              },
            ],
          },
        },

        {
          fullUrl: `urn:uuid:${docRefId}`,
          resource: {
            resourceType: 'DocumentReference',
            id: docRefId,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentReference',
              ],
            },
            status: 'current',
            docStatus: 'final',
            type: {
              coding: [
                {
                  system: 'http://snomed.info/sct',
                  code: '4241000179101',
                  display: 'consult note',
                },
              ],
              text: file.split('.')[0],
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: 'Patient',
            },
            content: [
              {
                attachment: {
                  contentType: 'application/pdf',
                  language: 'en-IN',
                  data: docs,
                  title: file.originalname,
                  creation: CurrDate,
                },
              },
            ],
          },
        },
      ],
    };

    if (diagnosisDetails && diagnosisDetails.length > 0) {
      const entries: any[] = [];

      const composition = wellnessBundle.entry[0]?.resource;
      if (!composition.section) {
        composition.section = [];
      } else {
        composition.section = [];
      }

      const SpecimenID = uuidv4();
      const specimenFullUrl = `urn:uuid:${SpecimenID}`;

      entries.push({
        fullUrl: specimenFullUrl,
        resource: {
          id: SpecimenID,
          meta: {
            profile: [
              'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Specimen',
            ],
          },
          resourceType: 'Specimen',
          text: {
            status: 'generated',
            div: '<div xmlns="http://www.w3.org/1999/xhtml"> Specimen </div>',
          },
          type: { text: 'EDTA Blood (3ml)' },
          subject: {
            reference: `urn:uuid:${PatientID}`,
            display: patientDetails.patientName,
          },
          receivedTime: CurrDate,
          collection: { collectedDateTime: CurrDate },
        },
      });

      diagnosisDetails.forEach((diag: any, index: number) => {
        const ObservationID = uuidv4();
        const obsFullUrl = `urn:uuid:${ObservationID}`;

        const testName =
          diag?.panel ||
          diag?.subCategory ||
          diag?.testName ||
          `Diagnostic Report ${index + 1}`;

        entries.push({
          fullUrl: obsFullUrl,
          resource: {
            id: ObservationID,
            meta: {
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/Observation',
              ],
            },
            resourceType: 'Observation',
            text: {
              status: 'generated',
              div: `<div xmlns="http://www.w3.org/1999/xhtml"> ${testName} </div>`,
            },
            status: 'final',
            code: {
              text: testName,
            },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            effectiveDateTime: CurrDate,
            ...(diag?.value != null
              ? {
                valueQuantity: {
                  value: Number(diag.value),
                  unit: diag.unit || '',
                },
              }
              : {}),
            ...(diag?.low != null || diag?.high != null
              ? {
                referenceRange: [
                  {
                    ...(diag?.low != null
                      ? {
                        low: {
                          value: Number(diag.low),
                          unit: diag.unit || '',
                        },
                      }
                      : {}),
                    ...(diag?.high != null
                      ? {
                        high: {
                          value: Number(diag.high),
                          unit: diag.unit || '',
                        },
                      }
                      : {}),
                  },
                ],
              }
              : {}),
            ...(diag?.remarks
              ? { note: [{ text: String(diag.remarks) }] }
              : {}),
          },
        });

        const DiagnosticReportID = uuidv4();
        const drFullUrl = `urn:uuid:${DiagnosticReportID}`;

        entries.push({
          fullUrl: drFullUrl,
          resource: {
            resourceType: 'DiagnosticReport',
            id: DiagnosticReportID,
            meta: {
              versionId: '1',
              lastUpdated: CurrDate,
              profile: [
                'https://nrces.in/ndhm/fhir/r4/StructureDefinition/DiagnosticReportLab',
              ],
            },
            text: {
              status: 'generated',
              div: '<div xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-IN" lang="en-IN">DiagnosticReport</div>',
            },
            status: 'final',
            code: { text: diag.category },
            subject: {
              reference: `urn:uuid:${PatientID}`,
              display: patientDetails.patientName,
            },
            issued: CurrDate,
            resultsInterpreter: [
              {
                reference: `urn:uuid:${PractitionerID}`,
                display: doctorDetails.doctorName || 'Fellow Oncology',
              },
            ],
            specimen: [
              {
                reference: specimenFullUrl,
                display: 'EDTA Blood (3ml)',
              },
            ],
            result: [
              {
                reference: obsFullUrl,
                display: diag.category || testName,
              },
            ],
            conclusion: diag?.remarks
              ? String(diag.remarks)
              : `Comment for ${testName}`,
          },
        });

        composition.section.push({
          title: testName,
          entry: [
            {
              reference: drFullUrl,
              display: `${testName}-Report`,
            },
          ],
        });
      });

      composition.section.push({
        title: 'report',
        entry: [
          {
            reference: `urn:uuid:${docRefId}`,
            display: 'DocumentReference',
          },
        ],
      });

      wellnessBundle.entry.push(...entries);
    }

    const uploadWellnessBody = {
      value: wellnessBundle,
    };

    const response1 = await axios.post(
      'https://abha-api.plenome.com/file_upload',
      uploadWellnessBody,
    );
    const currentDate = new Date();
    const formattedDate = currentDate.toISOString().split('T')[0];
    8;
    const carecontext_reqbody = {
      abhaAddress: abhaAddress,
      patient_ref_no: await getPatDOB.aayush_unique_id,
      name: await this.normalizeSpaces(await getPatDOB.patient_name),
      gender: await getPatDOB.gender,
      year_of_birth: await yob,
      mobileno: await getPatDOB.mobileno,
      secondary_mobile: await getPatDOB.emergency_mobile_no,

      patient: [
        {
          display: 'Diagnostic Report Linked',
          careContexts: [
            {
              display: 'Diagnostic Report' + formattedDate,
              doc_key: response1.data.data,
            },
          ],

          hiType: 'DiagnosticReport',
          count: 1,
        },
      ],
    };
    if (
      abhaAddress &&
      abhaAddress.trim() != '' &&
      abhaAddress.toLocaleLowerCase() != 'null'
    ) {
      if (getPatientID.patient_id == checkPatientAbhaAddress.patient_id) {
        const PatientDetails = await patientDetails;

        if (
          checkPatientAbhaAddress.link_token_updated_date &&
          checkPatientAbhaAddress.linkToken
        ) {
          const givenDate = new Date(
            checkPatientAbhaAddress.link_token_updated_date,
          );
          const currentDate = new Date();

          currentDate.setHours(0, 0, 0, 0);
          givenDate.setHours(0, 0, 0, 0);

          const monthDifference =
            (currentDate.getFullYear() - givenDate.getFullYear()) * 12 +
            currentDate.getMonth() -
            givenDate.getMonth();

          if (monthDifference > 5) {
            const getPatnameBody = {
              abhaAddress: abhaAddress,
            };

            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };
            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };

            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }
        } else {
          const [checkPatientAbhaAddress] = await this.dynamicConnection.query(
            `select * from patient_abha_address where abhaAddress = ?`,
            [abhaAddress],
          );
          if (!checkPatientAbhaAddress.linkToken && !checkPatientAbhaAddress.link_token_updated_date) {
            const getPatnameBody = { abhaAddress: abhaAddress };
            const getname = await axios.post(
              'https://abha-api.plenome.com/m1-abha-address-verification',
              getPatnameBody,
            );

            const PatName = await getname.data.fullName;
            let patGender;
            if (
              PatientDetails.gender.toLocaleLowerCase() == 'male' ||
              PatientDetails.gender.toLocaleLowerCase() == 'm'
            ) {
              patGender = 'M';
            } else if (
              PatientDetails.gender.toLocaleLowerCase() == 'female' ||
              PatientDetails.gender.toLocaleLowerCase() == 'f'
            ) {
              patGender = 'F';
            } else {
              patGender = 'O';
            }

            const [getHosHipId] = await this.connection.query(
              `select hip_id from hospitals where plenome_id = ?`,
              [hospital_id],
            );

            const getLinkTokenBody = {
              name: await PatName,
              gender: await patGender,
              yearOfBirth: await yob,
              abhaAddress: abhaAddress,
            };

            const headers = {
              'X-HIP-ID': await getHosHipId.hip_id,
              'Content-Type': 'application/json',
            };
            const getLinkToken = await axios.post(
              'https://abha-api.plenome.com/hiecm/api/v3/generate-token',
              getLinkTokenBody,
              { headers },
            );

            await this.updateLinkToken(
              hospital_id,
              getLinkToken.data[0].response[0].payload.linkToken,
              abhaAddress,
            );
          }


        }
        const existing_link_token: any = await this.getexistingLinkToken(
          hospital_id,
          abhaAddress,
        );

        if (existing_link_token.linkToken) {
          const cc_headers = {
            'X-LINK-TOKEN': await existing_link_token.linkToken,
            'X-HIP-ID': await getHosHipId.hip_id,
            'Content-Type': 'application/json',
          };
          await axios.post(
            'https://abha-api.plenome.com/link/carecontext',
            carecontext_reqbody,
            { headers: cc_headers },
          );
        }
      }
    } else {
      const cc_headers = {
        'X-LINK-TOKEN': 'Temp_linktoken',
        'X-HIP-ID': await getHosHipId.hip_id,
        'Content-Type': 'application/json',
      };
      try {
        await axios.post(
          'https://abha-api.plenome.com/link/carecontext',
          carecontext_reqbody,
          { headers: cc_headers },
        );

        await this.send_sms(
          patientDetails.emergency_mobile_no?.trim() || patientDetails.mobileno,
          getHosHipId.hip_id,
          getHosHipId.hip_name,
        );
      } catch (error) {
        console.log(error, 'error1111');
      }

    }
    return wellnessBundle;
  }

  async updateLinkToken(
    hospital_id: number,
    token: string,
    abhaAddress: string,
  ) {
    try {
      console.log(token, "a", abhaAddress, "token, abhaAddress");

      await this.dynamicConnection.query(
        `update patient_abha_address set linkToken = ?,
            link_token_updated_date = date(now()) where abhaAddress = ?`,
        [token, abhaAddress],
      );
    } catch (error) {
      console.log(error);
    }
  }

  async getexistingLinkToken(hospital_id: number, abhaAddress: string) {
    try {
      const [existing_link_token] = await this.dynamicConnection.query(
        `select linkToken from patient_abha_address where abhaAddress = ?`,
        [abhaAddress],
      );
      return existing_link_token;
    } catch (error) {
      console.log(error);
    }
  }

  async findAll(value: string) {
    try {
      const s3 = new S3({
        credentials: {
          accessKeyId: awsConfig.accessKeyId,
          secretAccessKey: awsConfig.secretAccessKey,
        },
        region: awsConfig.region,
      });

      const command = new GetObjectCommand({
        Bucket: awsConfig.bucketName,
        Key: value,
      });

      const s3Data = await s3.send(command);

      const buffer = Buffer.from(await s3Data.Body.transformToByteArray());
      return buffer.toString('base64');
    } catch (error) {
      console.error(error);
      return error;
    }
  }

  async findOne(token: any) {
    let transactionNumber: number;

    try {
      transactionNumber = parseInt(token.replace(/[a-zA-Z]/g, ''), 10);
    } catch (error) {
      transactionNumber = parseInt(token);
    }
    const getPatientChargeDetails = await this.dynamicConnection.query(
      `
      select * from patient_charges where transaction_id = ?
      `,
      [transactionNumber],
    );
    if (getPatientChargeDetails.length == 0) {
      return {
        status: 'failed',
        message: 'Unable to fetch Charge Details for the given transaction id',
      };
    }
    return {
      status: 'success',
      message: 'Charge Details Fetched Successfully',
      data: getPatientChargeDetails,
    };
  }

  update(
    id: number,
    updateOpHubBundleGenerationDto: UpdateOpHubBundleGenerationDto,
  ) {
    return `This action updates a #${id} opHubBundleGeneration`;
  }

  async send_sms(mobileno: number, hip_id: string, hip_name: string) {
    const message_req_body = {
      phoneNo: mobileno,
      hipId: hip_id,
      hipName: hip_name,
    };
    const send_message = await axios.post(
      `https://abha-api.plenome.com/notification/sms`,
      message_req_body,
    );
  }
}
