#!/usr/bin/env python

import os
import sys
import shutil
import stat
import subprocess
from pathlib import Path
import re

# Set production settings
os.environ["DJANGO_SETTINGS_MODULE"] = "branch_system.settings_production"

# Add the project directory to the Python path
sys.path.insert(0, os.path.dirname(__file__))

# Import Django modules after setting the environment
import django
django.setup()

from django.conf import settings
from django.core.management import call_command

def print_header(message):
    print(f"\n{'=' * 60}")
    print(f" {message}")
    print(f"{'=' * 60}\n")

def print_step(message):
    print(f"🔧 {message}")

def print_success(message):
    print(f"✅ {message}")

def print_warning(message):
    print(f"⚠️ {message}")

def backup_files():
    print_step("Creating backup of critical files...")
    
    backup_dir = Path(settings.BASE_DIR) / 'backups'
    backup_dir.mkdir(exist_ok=True)
    
    # Files to backup
    files_to_backup = [
        Path(settings.BASE_DIR) / 'branch_system' / 'settings_production.py',
        Path(settings.BASE_DIR) / 'branch_system' / 'urls.py',
        Path(settings.BASE_DIR) / 'branch_system' / 'wsgi.py',
        Path(settings.BASE_DIR) / '.htaccess',
    ]
    
    for file_path in files_to_backup:
        if file_path.exists():
            backup_path = backup_dir / f"{file_path.name}.bak"
            shutil.copy2(file_path, backup_path)
            print_success(f"Backed up {file_path} to {backup_path}")
    
    print_success("Backup completed")

def fix_settings_production():
    print_step("Updating settings_production.py...")
    
    settings_path = Path(settings.BASE_DIR) / 'branch_system' / 'settings_production.py'
    if settings_path.exists():
        with open(settings_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # Check if DEBUG is False and temporarily set it to True
        if 'DEBUG = False' in content:
            content = content.replace('DEBUG = False', 'DEBUG = True  # Temporarily enabled for troubleshooting')
            print_warning("Temporarily setting DEBUG=True for troubleshooting")
        
        # Ensure STATICFILES_DIRS is properly configured
        if 'STATICFILES_DIRS' not in content:
            # Find STATIC_ROOT line
            static_root_pattern = re.compile(r'STATIC_ROOT\s*=\s*.*')
            match = static_root_pattern.search(content)
            if match:
                # Add STATICFILES_DIRS after STATIC_ROOT
                insert_pos = match.end()
                staticfiles_dirs = "\n\n# Additional locations of static files\nSTATICFILES_DIRS = [BASE_DIR / 'static']\n"
                content = content[:insert_pos] + staticfiles_dirs + content[insert_pos:]
                print_success("Added STATICFILES_DIRS configuration")
        
        # Ensure STATIC_ROOT is set to 'staticfiles'
        if "STATIC_ROOT = BASE_DIR / 'static'" in content:
            content = content.replace("STATIC_ROOT = BASE_DIR / 'static'", "STATIC_ROOT = BASE_DIR / 'staticfiles'")
            print_success("Updated STATIC_ROOT to use 'staticfiles' directory")
        
        # Write updated content
        with open(settings_path, 'w', encoding='utf-8') as f:
            f.write(content)
        
        print_success("Updated settings_production.py")
    else:
        print_warning(f"settings_production.py not found at {settings_path}")

def fix_urls_py():
    print_step("Updating urls.py...")
    
    urls_path = Path(settings.BASE_DIR) / 'branch_system' / 'urls.py'
    if urls_path.exists():
        with open(urls_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # Check if static patterns are already conditionally served
        if 'if settings.DEBUG:' not in content and 'urlpatterns += static(settings.STATIC_URL' in content:
            # Find the static URL patterns
            static_pattern = re.compile(r'urlpatterns\s*\+=\s*static\(settings\.STATIC_URL.*?\)')
            media_pattern = re.compile(r'urlpatterns\s*\+=\s*static\(settings\.MEDIA_URL.*?\)')
            
            static_match = static_pattern.search(content)
            media_match = media_pattern.search(content)
            
            if static_match and media_match:
                # Replace with conditional serving for static files
                static_line = static_match.group(0)
                media_line = media_match.group(0)
                
                # Remove both lines
                content = content.replace(static_line, '')
                content = content.replace(media_line, '')
                
                # Add conditional serving
                new_patterns = "\n# Serve static files from Django only in development\nif settings.DEBUG:\n    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)\n\n# Always serve media files from Django\nurlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)\n"
                
                # Add at the end of the file
                content += new_patterns
                
                print_success("Updated static/media file serving in urls.py")
        
        # Write updated content
        with open(urls_path, 'w', encoding='utf-8') as f:
            f.write(content)
        
        print_success("Updated urls.py")
    else:
        print_warning(f"urls.py not found at {urls_path}")

def fix_htaccess():
    print_step("Updating .htaccess file...")
    
    htaccess_path = Path(settings.BASE_DIR) / '.htaccess'
    if htaccess_path.exists():
        with open(htaccess_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # Check if RewriteEngine is enabled
        if 'RewriteEngine On' not in content:
            content = "RewriteEngine On\n\n" + content
            print_success("Enabled RewriteEngine")
        
        # Improved rewrite rules for static files
        static_rewrite = """
# Serve static files from staticfiles directory
RewriteCond %{REQUEST_URI} ^/static/(.*)$
RewriteCond %{DOCUMENT_ROOT}/staticfiles/%1 -f
RewriteRule ^static/(.*)$ staticfiles/$1 [L]

# Fallback to static directory if file not found in staticfiles
RewriteCond %{REQUEST_URI} ^/static/(.*)$
RewriteCond %{DOCUMENT_ROOT}/static/%1 -f
RewriteRule ^static/(.*)$ static/$1 [L]

# Serve media files
RewriteCond %{REQUEST_URI} ^/media/(.*)$
RewriteRule ^media/(.*)$ media/$1 [L]
"""
        
        # Check if static rewrite rules already exist
        if 'RewriteCond %{REQUEST_URI} ^/static/(.*)$' not in content:
            # Find position to insert rules (after RewriteEngine On)
            rewrite_pos = content.find('RewriteEngine On') + len('RewriteEngine On')
            content = content[:rewrite_pos] + "\n" + static_rewrite + content[rewrite_pos:]
            print_success("Added improved static/media rewrite rules")
        
        # Add security headers if not present
        security_headers = """
# Security headers
<IfModule mod_headers.c>
    Header set X-Content-Type-Options "nosniff"
    Header set X-XSS-Protection "1; mode=block"
    Header set X-Frame-Options "SAMEORIGIN"
    Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
"""
        
        if 'X-Content-Type-Options' not in content:
            content += "\n" + security_headers
            print_success("Added security headers")
        
        # Add compression if not present
        compression = """
# Enable compression
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
</IfModule>
"""
        
        if 'mod_deflate.c' not in content:
            content += "\n" + compression
            print_success("Added compression settings")
        
        # Add caching if not present
        caching = """
# Enable caching
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css "access plus 1 month"
    ExpiresByType application/javascript "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"
</IfModule>
"""
        
        if 'mod_expires.c' not in content:
            content += "\n" + caching
            print_success("Added caching settings")
        
        # Write updated content
        with open(htaccess_path, 'w', encoding='utf-8') as f:
            f.write(content)
        
        print_success("Updated .htaccess file")
    else:
        print_warning(f".htaccess not found at {htaccess_path}")

def fix_css_js():
    print_step("Creating/updating CSS and JS fixes...")
    
    # Create CSS directory if it doesn't exist
    css_dir = Path(settings.BASE_DIR) / 'static' / 'css'
    css_dir.mkdir(exist_ok=True, parents=True)
    
    # Create JS directory if it doesn't exist
    js_dir = Path(settings.BASE_DIR) / 'static' / 'js'
    js_dir.mkdir(exist_ok=True, parents=True)
    
    # CSS fixes for client names and images
    css_content = """
/* Fix for client names in tables */
.client-name {
    max-width: 150px;
    white-space: normal !important;
    word-break: break-word;
    overflow-wrap: break-word;
}

/* Fix for image display */
.profile-image {
    max-width: 100%;
    height: auto;
    display: block;
}

/* Fix for table layout */
.table-responsive {
    overflow-x: auto;
}

/* Fix for overlapping content */
td, th {
    padding: 8px !important;
    vertical-align: top !important;
}

/* Ensure images are visible */
img {
    max-width: 100%;
    height: auto;
}
"""
    
    css_path = css_dir / 'table-fix.css'
    with open(css_path, 'w', encoding='utf-8') as f:
        f.write(css_content)
    
    # JS fixes for tables and client names
    js_content = """
// Fix for client names and table layout
document.addEventListener('DOMContentLoaded', function() {
    // Add client-name class to client name cells
    const clientNameCells = document.querySelectorAll('td:nth-child(2)');
    clientNameCells.forEach(cell => {
        cell.classList.add('client-name');
    });
    
    // Ensure all tables have responsive class
    const tables = document.querySelectorAll('table');
    tables.forEach(table => {
        if (!table.classList.contains('table-responsive')) {
            const wrapper = document.createElement('div');
            wrapper.classList.add('table-responsive');
            table.parentNode.insertBefore(wrapper, table);
            wrapper.appendChild(table);
        }
    });
});
"""
    
    js_path = js_dir / 'table-fix.js'
    with open(js_path, 'w', encoding='utf-8') as f:
        f.write(js_content)
    
    print_success("Created/updated CSS and JS fixes")

def collect_static():
    print_step("Collecting static files...")
    
    try:
        # Create staticfiles directory if it doesn't exist
        staticfiles_dir = Path(settings.BASE_DIR) / 'staticfiles'
        staticfiles_dir.mkdir(exist_ok=True)
        
        # Run collectstatic
        call_command('collectstatic', '--noinput')
        print_success("Static files collected successfully")
        
        # Set proper permissions for staticfiles directory
        for root, dirs, files in os.walk(staticfiles_dir):
            for d in dirs:
                os.chmod(os.path.join(root, d), 0o755)
            for f in files:
                os.chmod(os.path.join(root, f), 0o644)
        
        print_success("Static file permissions set")
    except Exception as e:
        print_warning(f"Error collecting static files: {e}")

def set_media_permissions():
    print_step("Setting proper permissions for media files...")
    
    try:
        media_dir = Path(settings.MEDIA_ROOT)
        if media_dir.exists():
            # Set directory permissions to 755
            for root, dirs, files in os.walk(media_dir):
                for d in dirs:
                    os.chmod(os.path.join(root, d), 0o755)
                for f in files:
                    os.chmod(os.path.join(root, f), 0o644)
            
            print_success("Media file permissions set")
        else:
            print_warning(f"Media directory not found at {media_dir}")
    except Exception as e:
        print_warning(f"Error setting media permissions: {e}")

def update_templates():
    print_step("Updating templates to include CSS and JS fixes...")
    
    # Find base template
    base_template_path = Path(settings.BASE_DIR) / 'templates' / 'base.html'
    if base_template_path.exists():
        with open(base_template_path, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read()
        
        # Check if our CSS and JS are already included
        css_included = 'table-fix.css' in content
        js_included = 'table-fix.js' in content
        
        if not css_included or not js_included:
            # Find the </head> tag
            head_end_pos = content.find('</head>')
            if head_end_pos != -1:
                # Add our CSS and JS before the </head> tag
                includes = ''
                if not css_included:
                    includes += '\n    <!-- Fix for client names and images -->\n'
                    includes += '    <link rel="stylesheet" href="{% static \'css/table-fix.css\' %}">\n'
                if not js_included:
                    includes += '    <script src="{% static \'js/table-fix.js\' %}" defer></script>\n'
                
                updated_content = content[:head_end_pos] + includes + content[head_end_pos:]
                
                with open(base_template_path, 'w', encoding='utf-8') as f:
                    f.write(updated_content)
                
                print_success(f"Updated {base_template_path} to include CSS and JS fixes")
            else:
                print_warning(f"Could not find </head> tag in {base_template_path}")
        else:
            print_success(f"CSS and JS fixes already included in {base_template_path}")
    else:
        print_warning(f"Base template not found: {base_template_path}")
        
        # Try to find other templates that might include <head>
        templates_dir = Path(settings.BASE_DIR) / 'templates'
        if templates_dir.exists():
            for root, dirs, files in os.walk(templates_dir):
                for file in files:
                    if file.endswith('.html'):
                        template_path = Path(root) / file
                        with open(template_path, 'r', encoding='utf-8', errors='ignore') as f:
                            content = f.read()
                        
                        if '</head>' in content and ('table-fix.css' not in content or 'table-fix.js' not in content):
                            print_step(f"Found template with </head>: {template_path}")
                            # Add our CSS and JS before the </head> tag
                            head_end_pos = content.find('</head>')
                            includes = '\n    <!-- Fix for client names and images -->\n'
                            if 'table-fix.css' not in content:
                                includes += '    <link rel="stylesheet" href="{% static \'css/table-fix.css\' %}">\n'
                            if 'table-fix.js' not in content:
                                includes += '    <script src="{% static \'js/table-fix.js\' %}" defer></script>\n'
                            
                            updated_content = content[:head_end_pos] + includes + content[head_end_pos:]
                            
                            with open(template_path, 'w', encoding='utf-8') as f:
                                f.write(updated_content)
                            
                            print_success(f"Updated {template_path} to include CSS and JS fixes")

def fix_wsgi_py():
    print_step("Updating wsgi.py...")
    
    wsgi_path = Path(settings.BASE_DIR) / 'branch_system' / 'wsgi.py'
    if wsgi_path.exists():
        with open(wsgi_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # Check if settings module is set to production
        if "'branch_system.settings'" in content and "'branch_system.settings_production'" not in content:
            content = content.replace("'branch_system.settings'", "'branch_system.settings_production'")
            
            with open(wsgi_path, 'w', encoding='utf-8') as f:
                f.write(content)
            
            print_success("Updated wsgi.py to use production settings")
        else:
            print_success("wsgi.py already using correct settings")
    else:
        print_warning(f"wsgi.py not found at {wsgi_path}")

def main():
    print_header("HAVEN GRAZURI INVESTMENT LIMITED- Enhanced Media & Static Files Fix")
    
    # Create backups
    backup_files()
    
    # Fix settings_production.py
    fix_settings_production()
    
    # Fix urls.py
    fix_urls_py()
    
    # Fix .htaccess
    fix_htaccess()
    
    # Fix wsgi.py
    fix_wsgi_py()
    
    # Create/update CSS and JS fixes
    fix_css_js()
    
    # Collect static files
    collect_static()
    
    # Set media permissions
    set_media_permissions()
    
    # Update templates
    update_templates()
    
    print_header("ENHANCED FIX COMPLETED")
    print("\n📋 Next Steps:")
    print("1. Restart your web server")
    print("2. Test the website to ensure images are loading")
    print("3. Verify client names are displaying correctly")
    print("4. Once everything is working, set DEBUG back to False in settings_production.py")
    print("\n🔍 If issues persist:")
    print("- Check server error logs")
    print("- Verify file permissions (755 for directories, 644 for files)")
    print("- Ensure .htaccess is being read by Apache")
    print("- Consider keeping DEBUG=True temporarily for troubleshooting")

if __name__ == "__main__":
    main()