import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/typeorm';
import { Connection } from 'typeorm';
import { PatientRecord } from './entities/patient_record.entity';
import { S3Client, GetObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
import { awsConfig } from 'src/aws.config';
import { Readable } from 'stream';

@Injectable()
export class PatientRecordsService {
  private s3Client: S3Client;

  constructor(@InjectConnection() private connection: Connection) {
    // Initialize the S3 client
    this.s3Client = new S3Client({
      credentials: {
        accessKeyId: awsConfig.accessKeyId,
        secretAccessKey: awsConfig.secretAccessKey,
      },
      region: awsConfig.region,
    });
  }

  async create(recordEntity: PatientRecord, file: any) {
    console.log('entered create', recordEntity.patient_id,
      recordEntity.record_name,
      recordEntity.record_type_id,
      JSON.stringify(recordEntity.files),"oooo",
      JSON.stringify(recordEntity.tags));


    const recordEnter = await this.connection.query(
      `insert into patient_records (patient_id, record_name, record_type_id, files, tags) values(?,?,?,?,?)`,
      [
        recordEntity.patient_id,
        recordEntity.record_name,
        recordEntity.record_type_id,
        JSON.stringify(recordEntity.files),
        JSON.stringify(recordEntity.tags),
      ],
    );
    console.log(recordEnter, 'recordEnter');

    return [
      {
        status: 'success',
        messege: 'Patient record uploaded successfully',
      },
    ];
  }

  async getDOC(key: string) {
    console.log(key,"asdfadsf");
    
    const s3Params = {
      Bucket: awsConfig.bucketName,
      Key: key,
    };

    try {
      const data = await this.s3Client.send(new GetObjectCommand(s3Params));
      const stream = data.Body as Readable;
      const chunks: any[] = [];
      for await (const chunk of stream) {
        chunks.push(chunk);
      }
      const buffer = Buffer.concat(chunks);
      return buffer.toString('base64');
    } catch (error) {
      console.error('Error fetching file from S3:', error);
      throw new Error('Could not fetch file from S3');
    }
  }

  async delDOC(key: string) {
    const s3Params = {
      Bucket: awsConfig.bucketName,
      Key: key,
    };

    try {
      const s3Data = await this.s3Client.send(new DeleteObjectCommand(s3Params));
      return s3Data;
    } catch (error) {
      console.error('Error deleting file from S3:', error);
      throw new Error('Could not delete file from S3');
    }
  }

  async findOne(id: number) {
    const getAllRecords = await this.connection.query(
      `select * from patient_records where patient_id = ?`,
      [id],
    );

    // Fetch files from S3 for each record
    const recordsWithData = await Promise.all(
      getAllRecords.map(async (record: any) => {
        try {
          const s3Data = await this.getDOC(JSON.parse(record.files));
          console.log(s3Data, 's3Data');

          // Add the file data to the record
          console.log(record, 'recordrecordrecord');

          return { ...record, fileData: s3Data };
        } catch (error) {
          console.error('Error fetching file data from S3:', error);
          // Handle error if needed
          return { ...record, fileData: null }; // Return null for the file data in case of an error
        }
      }),
    );

    return recordsWithData;
  }

  async findByType(id: number, type_id: number) {
    console.log('aabbccdd');

    const getAllRecords = await this.connection.query(
      `select * from patient_records where patient_id = ? and record_type_id = ?`,
      [id, type_id],
    );
    const recordsWithData = await Promise.all(
      getAllRecords.map(async (record: any) => {
        try {
          const s3Data = await this.getDOC(JSON.parse(record.files));

          // Add the file data to the record
          console.log(record, 'recordrecordrecord');

          return { ...record, fileData: s3Data };
        } catch (error) {
          console.error('Error fetching file data from S3:', error);
          // Handle error if needed
          return { ...record, fileData: null }; // Return null for the file data in case of an error
        }
      }),
    );

    return recordsWithData;
  }

  async remove(id: number) {
    const [getRec] = await this.connection.query(
      `select * from patient_records where id = ?`,
      [id],
    );
    if (getRec) {
      const s3Key = JSON.parse(getRec.files);
      const a = await this.delDOC(s3Key);
      console.log(a, 'aaaa');

      const delRecords = await this.connection.query(
        `delete from patient_records where id = ?`,
        [id],
      );
      return `This record number #${id} in patientRecord is deleted successfully.`;
    } else {
      return 'This Record does not Exist';
    }
  }
}
