"""Detect unsubscribe links in emails."""
import re
from typing import Dict, List, Optional
from bs4 import BeautifulSoup


def detect_unsubscribe_link(email_content: Dict) -> Optional[str]:
    """
    Wykrywa link do wypisania się z newslettera.
    
    Args:
        email_content: Słownik z danymi emaila (body, headers)
    
    Returns:
        URL do unsubscribe lub None
    """
    # 1. Check List-Unsubscribe header (RFC 2369)
    headers = email_content.get('headers', {})
    list_unsubscribe = headers.get('List-Unsubscribe', '')
    
    if list_unsubscribe:
        # Extract URL from <url> format
        url_match = re.search(r'<(https?://[^>]+)>', list_unsubscribe)
        if url_match:
            return url_match.group(1)
    
    # 2. Check email body for unsubscribe links
    body = email_content.get('body', '')
    html_body = email_content.get('html_body', body)
    
    # Parse HTML if available
    if html_body:
        soup = BeautifulSoup(html_body, 'html.parser')
        
        # Look for links with unsubscribe keywords
        unsubscribe_keywords = [
            'unsubscribe', 'wypisz', 'rezygnacja', 'abmelden',
            'désabonner', 'darse de baja', 'annulla iscrizione',
            'opt-out', 'opt out', 'remove', 'usun'
        ]
        
        for link in soup.find_all('a', href=True):
            href = link.get('href', '')
            text = link.get_text().lower()
            
            # Check if link text or URL contains unsubscribe keywords
            for keyword in unsubscribe_keywords:
                if keyword in text or keyword in href.lower():
                    if href.startswith('http'):
                        return href
        
        # Look for links in footer (common location)
        footer = soup.find(['footer', 'div'], class_=re.compile(r'footer|foot', re.I))
        if footer:
            for link in footer.find_all('a', href=True):
                href = link.get('href', '')
                if href.startswith('http'):
                    text = link.get_text().lower()
                    for keyword in unsubscribe_keywords:
                        if keyword in text or keyword in href.lower():
                            return href
    
    # 3. Fallback: regex search in plain text body
    unsubscribe_patterns = [
        r'https?://[^\s<>"]+unsubscribe[^\s<>"]*',
        r'https?://[^\s<>"]+opt-out[^\s<>"]*',
        r'https?://[^\s<>"]+remove[^\s<>"]*',
        r'https?://[^\s<>"]+wypisz[^\s<>"]*',
    ]
    
    for pattern in unsubscribe_patterns:
        match = re.search(pattern, body, re.IGNORECASE)
        if match:
            return match.group(0)
    
    return None


def extract_unsubscribe_info(email_content: Dict) -> Dict:
    """
    Ekstraktuje wszystkie informacje potrzebne do unsubscribe.
    
    Args:
        email_content: Słownik z danymi emaila
    
    Returns:
        Słownik z informacjami: link, sender, subject, date, body_fragment
    """
    info = {
        'link': detect_unsubscribe_link(email_content),
        'sender': email_content.get('from', 'Unknown'),
        'subject': email_content.get('subject', 'No subject'),
        'date': email_content.get('date', ''),
        'body_fragment': '',
        'has_unsubscribe': False,
    }
    
    # Extract body fragment around unsubscribe link
    if info['link']:
        info['has_unsubscribe'] = True
        body = email_content.get('body', '')
        
        # Find context around the link
        link_pos = body.lower().find('unsubscribe')
        if link_pos == -1:
            link_pos = body.lower().find('wypisz')
        if link_pos == -1:
            link_pos = body.lower().find('opt-out')
        
        if link_pos >= 0:
            # Extract 100 chars before and after
            start = max(0, link_pos - 100)
            end = min(len(body), link_pos + 100)
            info['body_fragment'] = body[start:end].strip()
        else:
            # Just take last 200 chars (footer usually)
            info['body_fragment'] = body[-200:].strip()
    
    return info


def is_newsletter(email_content: Dict) -> bool:
    """
    Sprawdza czy email jest newsletterem.
    
    Args:
        email_content: Słownik z danymi emaila
    
    Returns:
        True jeśli newsletter
    """
    # Check headers
    headers = email_content.get('headers', {})
    
    # Has List-Unsubscribe header?
    if 'List-Unsubscribe' in headers:
        return True
    
    # Check for bulk/marketing precedence
    precedence = headers.get('Precedence', '').lower()
    if precedence in ['bulk', 'list']:
        return True
    
    # Check for marketing/promotional keywords in subject
    subject = email_content.get('subject', '').lower()
    newsletter_keywords = [
        'newsletter', 'update', 'digest', 'weekly', 'monthly',
        'promotion', 'offer', 'deal', 'sale', 'discount',
        'biuletyn', 'aktualności', 'oferta', 'promocja'
    ]
    
    for keyword in newsletter_keywords:
        if keyword in subject:
            return True
    
    # Check for unsubscribe link in body
    if detect_unsubscribe_link(email_content):
        return True
    
    return False
