const express = require('express');
const { exec, spawn } = require('child_process');
const path = require('path');
const fs = require('fs');
const axios = require('axios');

const app = express();
app.use(express.json());

class WgetCloner {
  constructor() {
    this.baseOutputDir = path.join(__dirname, '..', 'cloned-sites');
    this.wgetPath = path.join(__dirname, 'wget.exe');
    this.ensureDirectoryExists(this.baseOutputDir);
  }

  ensureDirectoryExists(dirPath) {
    if (!fs.existsSync(dirPath)) {
      fs.mkdirSync(dirPath, { recursive: true });
    }
  }

  sanitizeFilename(filename) {
    return filename.replace(/[<>:"/\\|?*]/g, '_').replace(/\s+/g, '_');
  }

  async checkWget() {
    return new Promise((resolve) => {
      exec('where wget', (error, stdout) => {
        if (error || !stdout) {
          resolve(false);
        } else {
          resolve(true);
        }
      });
    });
  }

  async downloadWget() {
    console.log('📥 Baixando wget para Windows...');
    
    try {
      // URL do wget para Windows (versão portável)
      const wgetUrl = 'https://eternallybored.org/misc/wget/1.21.4/64/wget.exe';
      
      console.log('🔗 Conectando ao servidor...');
      const response = await axios.get(wgetUrl, {
        responseType: 'arraybuffer',
        timeout: 120000,
        maxContentLength: 50 * 1024 * 1024, // 50MB
        onDownloadProgress: (progressEvent) => {
          const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
          process.stdout.write(`\r📦 Baixando: ${percentCompleted}%`);
        }
      });
      
      console.log('\n💾 Salvando arquivo...');
      fs.writeFileSync(this.wgetPath, response.data);
      console.log('✅ wget baixado com sucesso!');
      return true;
    } catch (error) {
      console.error('\n❌ Erro ao baixar wget:', error.message);
      console.log('💡 Você pode baixar manualmente de: https://eternallybored.org/misc/wget/');
      return false;
    }
  }

  async cloneWebsite(url) {
    console.log(`\n${'='.repeat(60)}`);
    console.log(`🚀 CLONAGEM PROFISSIONAL COM WGET`);
    console.log(`${'='.repeat(60)}`);
    console.log(`🌐 URL: ${url}\n`);

    // Sempre usar o wget.exe local primeiro
    let wgetCommand = '/bin/wget'; // Linux system wget
    
    // Verificar se o wget.exe local existe
    if (false) { // bypass wget.exe check
      console.log('⚠️  wget.exe local não encontrado');
      
      // Tentar baixar
      const downloaded = await this.downloadWget();
      if (!downloaded) {
        // Tentar usar wget do sistema como fallback
        const hasWget = await this.checkWget();
        if (hasWget) {
          console.log('✅ Usando wget do sistema');
          wgetCommand = 'wget';
        } else {
          throw new Error('Não foi possível baixar o wget. Instale manualmente: https://eternallybored.org/misc/wget/');
        }
      }
    } else {
      console.log('✅ Usando wget.exe local');
    }

    // Criar diretório para o site
    const urlObj = new URL(url);
    const siteName = this.sanitizeFilename(urlObj.hostname);
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const siteDir = path.join(this.baseOutputDir, `${siteName}_${timestamp}`);
    this.ensureDirectoryExists(siteDir);

    console.log(`📁 Salvando em: ${siteDir}\n`);

    // Argumentos do wget - ABORDAGEM SIMPLES E EFICAZ
    const wgetArgs = [
      '--recursive',                       // Baixar recursivamente
      '--no-clobber',                      // Não sobrescrever arquivos
      '--page-requisites',                 // Baixar CSS, JS, imagens
      '--html-extension',                  // Adicionar .html
      '--convert-links',                   // Converter links para locais
      '--restrict-file-names=windows',     // Nomes compatíveis com Windows
      '--domains=' + urlObj.hostname,      // Apenas este domínio
      '--no-parent',                       // Não subir diretórios
      '--no-check-certificate',            // Ignorar SSL
      '-e', 'robots=off',                  // Ignorar robots.txt
      `-P`, siteDir,                       // Diretório de saída
      url
    ];

    return new Promise((resolve, reject) => {
      console.log('🔄 Iniciando clonagem...\n');
      
      const wgetProcess = spawn(wgetCommand, wgetArgs, {
        cwd: this.baseOutputDir,
        shell: true
      });

      let output = '';
      let errorOutput = '';

      wgetProcess.stdout.on('data', (data) => {
        const text = data.toString();
        output += text;
        
        // Mostrar progresso
        const lines = text.split('\n');
        lines.forEach(line => {
          if (line.includes('%') || line.includes('saved') || line.includes('=>')) {
            console.log(`  ${line.trim()}`);
          }
        });
      });

      wgetProcess.stderr.on('data', (data) => {
        const text = data.toString();
        errorOutput += text;
        
        // Mostrar erros importantes
        if (text.includes('ERROR') || text.includes('failed')) {
          console.log(`  ⚠️  ${text.trim()}`);
        }
      });

      wgetProcess.on('close', (code) => {
        console.log(`\n${'='.repeat(60)}`);
        
        if (code === 0 || code === 8) { // 8 = alguns arquivos falharam, mas ok
          console.log(`✅ CLONAGEM CONCLUÍDA!`);
          console.log(`${'='.repeat(60)}`);
          console.log(`📁 Localização: ${siteDir}`);
          
          // Baixar imagens faltantes manualmente
          console.log(`\n🔍 Verificando imagens faltantes...`);
          this.downloadMissingImages(siteDir, url).then(() => {
            console.log(`🌐 Abra o arquivo index.html no navegador`);
            console.log(`${'='.repeat(60)}\n`);
          });

          // Criar arquivo de informações
          const info = {
            originalUrl: url,
            clonedAt: new Date().toISOString(),
            directory: siteDir,
            method: 'wget',
            success: true
          };

          fs.writeFileSync(
            path.join(siteDir, 'clone-info.json'),
            JSON.stringify(info, null, 2)
          );

          // Criar arquivo .bat para abrir
          const indexPath = this.findIndexFile(siteDir);
          if (indexPath) {
            fs.writeFileSync(
              path.join(siteDir, 'abrir-site.bat'),
              `@echo off\nstart "" "${indexPath}"`
            );
          }

          resolve({
            url: url,
            success: true,
            directory: siteDir,
            method: 'wget',
            exitCode: code,
            cloneInfo: info
          });
        } else {
          console.log(`❌ ERRO NA CLONAGEM (código: ${code})`);
          console.log(`${'='.repeat(60)}\n`);
          
          reject(new Error(`wget falhou com código ${code}\n${errorOutput}`));
        }
      });

      wgetProcess.on('error', (error) => {
        console.error(`❌ Erro ao executar wget: ${error.message}`);
        reject(error);
      });
    });
  }

  async downloadMissingImages(siteDir, baseUrl) {
    try {
      const indexPath = path.join(siteDir, 'index.html');
      if (!fs.existsSync(indexPath)) return;

      const html = fs.readFileSync(indexPath, 'utf8');
      
      // Procurar por todas as referências de imagens
      const imagePatterns = [
        /background-image="([^"]+)"/g,
        /src="([^"]+\.(jpg|jpeg|png|gif|webp|svg))"/gi,
        /href="([^"]+\.(jpg|jpeg|png|gif|webp|svg))"/gi,
      ];

      const imagesToDownload = new Set();
      
      for (const pattern of imagePatterns) {
        let match;
        while ((match = pattern.exec(html)) !== null) {
          const imagePath = match[1];
          if (imagePath.startsWith('/ws/') || imagePath.startsWith('ws/')) {
            imagesToDownload.add(imagePath.replace(/^\//, ''));
          }
        }
      }

      console.log(`📦 Encontradas ${imagesToDownload.size} referências de imagens`);

      let downloaded = 0;
      for (const imagePath of imagesToDownload) {
        const localPath = path.join(siteDir, imagePath);
        
        // Se já existe, pular
        if (fs.existsSync(localPath)) continue;

        // Criar diretório se não existir
        const dir = path.dirname(localPath);
        if (!fs.existsSync(dir)) {
          fs.mkdirSync(dir, { recursive: true });
        }

        // Baixar imagem
        try {
          const urlObj = new URL(baseUrl);
          const imageUrl = `${urlObj.protocol}//${urlObj.hostname}/${imagePath}`;
          
          console.log(`  📥 Baixando: ${imagePath}`);
          const response = await axios.get(imageUrl, {
            responseType: 'arraybuffer',
            timeout: 30000,
            headers: {
              'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            }
          });

          fs.writeFileSync(localPath, response.data);
          downloaded++;
        } catch (error) {
          console.log(`  ⚠️  Falha ao baixar: ${imagePath}`);
        }
      }

      console.log(`✅ ${downloaded} imagens adicionais baixadas`);
    } catch (error) {
      console.log(`⚠️  Erro ao baixar imagens faltantes: ${error.message}`);
    }
  }

  findIndexFile(directory) {
    // Procurar por index.html recursivamente
    const findIndex = (dir) => {
      const files = fs.readdirSync(dir);
      
      for (const file of files) {
        const fullPath = path.join(dir, file);
        const stat = fs.statSync(fullPath);
        
        if (stat.isDirectory()) {
          const found = findIndex(fullPath);
          if (found) return found;
        } else if (file === 'index.html') {
          return fullPath;
        }
      }
      
      return null;
    };

    return findIndex(directory);
  }
}

// API
app.post('/wget-clone', async (req, res) => {
  try {
    const { url } = req.body;
    if (!url) {
      return res.status(400).json({ error: 'URL obrigatória' });
    }

    const cloner = new WgetCloner();
    const result = await cloner.cloneWebsite(url);
    
    res.json({ success: true, data: result });
  } catch (error) {
    console.error('❌ Erro:', error.message);
    res.status(500).json({ success: false, error: error.message });
  }
});

app.get('/health', (req, res) => {
  res.json({ status: 'ok', service: 'wget-cloner' });
});

app.listen(3002, () => {
  console.log('\n' + '='.repeat(60));
  console.log('🌐 WGET Cloner - Clonagem Profissional de Sites');
  console.log('='.repeat(60));
  console.log('📡 Rodando em: http://localhost:3002');
  console.log('✅ Clonagem de alta fidelidade com wget');
  console.log('='.repeat(60) + '\n');
});
