import os
import re
from flask import request, redirect
from configs.filetypes import available_filetypes
from configs.languages import supported_languages
from helpers import get_site_settings

def _get_website_url():
    return os.getenv("website_url", "localhost")


def _is_subdomains_enabled():
    try:
        if os.environ.get('REPLIT_DEV_DOMAIN'):
            return False
        settings = get_site_settings()
        return settings.get('subdomains_enabled', '0') == '1'
    except Exception:
        return False


def _filetype_from_host():
    from flask import current_app
    server_name = current_app.config.get('SERVER_NAME')
    if not server_name:
        return None
    host = request.host.split(':')[0].lower()
    server_name = server_name.lower()
    if host == server_name or not host.endswith('.' + server_name):
        return None
    subdomain = host[:-(len(server_name) + 1)]
    return subdomain if subdomain else None


def register_subdomain_hooks(app):

    @app.before_request
    def redirect_non_www():
        
        app.logger.info(f"===== BEFORE_REQUEST: redirect_non_www =====")
        app.logger.info(f"URL: {request.url}")
        app.logger.info(f"Path: {request.path}")
        if request.path != '/' and request.path.endswith('/'):
            return redirect(request.path.rstrip('/'))
        host_hdr = request.headers.get('Host') or ''
        if host_hdr.startswith('www.'):
            new_url = request.url.replace('//www.', '//', 1)
            return redirect(new_url, code=308 if request.method == 'POST' else 301)
            
            
    
            
    # Subdomains reserved for internal services — never treated as filetype subdomains
    _RESERVED_SUBDOMAINS = {'api', 'developers'}

    @app.before_request
    def redirect_based_on_subdomain_status():
        """Force redirects based on whether subdomains are enabled or disabled"""

        # Skip in Replit dev tunnel — SERVER_NAME is not set, so we can't build valid subdomain URLs
        if os.environ.get('REPLIT_DEV_DOMAIN'):
            return

        # Skip for excluded paths
        excluded_paths = [
            '/upload', '/upload/remove', '/output', '/hash-output',
            '/job/status', '/download', '/static', '/favicon.ico',
            '/favico.ico', '/onlineconvert-favicon.ico', '/onlineconvert-favico.ico',
            '/ads.txt', '/robots.txt', '/sitemap.xml', '/sitemap', '/sitemap2.xml',
            '/sitemap2', '/dashboard', '/admin', '/login', '/register', '/logout',
            '/subscribe', '/pricing', '/checkout', '/account', '/blog', '/api',
            '/developers', '/formats', '/currencies', '/currency', '/debug', '/sw.js',
        ]
        
        for excluded in excluded_paths:
            if request.path.startswith(excluded):
                return
        
        host = request.host.split(':')[0]
        server_name = (app.config.get('SERVER_NAME') or _get_website_url())
        current_subdomain = _filetype_from_host()
        subdomains_enabled = _is_subdomains_enabled()

        # Never redirect reserved service subdomains (api, developers) —
        # they are handled by their own Flask routes, not filetype routing.
        if current_subdomain in _RESERVED_SUBDOMAINS:
            return
        
        # Get language prefix if present
        path = request.path
        lang_prefix = ""
        path_without_lang = path
        
        # Check for language code in path
        segments = path.split('/')
        if len(segments) > 1 and segments[1] in supported_languages:
            lang_prefix = f"/{segments[1]}"
            path_without_lang = '/' + '/'.join(segments[2:]) if len(segments) > 2 else '/'
        
        # CASE 1: Subdomains are DISABLED but we're on a subdomain -> redirect to main domain
        if not subdomains_enabled and current_subdomain:
            app.logger.info(f"Subdomains disabled: Redirecting from subdomain {host}{path} to main domain")
            
            # Map subdomain URL to main domain URL
            new_path = path_without_lang
            
            # Handle different URL patterns
            if path_without_lang.startswith('/convert-to-'):
                # /convert-to-jpg -> /converter/[filetype]/jpg
                fileformat = path_without_lang.replace('/convert-to-', '')
                new_path = f"/converter/{current_subdomain}/{fileformat}"
            elif path_without_lang.startswith('/do/'):
               
                fileformat = path_without_lang.replace('/do/', '')
                new_path = f"/do/{fileformat}"    
                
            elif path_without_lang.startswith('/convert-for-'):
                # /convert-for-psp -> /converter/device/psp
                fileformat = path_without_lang.replace('/convert-for-', '')
                new_path = f"/converter/device/{fileformat}"
            elif path_without_lang.startswith('/compress-'):
                # /compress-jpg -> /converter/[compressor-type]/jpg
                fileformat = path_without_lang.replace('/compress-', '')
                if current_subdomain in ["image-compressor", "video-compressor"]:
                    new_path = f"/converter/{current_subdomain}/{fileformat}"
            elif path_without_lang.startswith('/convert/') and '-to-' in path_without_lang:
                # /convert/bmp-to-jpg -> /convert/bmp-to-jpg (keep same)
                new_path = path_without_lang
            elif current_subdomain == 'hash' and re.match(r'^/[a-z0-9]+-generator$', path_without_lang):
                # hash.domain/md5-generator -> /converter/hash/md5
                hash_fmt = path_without_lang.lstrip('/').replace('-generator', '')
                new_path = f"/converter/hash/{hash_fmt}"
            elif re.match(r'^/[a-z0-9]+-converter$', path_without_lang):
                # image.domain/jpg-converter -> /image/jpg-converter
                fmt = path_without_lang.lstrip('/').replace('-converter', '')
                new_path = f"/{current_subdomain}/{fmt}-converter"
            elif path_without_lang == '/':
                # Subdomain homepage -> /converter/[filetype]
                new_path = f"/converter/{current_subdomain}"
            elif path_without_lang.startswith('/') and '-to-' in path_without_lang and '/' not in path_without_lang[1:]:
                # /jpg-to-png -> /convert/jpg-to-png
                new_path = f"/convert{path_without_lang}"
            
            new_url = f"{request.scheme}://{server_name}{lang_prefix}{new_path}"
            app.logger.info(f"Redirecting to: {new_url}")
            return redirect(new_url, code=301)
        
        # CASE 2: Subdomains are ENABLED but we're on main domain with converter URLs -> redirect to subdomain
        if subdomains_enabled and not current_subdomain:
            app.logger.info(f"Subdomains enabled: Checking if {path} should redirect to subdomain")
            
            # Pattern: /converter/filetype or /converter/filetype/format
            if path_without_lang.startswith('/converter/'):
                parts = path_without_lang.split('/')
                if len(parts) >= 3:
                    filetype = parts[2]
                    fileformat = parts[3] if len(parts) >= 4 else None
                    
                    if filetype in available_filetypes or filetype == "hash":
                        # Build subdomain URL with the correct prefix
                        subdomain = filetype
                        base_url = f"{request.scheme}://{subdomain}.{server_name}{lang_prefix}"
                        
                        if fileformat:
                            if filetype == "device":
                                new_url = f"{base_url}/convert-for-{fileformat}"
                            elif filetype == "webservice":
                                new_url = f"{base_url}/convert-for-{fileformat}"
                            elif filetype == "hash":
                                new_url = f"{base_url}/{fileformat}-generator"
                            elif filetype == "pdf":
                                new_url = f"{base_url}/do/{fileformat}"    
                            elif filetype in ["image-compressor", "video-compressor"]:
                                new_url = f"{base_url}/compress-{fileformat}"
                            else:
                                new_url = f"{base_url}/convert-to-{fileformat}"
                        else:
                            new_url = base_url + "/"
                        
                        app.logger.info(f"Redirecting to: {new_url}")
                        return redirect(new_url, code=301)
            
            # Pattern: /convert/first-to-second
            elif path_without_lang.startswith('/convert/') and '-to-' in path_without_lang:
                match = re.search(r'/convert/([a-z0-9]+)-to-([a-z0-9]+)', path_without_lang)
                if match:
                    first, second = match.groups()
                    for ft, config in available_filetypes.items():
                        allowed = [f.lower() for f in config.get('allowed', [])]
                        extensions = [f.lower() for f in config.get('ext', [])]
                        if first.lower() in allowed and second.lower() in extensions:
                            new_url = f"{request.scheme}://{ft}.{server_name}{lang_prefix}{path_without_lang}"
                            app.logger.info(f"Redirecting to: {new_url}")
                            return redirect(new_url, code=301)
            
            # Pattern: /filetype/fileformat-converter  e.g. /image/jpg-converter
            elif re.match(r'^/[a-z0-9-]+/[a-z0-9]+-converter$', path_without_lang):
                parts = path_without_lang.strip('/').split('/')
                if len(parts) == 2:
                    ft = parts[0]
                    fmt = parts[1].replace('-converter', '')
                    if ft in available_filetypes or ft == 'hash':
                        new_url = f"{request.scheme}://{ft}.{server_name}{lang_prefix}/{fmt}-converter"
                        app.logger.info(f"Redirecting format-converter to subdomain: {new_url}")
                        return redirect(new_url, code=301)

            # Pattern: /first-to-second (direct conversion URL)
            # Redirect to filetype subdomain /convert/first-to-second
            elif re.match(r'^/[a-z0-9]+-to-[a-z0-9]+$', path_without_lang):
                path_clean = path_without_lang.strip('/')
                if '-to-' in path_clean:
                    first, second = path_clean.split('-to-', 1)
                    for ft, config in available_filetypes.items():
                        allowed = [f.lower() for f in config.get('allowed', [])]
                        extensions = [f.lower() for f in config.get('ext', [])]
                        if first.lower() in allowed and second.lower() in extensions:
                            new_url = f"{request.scheme}://{ft}.{server_name}{lang_prefix}/convert/{path_clean}"
                            app.logger.info(f"Redirecting ext-to-ext to subdomain: {new_url}")
                            return redirect(new_url, code=301)
        
        # If no redirect needed, continue
        return

    @app.before_request
    def redirect_to_subdomain():
        app.logger.debug(f"🔴 REDIRECT_TO_SUBDOMAIN CHECK for: {request.path}")
        
        # Skip if this is the custom admin slug
        try:
            from helpers import get_site_settings
            settings = get_site_settings()
            custom_slug = settings.get('admin_login_slug', '').strip().strip('/')
            app.logger.debug(f"redirect_to_subdomain - custom slug: '{custom_slug}'")
            
            if custom_slug and request.path.strip('/') == custom_slug:
                app.logger.debug(f"🔴 SKIPPING REDIRECT FOR CUSTOM SLUG: /{custom_slug} 🔴")
                return
        except Exception as e:
            app.logger.error(f"Error in redirect_to_subdomain custom slug check: {e}")
        
        current_subdomain = _filetype_from_host()
        
        if os.environ.get('REPLIT_DEV_DOMAIN'):
            return

        if not _is_subdomains_enabled():
            return

        # Never redirect reserved service subdomains (api, developers)
        if current_subdomain in _RESERVED_SUBDOMAINS:
            return

        # Don't redirect if we're already on a (filetype) subdomain
        if current_subdomain:
            return

        excluded_paths = [
            '/upload', '/upload/remove', '/output', '/hash-output',
            '/job/status', '/download', '/static', '/favicon.ico',
            '/favico.ico', '/onlineconvert-favicon.ico', '/onlineconvert-favico.ico',
            '/ads.txt', '/robots.txt', '/sitemap.xml', '/sitemap', '/sitemap2.xml',
            '/sitemap2', '/dashboard', '/admin', '/login', '/register', '/logout',
            '/subscribe', '/pricing', '/checkout', '/account', '/blog', '/api',
            '/developers', '/formats', '/currencies', '/currency',
        ]
        for excluded in excluded_paths:
            if request.path.startswith(excluded):
                return
                
        host = request.host.split(':')[0]
        parts = host.split('.')
        path = request.path.lstrip('/')

        # Only redirect if we're on main domain (less than 3 parts)
        if len(parts) < 3:
            segments = path.split('/')
            lang_prefix = ""
            if segments and segments[0].lower() in supported_languages:
                lang_prefix = f"/{segments[0]}"
                segments = segments[1:]
            
            # Redirect /converter/filetype or /converter/filetype/format to subdomain
            if segments and segments[0].lower() in ["converter", "convert"] and len(segments) >= 2:
                filetype = segments[1].lower()
                fileformat = segments[2].lower() if len(segments) >= 3 else None
                
                if filetype in available_filetypes or filetype == "hash":
                    subdomain = filetype
                    server_name = (app.config.get('SERVER_NAME') or _get_website_url())
                    base_url = f"{request.scheme}://{subdomain}.{server_name}{lang_prefix}"
                    
                    if fileformat:
                        if filetype == "device":
                            new_url = f"{base_url}/convert-for-{fileformat}"
                        elif filetype == "webservice":
                                new_url = f"{base_url}/convert-for-{fileformat}"    
                        elif filetype == "hash":
                            new_url = f"{base_url}/{fileformat}-generator"
                        elif filetype == "pdf":
                                new_url = f"{base_url}/do/{fileformat}"    
                        elif filetype in ["image-compressor", "video-compressor"]:
                            new_url = f"{base_url}/compress-{fileformat}"
                        else:
                            new_url = f"{base_url}/convert-to-{fileformat}"
                    else:
                        new_url = base_url + "/"
                    
                    app.logger.info(f"Redirecting to subdomain: {new_url}")
                    return redirect(new_url, code=308 if request.method == 'POST' else 301)
            
            # Redirect /hash to hash subdomain homepage
            if segments and segments[0].lower() == "hash":
                server_name = (app.config.get('SERVER_NAME') or _get_website_url())
                
                # Case 1: Just /hash or /hash/ (homepage)
                if len(segments) == 1 or (len(segments) == 2 and segments[1] == ""):
                    new_url = f"{request.scheme}://hash.{server_name}{lang_prefix}/"
                    app.logger.info(f"Redirecting hash homepage to subdomain: {new_url}")
                    return redirect(new_url, code=308 if request.method == 'POST' else 301)
                
                # Case 2: /hash/format or /hash/format-generator
                elif len(segments) >= 2:
                    hashformat = segments[1].lower()
                    # Remove -generator if present to avoid duplication
                    if hashformat.endswith('-generator'):
                        hashformat = hashformat.replace('-generator', '')
                    new_url = f"{request.scheme}://hash.{server_name}{lang_prefix}/{hashformat}-generator"
                    app.logger.info(f"Redirecting hash format to subdomain: {new_url}")
                    return redirect(new_url, code=308 if request.method == 'POST' else 301)

            # Redirect /filetype/fileformat-converter to subdomain
            # e.g. /image/jpg-converter -> image.domain/jpg-converter
            if (
                len(segments) == 2
                and segments[1].endswith('-converter')
                and segments[0] in available_filetypes
            ):
                ft = segments[0]
                fmt = segments[1].replace('-converter', '')
                server_name = (app.config.get('SERVER_NAME') or _get_website_url())
                new_url = f"{request.scheme}://{ft}.{server_name}{lang_prefix}/{fmt}-converter"
                app.logger.info(f"Redirecting format-converter to subdomain: {new_url}")
                return redirect(new_url, code=308 if request.method == 'POST' else 301)

            # Redirect /first-to-second directly to filetype subdomain /convert/first-to-second
            _excluded_hyphen = {
                'forgot-password', 'reset-password', 'change-password', 'verify-email',
                'resend-verification', 'sign-in', 'sign-up', 'log-in', 'log-out',
                'two-factor', 'two-factor-auth', 'privacy-policy', 'terms-of-service',
                'contact-us', 'about-us', 'online-convert', 'delete-account',
                'unsubscribe', 'email-preferences', 'account-settings',
            }
            if (
                '/' not in path
                and '-to-' in path
                and path not in _excluded_hyphen
                and re.match(r'^[a-z0-9]+-to-[a-z0-9]+$', path)
            ):
                first, second = path.split('-to-', 1)
                server_name = (app.config.get('SERVER_NAME') or _get_website_url())
                # Try to find which filetype owns this conversion pair
                for ft, config in available_filetypes.items():
                    allowed = [f.lower() for f in config.get('allowed', [])]
                    extensions = [f.lower() for f in config.get('ext', [])]
                    if first.lower() in allowed and second.lower() in extensions:
                        new_url = f"{request.scheme}://{ft}.{server_name}{lang_prefix}/convert/{path}"
                        app.logger.info(f"Redirecting ext-to-ext to subdomain: {new_url}")
                        return redirect(new_url, code=308 if request.method == 'POST' else 301)
                # Fallback: stay on main domain under /convert/
                new_url = f"{request.scheme}://{host}/convert/{path}"
                app.logger.info(f"Redirecting to /convert/ (no filetype match): {new_url}")
                return redirect(new_url, code=308 if request.method == 'POST' else 301)