<?php

/**
 * Multi-Tenant File Manager - Handles company-specific file storage
 */
class FileManager {
    
    /**
     * Get company storage path
     */
    public static function getCompanyStoragePath(int $companyId, string $subfolder = ''): string
    {
        $baseStorage = __DIR__ . '/../storage';
        $companyPath = $baseStorage . '/companies/' . $companyId;
        
        if (!empty($subfolder)) {
            $companyPath .= '/' . trim($subfolder, '/');
        }
        
        return $companyPath;
    }
    
    /**
     * Ensure company storage directories exist
     */
    public static function ensureCompanyDirectories(int $companyId): void
    {
        $directories = [
            'proposals',
            'invoices', 
            'contracts',
            'receipts',
            'pdfs',
            'logos',
            'signatures',
            'templates',
            'temp',
            'uploads'
        ];
        
        foreach ($directories as $dir) {
            $path = self::getCompanyStoragePath($companyId, $dir);
            if (!is_dir($path)) {
                mkdir($path, 0755, true);
            }
        }
    }
    
    /**
     * Store file for company
     */
    public static function storeFile(int $companyId, string $subfolder, array $file): string
    {
        // Ensure company directories exist
        self::ensureCompanyDirectories($companyId);
        
        $storagePath = self::getCompanyStoragePath($companyId, $subfolder);
        
        // Generate unique filename
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = uniqid() . '_' . time() . '.' . $extension;
        $fullPath = $storagePath . '/' . $filename;
        
        // Move uploaded file
        if (move_uploaded_file($file['tmp_name'], $fullPath)) {
            return $filename;
        }
        
        throw new Exception('Failed to store file');
    }
    
    /**
     * Get file URL for company
     */
    public static function getFileUrl(int $companyId, string $subfolder, string $filename): string
    {
        $baseUrl = $_ENV['APP_URL'] ?? 'http://localhost';
        return $baseUrl . '/storage/companies/' . $companyId . '/' . trim($subfolder, '/') . '/' . $filename;
    }
    
    /**
     * Get file path for company
     */
    public static function getFilePath(int $companyId, string $subfolder, string $filename): string
    {
        return self::getCompanyStoragePath($companyId, $subfolder) . '/' . $filename;
    }
    
    /**
     * Delete company file
     */
    public static function deleteFile(int $companyId, string $subfolder, string $filename): bool
    {
        $filePath = self::getFilePath($companyId, $subfolder, $filename);
        
        if (file_exists($filePath)) {
            return unlink($filePath);
        }
        
        return false;
    }
    
    /**
     * Copy existing files to company structure
     */
    public static function migrateExistingFiles(int $companyId): void
    {
        $sourceBase = __DIR__ . '/../storage';
        $targetBase = self::getCompanyStoragePath($companyId);
        
        $directories = ['contracts', 'pdfs', 'receipts'];
        
        foreach ($directories as $dir) {
            $sourceDir = $sourceBase . '/' . $dir;
            $targetDir = $targetBase . '/' . $dir;
            
            if (is_dir($sourceDir) && !is_dir($targetDir)) {
                // Copy directory structure
                self::copyDirectory($sourceDir, $targetDir);
            }
        }
        
        // Copy assets if they exist
        $assetsSource = __DIR__ . '/../public/assets';
        if (is_dir($assetsSource)) {
            $logosTarget = $targetBase . '/logos';
            $signaturesTarget = $targetBase . '/signatures';
            
            if (is_dir($assetsSource . '/logos') && !is_dir($logosTarget)) {
                self::copyDirectory($assetsSource . '/logos', $logosTarget);
            }
            
            if (is_dir($assetsSource . '/signatures') && !is_dir($signaturesTarget)) {
                self::copyDirectory($assetsSource . '/signatures', $signaturesTarget);
            }
        }
    }
    
    /**
     * Copy directory recursively
     */
    private static function copyDirectory(string $source, string $target): void
    {
        if (!is_dir($target)) {
            mkdir($target, 0755, true);
        }
        
        $files = scandir($source);
        foreach (array_diff($files, ['.', '..']) as $file) {
            $sourcePath = $source . '/' . $file;
            $targetPath = $target . '/' . $file;
            
            if (is_dir($sourcePath)) {
                self::copyDirectory($sourcePath, $targetPath);
            } else {
                copy($sourcePath, $targetPath);
            }
        }
    }
    
    /**
     * Get company file list
     */
    public static function getCompanyFiles(int $companyId, string $subfolder): array
    {
        $directory = self::getCompanyStoragePath($companyId, $subfolder);
        
        if (!is_dir($directory)) {
            return [];
        }
        
        $files = [];
        $items = scandir($directory);
        
        foreach (array_diff($items, ['.', '..']) as $file) {
            $filePath = $directory . '/' . $file;
            if (is_file($filePath)) {
                $files[] = [
                    'name' => $file,
                    'path' => $filePath,
                    'url' => self::getFileUrl($companyId, $subfolder, $file),
                    'size' => filesize($filePath),
                    'modified' => filemtime($filePath)
                ];
            }
        }
        
        return $files;
    }
    
    /**
     * Clean up temporary files for company
     */
    public static function cleanupTempFiles(int $companyId, int $maxAge = 3600): void
    {
        $tempDir = self::getCompanyStoragePath($companyId, 'temp');
        
        if (!is_dir($tempDir)) {
            return;
        }
        
        $cutoffTime = time() - $maxAge;
        $files = scandir($tempDir);
        
        foreach (array_diff($files, ['.', '..']) as $file) {
            $filePath = $tempDir . '/' . $file;
            if (is_file($filePath) && filemtime($filePath) < $cutoffTime) {
                unlink($filePath);
            }
        }
    }
    
    /**
     * Get storage usage for company
     */
    public static function getStorageUsage(int $companyId): array
    {
        $companyBase = self::getCompanyStoragePath($companyId);
        
        if (!is_dir($companyBase)) {
            return ['total' => 0, 'by_type' => []];
        }
        
        $totalSize = 0;
        $byType = [];
        
        $directories = ['proposals', 'invoices', 'contracts', 'receipts', 'pdfs', 'logos', 'signatures', 'templates'];
        
        foreach ($directories as $dir) {
            $dirPath = $companyBase . '/' . $dir;
            if (is_dir($dirPath)) {
                $size = self::getDirectorySize($dirPath);
                $byType[$dir] = $size;
                $totalSize += $size;
            }
        }
        
        return [
            'total' => $totalSize,
            'by_type' => $byType
        ];
    }
    
    /**
     * Get directory size
     */
    private static function getDirectorySize(string $directory): int
    {
        $size = 0;
        $files = scandir($directory);
        
        foreach (array_diff($files, ['.', '..']) as $file) {
            $filePath = $directory . '/' . $file;
            if (is_file($filePath)) {
                $size += filesize($filePath);
            } elseif (is_dir($filePath)) {
                $size += self::getDirectorySize($filePath);
            }
        }
        
        return $size;
    }
}
