// ========================================
// DIGITAL OCEAN TEMPLATES - RÉCUPÉRATION XML
// Responsabilité: Récupération et cache des templates XML depuis DigitalOcean Spaces
// ========================================

require('dotenv').config();
const { logSh } = require('../ErrorReporting');
const { tracer } = require('../trace');
const fs = require('fs').promises;
const path = require('path');
const axios = require('axios');
const AWS = require('aws-sdk');

/**
 * DIGITAL OCEAN TEMPLATES MANAGER
 * Gestion récupération, cache et fallback des templates XML
 */
class DigitalOceanTemplates {

  constructor() {
    this.cacheDir = path.join(__dirname, '../../cache/templates');

    // Extraire bucket du endpoint si présent (ex: https://autocollant.fra1.digitaloceanspaces.com)
    let endpoint = process.env.DO_ENDPOINT || process.env.DO_SPACES_ENDPOINT || 'https://fra1.digitaloceanspaces.com';
    let bucket = process.env.DO_BUCKET_NAME || process.env.DO_SPACES_BUCKET || 'autocollant';

    // Si endpoint contient le bucket, le retirer
    if (endpoint.includes(`${bucket}.`)) {
      endpoint = endpoint.replace(`${bucket}.`, '');
    }

    this.config = {
      endpoint: endpoint,
      bucket: bucket,
      region: process.env.DO_REGION || process.env.DO_SPACES_REGION || 'fra1',
      accessKey: process.env.DO_ACCESS_KEY_ID || process.env.DO_SPACES_KEY,
      secretKey: process.env.DO_SECRET_ACCESS_KEY || process.env.DO_SPACES_SECRET,
      timeout: 10000 // 10 secondes
    };

    // Cache en mémoire
    this.memoryCache = new Map();
    this.cacheExpiry = 5 * 60 * 1000; // 5 minutes

    // Templates par défaut
    this.defaultTemplates = {
      'default.xml': this.getDefaultTemplate(),
      'simple.xml': this.getSimpleTemplate(),
      'advanced.xml': this.getAdvancedTemplate()
    };

    this.initializeTemplateManager();
  }

  /**
   * Initialise le gestionnaire de templates
   */
  async initializeTemplateManager() {
    try {
      // Créer le dossier cache
      await fs.mkdir(this.cacheDir, { recursive: true });

      // Vérifier la configuration DO
      this.checkConfiguration();

      logSh('🌊 DigitalOceanTemplates initialisé', 'DEBUG');

    } catch (error) {
      logSh(`❌ Erreur initialisation DigitalOceanTemplates: ${error.message}`, 'ERROR');
    }
  }

  /**
   * Vérifie la configuration Digital Ocean
   */
  checkConfiguration() {
    const hasCredentials = this.config.accessKey && this.config.secretKey;

    if (!hasCredentials) {
      logSh('⚠️ Credentials Digital Ocean manquantes, utilisation cache/fallback uniquement', 'WARNING');
    } else {
      logSh('✅ Configuration Digital Ocean OK', 'DEBUG');
    }

    return hasCredentials;
  }

  // ========================================
  // RÉCUPÉRATION TEMPLATES
  // ========================================

  /**
   * Récupère un template XML (avec cache et fallback)
   */
  async getTemplate(filename) {
    return tracer.run('DigitalOceanTemplates.getTemplate', async () => {
      if (!filename) {
        throw new Error('Nom de fichier template requis');
      }

      logSh(`📋 Récupération template: ${filename}`, 'DEBUG');

      try {
        // 1. Vérifier le cache mémoire
        const memoryCached = this.getFromMemoryCache(filename);
        if (memoryCached) {
          logSh(`⚡ Template ${filename} trouvé en cache mémoire`, 'DEBUG');
          return memoryCached;
        }

        // 2. Vérifier le cache fichier
        const fileCached = await this.getFromFileCache(filename);
        if (fileCached) {
          logSh(`💾 Template ${filename} trouvé en cache fichier`, 'DEBUG');
          this.setMemoryCache(filename, fileCached);
          return fileCached;
        }

        // 3. Récupérer depuis Digital Ocean
        if (this.checkConfiguration()) {
          try {
            const template = await this.fetchFromDigitalOcean(filename);
            if (template) {
              logSh(`🌊 Template ${filename} récupéré depuis Digital Ocean`, 'INFO');

              // Sauvegarder en cache
              await this.saveToFileCache(filename, template);
              this.setMemoryCache(filename, template);

              return template;
            }
          } catch (doError) {
            logSh(`⚠️ Erreur Digital Ocean pour ${filename}: ${doError.message}`, 'WARNING');
          }
        }

        // 4. Fallback sur template par défaut
        const defaultTemplate = this.getDefaultTemplateForFile(filename);
        logSh(`🔄 Utilisation template par défaut pour ${filename}`, 'WARNING');

        return defaultTemplate;

      } catch (error) {
        logSh(`❌ Erreur récupération template ${filename}: ${error.message}`, 'ERROR');

        // Fallback ultime
        return this.getDefaultTemplate();
      }
    });
  }

  /**
   * Récupère depuis Digital Ocean Spaces
   */
  async fetchFromDigitalOcean(filename) {
    return tracer.run('DigitalOceanTemplates.fetchFromDigitalOcean', async () => {
      const fileKey = `wp-content/XML/${filename}`;

      logSh(`🌊 Récupération DO avec authentification S3: ${fileKey}`, 'DEBUG');

      try {
        // Configuration S3 pour Digital Ocean Spaces
        const s3 = new AWS.S3({
          endpoint: this.config.endpoint,
          accessKeyId: this.config.accessKey,
          secretAccessKey: this.config.secretKey,
          region: this.config.region,
          s3ForcePathStyle: false,
          signatureVersion: 'v4'
        });

        const params = {
          Bucket: this.config.bucket,
          Key: fileKey
        };

        logSh(`🔑 S3 getObject: bucket=${this.config.bucket}, key=${fileKey}`, 'DEBUG');

        const data = await s3.getObject(params).promise();
        const template = data.Body.toString('utf-8');

        logSh(`✅ Template ${filename} récupéré depuis DO (${template.length} chars)`, 'INFO');
        return template;

      } catch (error) {
        logSh(`❌ Digital Ocean S3 error: ${error.message} (code: ${error.code})`, 'WARNING');
        throw error;
      }
    });
  }

  // ========================================
  // GESTION CACHE
  // ========================================

  /**
   * Récupère depuis le cache mémoire
   */
  getFromMemoryCache(filename) {
    const cached = this.memoryCache.get(filename);

    if (cached && Date.now() - cached.timestamp < this.cacheExpiry) {
      return cached.content;
    }

    if (cached) {
      this.memoryCache.delete(filename);
    }

    return null;
  }

  /**
   * Sauvegarde en cache mémoire
   */
  setMemoryCache(filename, content) {
    this.memoryCache.set(filename, {
      content,
      timestamp: Date.now()
    });
  }

  /**
   * Récupère depuis le cache fichier
   */
  async getFromFileCache(filename) {
    try {
      const cachePath = path.join(this.cacheDir, filename);
      const stats = await fs.stat(cachePath);

      // Cache valide pendant 1 heure
      const maxAge = 60 * 60 * 1000;
      if (Date.now() - stats.mtime.getTime() < maxAge) {
        const content = await fs.readFile(cachePath, 'utf8');
        return content;
      }
    } catch (error) {
      // Fichier cache n'existe pas ou erreur
    }

    return null;
  }

  /**
   * Sauvegarde en cache fichier
   */
  async saveToFileCache(filename, content) {
    try {
      const cachePath = path.join(this.cacheDir, filename);
      await fs.writeFile(cachePath, content, 'utf8');
      logSh(`💾 Template ${filename} sauvé en cache`, 'DEBUG');
    } catch (error) {
      logSh(`⚠️ Erreur sauvegarde cache ${filename}: ${error.message}`, 'WARNING');
    }
  }

  // ========================================
  // TEMPLATES PAR DÉFAUT
  // ========================================

  /**
   * Retourne le template par défaut approprié
   */
  getDefaultTemplateForFile(filename) {
    const lowerFilename = filename.toLowerCase();

    if (lowerFilename.includes('simple')) {
      return this.defaultTemplates['simple.xml'];
    } else if (lowerFilename.includes('advanced') || lowerFilename.includes('complet')) {
      return this.defaultTemplates['advanced.xml'];
    }

    return this.defaultTemplates['default.xml'];
  }

  /**
   * Template par défaut standard
   */
  getDefaultTemplate() {
    return `<?xml version='1.0' encoding='UTF-8'?>
<article>
  <h1>|Titre_Principal{{T0}}{Rédige un titre H1 accrocheur de maximum 10 mots pour {{MC0}}. Style {{personality.style}}}|</h1>

  <intro>|Introduction{{MC0}}{Rédige une introduction engageante de 2-3 phrases qui présente {{MC0}} et donne envie de lire la suite. Ton {{personality.style}}}|</intro>

  <section>
    <h2>|Titre_H2_1{{MC+1_1}}{Crée un titre H2 informatif sur {{MC+1_1}}. Style {{personality.style}}}|</h2>
    <p>|Paragraphe_1{{MC+1_1}}{Rédige un paragraphe détaillé de 4-5 phrases sur {{MC+1_1}}. Explique les avantages et caractéristiques. Ton {{personality.style}}}|</p>
  </section>

  <section>
    <h2>|Titre_H2_2{{MC+1_2}}{Crée un titre H2 informatif sur {{MC+1_2}}. Style {{personality.style}}}|</h2>
    <p>|Paragraphe_2{{MC+1_2}}{Rédige un paragraphe détaillé de 4-5 phrases sur {{MC+1_2}}. Explique les avantages et caractéristiques. Ton {{personality.style}}}|</p>
  </section>

  <conclusion>|Conclusion{{MC0}}{Conclusion engageante de 2 phrases sur {{MC0}}. Appel à l'action subtil. Ton {{personality.style}}}|</conclusion>
</article>`;
  }

  /**
   * Template simple
   */
  getSimpleTemplate() {
    return `<?xml version='1.0' encoding='UTF-8'?>
<article>
  <h1>|Titre_H1{{T0}}{Titre principal pour {{MC0}}}|</h1>
  <intro>|Introduction{{MC0}}{Introduction pour {{MC0}}}|</intro>
  <content>|Contenu_Principal{{MC0}}{Contenu principal sur {{MC0}}}|</content>
  <conclusion>|Conclusion{{MC0}}{Conclusion sur {{MC0}}}|</conclusion>
</article>`;
  }

  /**
   * Template avancé
   */
  getAdvancedTemplate() {
    return `<?xml version='1.0' encoding='UTF-8'?>
<article>
  <h1>|Titre_Principal{{T0}}{Rédige un titre H1 accrocheur de maximum 10 mots pour {{MC0}}. Style {{personality.style}}}|</h1>

  <intro>|Introduction{{MC0}}{Rédige une introduction engageante de 2-3 phrases qui présente {{MC0}} et donne envie de lire la suite. Ton {{personality.style}}}|</intro>

  <section>
    <h2>|Titre_H2_1{{MC+1_1}}{Crée un titre H2 informatif sur {{MC+1_1}}. Style {{personality.style}}}|</h2>
    <p>|Paragraphe_1{{MC+1_1}}{Rédige un paragraphe détaillé de 4-5 phrases sur {{MC+1_1}}. Explique les avantages et caractéristiques. Ton {{personality.style}}}|</p>
  </section>

  <section>
    <h2>|Titre_H2_2{{MC+1_2}}{Crée un titre H2 informatif sur {{MC+1_2}}. Style {{personality.style}}}|</h2>
    <p>|Paragraphe_2{{MC+1_2}}{Rédige un paragraphe détaillé de 4-5 phrases sur {{MC+1_2}}. Explique les avantages et caractéristiques. Ton {{personality.style}}}|</p>
  </section>

  <section>
    <h2>|Titre_H2_3{{MC+1_3}}{Crée un titre H2 informatif sur {{MC+1_3}}. Style {{personality.style}}}|</h2>
    <p>|Paragraphe_3{{MC+1_3}}{Explique en 4-5 phrases les avantages de {{MC+1_3}} pour {{MC0}}. Ton {{personality.style}}}|</p>
  </section>

  <faq>
    <h2>|FAQ_Titre{Titre de section FAQ accrocheur sur {{MC0}}}|</h2>

    <question>
      <q>|Faq_q_1{{MC+1_1}}{Question fréquente sur {{MC+1_1}} et {{MC0}}}|</q>
      <a>|Faq_a_1{{MC+1_1}}{Réponse claire et précise. 2-3 phrases. Ton {{personality.style}}}|</a>
    </question>

    <question>
      <q>|Faq_q_2{{MC+1_2}}{Question pratique sur {{MC+1_2}} en lien avec {{MC0}}}|</q>
      <a>|Faq_a_2{{MC+1_2}}{Réponse détaillée et utile. 2-3 phrases explicatives. Ton {{personality.style}}}|</a>
    </question>

    <question>
      <q>|Faq_q_3{{MC+1_3}}{Question sur {{MC+1_3}} que se posent les clients}|</q>
      <a>|Faq_a_3{{MC+1_3}}{Réponse complète qui rassure et informe. 2-3 phrases. Ton {{personality.style}}}|</a>
    </question>
  </faq>

  <conclusion>|Conclusion{{MC0}}{Conclusion engageante de 2 phrases sur {{MC0}}. Appel à l'action subtil. Ton {{personality.style}}}|</conclusion>
</article>`;
  }

  // ========================================
  // UTILITAIRES
  // ========================================

  /**
   * Liste les templates disponibles
   */
  async listAvailableTemplates() {
    const templates = [];

    // Templates par défaut
    Object.keys(this.defaultTemplates).forEach(name => {
      templates.push({
        name,
        source: 'default',
        cached: true
      });
    });

    // Templates en cache
    try {
      const cacheFiles = await fs.readdir(this.cacheDir);
      cacheFiles.forEach(file => {
        if (file.endsWith('.xml')) {
          templates.push({
            name: file,
            source: 'cache',
            cached: true
          });
        }
      });
    } catch (error) {
      // Dossier cache n'existe pas
    }

    return templates;
  }

  /**
   * Vide le cache
   */
  async clearCache() {
    try {
      // Vider cache mémoire
      this.memoryCache.clear();

      // Vider cache fichier
      const cacheFiles = await fs.readdir(this.cacheDir);
      for (const file of cacheFiles) {
        if (file.endsWith('.xml')) {
          await fs.unlink(path.join(this.cacheDir, file));
        }
      }

      logSh('🗑️ Cache templates vidé', 'INFO');

    } catch (error) {
      logSh(`❌ Erreur vidage cache: ${error.message}`, 'ERROR');
    }
  }

  /**
   * Retourne les statistiques du cache
   */
  getCacheStats() {
    return {
      memoryCache: {
        size: this.memoryCache.size,
        expiry: this.cacheExpiry
      },
      config: {
        hasCredentials: this.checkConfiguration(),
        endpoint: this.config.endpoint,
        bucket: this.config.bucket,
        timeout: this.config.timeout
      },
      defaultTemplates: Object.keys(this.defaultTemplates).length
    };
  }
}

// ============= EXPORTS =============
module.exports = { DigitalOceanTemplates };