import { Injectable } from '@nestjs/common';
import { CreateDownloadfileDto } from './dto/create-downloadfile.dto';
import { UpdateDownloadfileDto } from './dto/update-downloadfile.dto';
import { NotifyService } from 'src/services/notify/notify.service';
import { EntityManager } from 'typeorm';
import { TypedocumentService } from '../typedocument/typedocument.service';
import * as SftpClient from 'ssh2-sftp-client';
import * as path from 'path';
import * as fs from 'fs/promises';
import { LoggerService } from 'src/logger/logger.service';

@Injectable()
export class DownloadfileService {

   private sftp = new SftpClient();
    private fileLignes: any[] = [];
    
    constructor( 
      private readonly typeDocService: TypedocumentService,
      private readonly logger: LoggerService,
      private readonly notifyServce: NotifyService,
      private readonly entityManager: EntityManager
    ){}
    
  
    
    async remoteProcessFile(): Promise<any> {
      this.logger.log('------------------------------------------------- DEBUT TRAITEMENT ----------------------------------------------------');
  
      const config = {
        host: process.env.SFTP_HOST,
        port: parseInt(process.env.SFTP_PORT || '22', 10),
        username: process.env.SFTP_USERNAME,
        password: process.env.SFTP_PASSWORD,
      };
  
      try {
        // Connexion SFTP une seule fois
        await this.sftp.connect(config);
        this.logger.log(`Connexion SFTP réussie vers ${config.host}`);
  
        const typeDocs = await this.typeDocService.findAll();
        const todayFolder = '/20250901'; // + new Date().toISOString().slice(0, 10).replace(/-/g, '');
  
        for (const typeDoc of typeDocs) {
          const remotePath = `${process.env.remotePath}${typeDoc.code}${todayFolder}`;
          const localPath  = `${process.env.localPath}${typeDoc.code}${todayFolder}`;
  
          // Vérifier si le répertoire existe sur le SFTP
          const exists = await this.sftp.exists(remotePath);
  
          if (!exists || exists !== 'd') {
            this.logger.warn(`⚠️ Répertoire introuvable : ${remotePath} — Passage au suivant`);
            continue;
          }
  
          const downloadedFiles: string[] = [];
  
          await fs.mkdir(localPath, { recursive: true });
  
          await this.downloadDirRecursive(
            this.sftp,
            remotePath,
            localPath,
            downloadedFiles,
            typeDoc.id
          );
  
          this.logger.log(`📥 ${downloadedFiles.length} fichiers téléchargés pour ${typeDoc.libelle}`);
  
          const jsonOutputPath = `public/amplitude_docs/files.json`;
          await this.saveFilePathsToJson(downloadedFiles, jsonOutputPath);
        }
  
        this.logger.log('------------------------------------------------- FIN TRAITEMENT ----------------------------------------------------');
        return 'successful';
  
      } catch (err) {
        this.logger.error('❌ Erreur SFTP: ' + err);
        return err;
      } finally {
        await this.sftp.end();
      }
    }
  
  
  
  
    /**
     * Télécharge récursivement et collecte tous les chemins absolus
     */
    private async downloadDirRecursive(
      sftp: SftpClient,
      remotePath: string,
      localPath: string,
      downloadedFiles: any[],
      typeDocId: number
    ): Promise<void> {
      const list = await sftp.list(remotePath);
  
      for (const item of list) {
        const remoteFilePath = `${remotePath}/${item.name}`;
        const localFilePath = path.join(localPath, item.name);
  
        if (item.type === 'd') {
          // C'est un répertoire
          await fs.mkdir(localFilePath, { recursive: true });
          await this.downloadDirRecursive(
            sftp,
            remoteFilePath,
            localFilePath,
            downloadedFiles,
            typeDocId
          );
        } else {
          // C'est un fichier
          await sftp.get(remoteFilePath, localFilePath);
  
          // Ajouter le chemin absolu au tableau
          //const absolutePath = path.resolve(localFilePath);
          const absolutePath = localFilePath;
          downloadedFiles.push({typeDocId, path: absolutePath});
  
          this.logger.debug(`Fichier téléchargé: ${item.name}`);
        }
      }
    }
  
    /**
     * Sauvegarde les chemins dans un fichier JSON
     */
    private async saveFilePathsToJson(
      filePaths: string[],
      outputPath: string,
    ): Promise<void> {
      try {
        const data = {
          timestamp: new Date().toISOString(),
          totalFiles: filePaths.length,
          files: filePaths,
        };
  
        // Créer le répertoire parent si nécessaire
        await fs.mkdir(path.dirname(outputPath), { recursive: true });
  
        await fs.writeFile(outputPath, JSON.stringify(data, null, 2), 'utf-8');
        this.logger.log(`✅ Chemins sauvegardés dans: ${outputPath}`);
      } catch (error) {
        this.logger.error('❌ Erreur lors de la sauvegarde JSON:', error.message);
        throw error;
      }
    }
  
    /**
     * Sauvegarde les chemins dans un fichier texte
     */
    private async saveFilePathsToTxt(
      filePaths: string[],
      outputPath: string,
    ): Promise<void> {
      try {
        const content = filePaths.join('\n');
  
        // Créer le répertoire parent si nécessaire
        await fs.mkdir(path.dirname(outputPath), { recursive: true });
  
        await fs.writeFile(outputPath, content, 'utf-8');
        this.logger.log(`✅ Chemins sauvegardés dans: ${outputPath}`);
      } catch (error) {
        this.logger.error('❌ Erreur lors de la sauvegarde TXT:', error.message);
        throw error;
      }
    }

}
