/**
 * CloneWeb Storage Manager
 * Gerencia versões, metadados e storage dos sites clonados
 */

const fs = require('fs');
const path = require('path');
const express = require('express');
const router = express.Router();

const BASE_DIR = '/app/cloned-sites';
const METADATA_FILE = 'clone-metadata.json';

/**
 * Get all clones with their metadata
 */
function getAllClones() {
    const clones = [];
    
    if (!fs.existsSync(BASE_DIR)) {
        return clones;
    }
    
    const dirs = fs.readdirSync(BASE_DIR).filter(f => {
        return fs.statSync(path.join(BASE_DIR, f)).isDirectory();
    });
    
    for (const dir of dirs) {
        const clonePath = path.join(BASE_DIR, dir);
        const metadata = loadMetadata(clonePath);
        const cloneInfo = loadCloneInfo(clonePath);
        const stats = getCloneStats(clonePath);
        
        // Extract base URL from directory name
        const baseUrl = extractBaseUrl(dir);
        
        clones.push({
            id: dir,
            directory: dir,
            baseUrl,
            path: clonePath,
            metadata: metadata || {},
            cloneInfo: cloneInfo || {},
            stats,
            versions: listVersions(clonePath)
        });
    }
    
    // Sort by most recent
    clones.sort((a, b) => {
        const dateA = new Date(a.cloneInfo.clonedAt || a.metadata.createdAt || 0);
        const dateB = new Date(b.cloneInfo.clonedAt || b.metadata.createdAt || 0);
        return dateB - dateA;
    });
    
    return clones;
}

function loadMetadata(clonePath) {
    const metaFile = path.join(clonePath, METADATA_FILE);
    if (fs.existsSync(metaFile)) {
        try {
            return JSON.parse(fs.readFileSync(metaFile, 'utf8'));
        } catch (e) {
            return null;
        }
    }
    return null;
}

function loadCloneInfo(clonePath) {
    const infoFile = path.join(clonePath, 'clone-info.json');
    if (fs.existsSync(infoFile)) {
        try {
            return JSON.parse(fs.readFileSync(infoFile, 'utf8'));
        } catch (e) {
            return null;
        }
    }
    return null;
}

function getCloneStats(clonePath) {
    let totalSize = 0;
    let fileCount = 0;
    
    function countFiles(dir) {
        if (!fs.existsSync(dir)) return;
        
        const items = fs.readdirSync(dir);
        for (const item of items) {
            const itemPath = path.join(dir, item);
            const stat = fs.statSync(itemPath);
            
            if (stat.isDirectory()) {
                // Skip cloned-sites subdirectory
                if (!item.includes('cloned-sites')) {
                    countFiles(itemPath);
                }
            } else {
                totalSize += stat.size;
                fileCount++;
            }
        }
    }
    
    countFiles(clonePath);
    
    return {
        totalSize,
        fileCount,
        formattedSize: formatBytes(totalSize)
    };
}

function listVersions(clonePath) {
    const versions = [];
    const versionsDir = path.join(clonePath, '.versions');
    
    if (fs.existsSync(versionsDir)) {
        const versionDirs = fs.readdirSync(versionsDir);
        for (const vDir of versionDirs) {
            const vPath = path.join(versionsDir, vDir);
            const stat = fs.statSync(vPath);
            versions.push({
                id: vDir,
                path: vPath,
                createdAt: stat.birthtime,
                size: getDirSize(vPath)
            });
        }
    }
    
    return versions;
}

function getDirSize(dirPath) {
    let size = 0;
    function count(dir) {
        if (!fs.existsSync(dir)) return;
        for (const item of fs.readdirSync(dir)) {
            const stat = fs.statSync(path.join(dir, item));
            if (stat.isDirectory()) {
                count(path.join(dir, item));
            } else {
                size += stat.size;
            }
        }
    }
    count(dirPath);
    return size;
}

function extractBaseUrl(dirName) {
    // "example.com_2026-05-17T20-58-30-760Z" -> "example.com"
    const parts = dirName.split('_');
    if (parts.length >= 2) {
        // Check if last part is a timestamp
        const lastPart = parts[parts.length - 1];
        if (/^\d{4}-\d{2}-\d{2}T/.test(lastPart)) {
            return parts.slice(0, -1).join('_');
        }
    }
    return parts[0];
}

function formatBytes(bytes) {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

// ============================================
// API ROUTES
// ============================================

// GET /api/clones - List all clones
router.get('/', (req, res) => {
    try {
        const clones = getAllClones();
        
        const summary = {
            total: clones.length,
            totalSize: clones.reduce((sum, c) => sum + c.stats.totalSize, 0),
            formattedSize: formatBytes(clones.reduce((sum, c) => sum + c.stats.totalSize, 0)),
            byStatus: {
                active: clones.filter(c => c.metadata?.status === 'active').length,
                archived: clones.filter(c => c.metadata?.status === 'archived').length,
                redesign: clones.filter(c => c.metadata?.status === 'redesign').length
            }
        };
        
        res.json({
            success: true,
            data: {
                clones,
                summary
            }
        });
    } catch (error) {
        console.error('Erro ao listar clones:', error);
        res.status(500).json({ success: false, error: error.message });
    }
});

// GET /api/clones/:id - Get single clone details
router.get('/:id', (req, res) => {
    try {
        const clonePath = path.join(BASE_DIR, req.params.id);
        
        if (!fs.existsSync(clonePath)) {
            return res.status(404).json({ success: false, error: 'Clone não encontrado' });
        }
        
        const metadata = loadMetadata(clonePath);
        const cloneInfo = loadCloneInfo(clonePath);
        const stats = getCloneStats(clonePath);
        const versions = listVersions(clonePath);
        
        // Get list of HTML files
        const htmlFiles = findFiles(clonePath, '.html');
        
        res.json({
            success: true,
            data: {
                id: req.params.id,
                baseUrl: extractBaseUrl(req.params.id),
                path: clonePath,
                metadata: metadata || { createdAt: cloneInfo?.clonedAt },
                cloneInfo,
                stats,
                versions,
                htmlFiles
            }
        });
    } catch (error) {
        console.error('Erro ao buscar clone:', error);
        res.status(500).json({ success: false, error: error.message });
    }
});

// PATCH /api/clones/:id - Update clone metadata
router.patch('/:id', (req, res) => {
    try {
        const clonePath = path.join(BASE_DIR, req.params.id);
        
        if (!fs.existsSync(clonePath)) {
            return res.status(404).json({ success: false, error: 'Clone não encontrado' });
        }
        
        const metaFile = path.join(clonePath, METADATA_FILE);
        let metadata = loadMetadata(clonePath) || {};
        
        // Merge updates
        metadata = {
            ...metadata,
            ...req.body,
            updatedAt: new Date().toISOString()
        };
        
        fs.writeFileSync(metaFile, JSON.stringify(metadata, null, 2));
        
        res.json({ success: true, data: { metadata } });
    } catch (error) {
        console.error('Erro ao atualizar clone:', error);
        res.status(500).json({ success: false, error: error.message });
    }
});

// POST /api/clones/:id/versions - Create a version snapshot
router.post('/:id/versions', (req, res) => {
    try {
        const clonePath = path.join(BASE_DIR, req.params.id);
        
        if (!fs.existsSync(clonePath)) {
            return res.status(404).json({ success: false, error: 'Clone não encontrado' });
        }
        
        const versionsDir = path.join(clonePath, '.versions');
        const versionId = `v${Date.now()}`;
        const versionPath = path.join(versionsDir, versionId);
        
        fs.mkdirSync(versionPath, { recursive: true });
        
        // Copy all files to version (except .versions itself)
        copyDirectory(clonePath, versionPath, ['.versions']);
        
        res.json({
            success: true,
            data: {
                versionId,
                path: versionPath,
                createdAt: new Date().toISOString()
            }
        });
    } catch (error) {
        console.error('Erro ao criar versão:', error);
        res.status(500).json({ success: false, error: error.message });
    }
});

// DELETE /api/clones/:id/versions/:versionId - Delete a version
router.delete('/:id/versions/:versionId', (req, res) => {
    try {
        const versionPath = path.join(BASE_DIR, req.params.id, '.versions', req.params.versionId);
        
        if (!fs.existsSync(versionPath)) {
            return res.status(404).json({ success: false, error: 'Versão não encontrada' });
        }
        
        fs.rmSync(versionPath, { recursive: true, force: true });
        
        res.json({ success: true, message: 'Versão removida' });
    } catch (error) {
        console.error('Erro ao remover versão:', error);
        res.status(500).json({ success: false, error: error.message });
    }
});

// POST /api/clones/:id/restore/:versionId - Restore from version
router.post('/:id/restore/:versionId', (req, res) => {
    try {
        const clonePath = path.join(BASE_DIR, req.params.id);
        const versionPath = path.join(clonePath, '.versions', req.params.versionId);
        
        if (!fs.existsSync(versionPath)) {
            return res.status(404).json({ success: false, error: 'Versão não encontrada' });
        }
        
        // Backup current state first
        const backupId = `pre-restore-${Date.now()}`;
        const backupPath = path.join(clonePath, '.versions', backupId);
        fs.mkdirSync(backupPath, { recursive: true });
        copyDirectory(clonePath, backupPath, ['.versions']);
        
        // Create restore point
        const restorePointId = `pre-restore-${Date.now()}`;
        const restorePointPath = path.join(clonePath, '.versions', restorePointId);
        fs.mkdirSync(restorePointPath, { recursive: true });
        copyDirectory(clonePath, restorePointPath, ['.versions']);
        
        // Copy version files back (overwrite)
        copyDirectory(versionPath, clonePath, ['.versions'], true);
        
        res.json({
            success: true,
            data: {
                restoredFrom: req.params.versionId,
                backupCreated: restorePointId
            }
        });
    } catch (error) {
        console.error('Erro ao restaurar versão:', error);
        res.status(500).json({ success: false, error: error.message });
    }
});

// DELETE /api/clones/:id - Delete a clone
router.delete('/:id', (req, res) => {
    try {
        const clonePath = path.join(BASE_DIR, req.params.id);
        
        if (!fs.existsSync(clonePath)) {
            return res.status(404).json({ success: false, error: 'Clone não encontrado' });
        }
        
        fs.rmSync(clonePath, { recursive: true, force: true });
        
        res.json({ success: true, message: 'Clone removido' });
    } catch (error) {
        console.error('Erro ao remover clone:', error);
        res.status(500).json({ success: false, error: error.message });
    }
});

// Helper functions
function findFiles(dir, extension) {
    const files = [];
    
    function search(d) {
        if (!fs.existsSync(d)) return;
        for (const item of fs.readdirSync(d)) {
            const itemPath = path.join(d, item);
            const stat = fs.statSync(itemPath);
            
            if (stat.isDirectory() && item !== '.versions' && !item.includes('node_modules')) {
                search(itemPath);
            } else if (item.endsWith(extension)) {
                files.push(path.relative(dir, itemPath));
            }
        }
    }
    
    search(dir);
    return files;
}

function copyDirectory(src, dest, exclude = [], overwrite = true) {
    if (!fs.existsSync(src)) return;
    fs.mkdirSync(dest, { recursive: true });
    
    for (const item of fs.readdirSync(src)) {
        if (exclude.includes(item)) continue;
        
        const srcPath = path.join(src, item);
        const destPath = path.join(dest, item);
        const stat = fs.statSync(srcPath);
        
        if (stat.isDirectory()) {
            copyDirectory(srcPath, destPath, exclude, overwrite);
        } else {
            if (overwrite || !fs.existsSync(destPath)) {
                fs.copyFileSync(srcPath, destPath);
            }
        }
    }
}

module.exports = router;
