"""Process and analyze email attachments."""
import logging
import re
from typing import Dict, List, Any, Optional
from pathlib import Path

try:
    from PyPDF2 import PdfReader
except ImportError:
    PdfReader = None

try:
    from docx import Document
except ImportError:
    Document = None

logger = logging.getLogger(__name__)


class AttachmentAnalyzer:
    """Analyze attachment content for classification hints."""

    def __init__(self, max_size_bytes: int = 5_000_000):
        """Initialize attachment analyzer."""
        self.max_size_bytes = max_size_bytes  # 5MB limit for processing

    def analyze_attachment(self, attachment_data: bytes, filename: str, mime_type: str) -> Dict[str, Any]:
        """
        Analyze single attachment and extract features.

        Returns:
            {
                'type': 'pdf'|'docx'|'xlsx'|'image'|'unknown',
                'size': bytes,
                'text_content': extracted text or None,
                'detected_keywords': list of detected patterns,
                'classification_hints': list of hints for classification
            }
        """
        result = {
            'filename': filename,
            'mime_type': mime_type,
            'size': len(attachment_data),
            'type': self._classify_type(filename, mime_type),
            'text_content': None,
            'detected_keywords': [],
            'classification_hints': []
        }

        # Check size limit
        if len(attachment_data) > self.max_size_bytes:
            logger.debug(f"Attachment {filename} too large ({len(attachment_data)} bytes), skipping content analysis")
            result['classification_hints'].append('large_attachment')
            return result

        # Extract content based on type
        if result['type'] == 'pdf':
            result.update(self._analyze_pdf(attachment_data, filename))
        elif result['type'] == 'docx':
            result.update(self._analyze_docx(attachment_data, filename))
        elif result['type'] == 'xlsx':
            result['classification_hints'].append('spreadsheet')
        elif result['type'] == 'image':
            result['classification_hints'].append('image_file')

        return result

    def _classify_type(self, filename: str, mime_type: str) -> str:
        """Classify attachment type."""
        filename_lower = filename.lower()

        if 'pdf' in mime_type or filename_lower.endswith('.pdf'):
            return 'pdf'
        elif 'word' in mime_type or filename_lower.endswith(('.doc', '.docx')):
            return 'docx'
        elif 'excel' in mime_type or 'spreadsheet' in mime_type or filename_lower.endswith(('.xls', '.xlsx')):
            return 'xlsx'
        elif 'image' in mime_type or filename_lower.endswith(('.png', '.jpg', '.jpeg', '.gif')):
            return 'image'
        else:
            return 'unknown'

    def _analyze_pdf(self, data: bytes, filename: str) -> Dict[str, Any]:
        """Extract and analyze PDF content."""
        result = {
            'text_content': None,
            'detected_keywords': [],
            'classification_hints': ['pdf']
        }

        if not PdfReader:
            logger.debug("PyPDF2 not available, skipping PDF analysis")
            return result

        try:
            from io import BytesIO
            pdf_file = BytesIO(data)
            reader = PdfReader(pdf_file)

            # Extract text from all pages
            text = ""
            for page in reader.pages[:5]:  # First 5 pages only
                try:
                    text += page.extract_text()
                except Exception as e:
                    logger.debug(f"Error extracting page from PDF: {e}")

            result['text_content'] = text[:1000] if text else None

            # Analyze extracted text
            if text:
                text_lower = text.lower()
                result['detected_keywords'] = self._extract_keywords(text_lower)
                result['classification_hints'].extend(self._get_classification_hints(text_lower))

            logger.debug(f"Analyzed PDF {filename}: {len(text)} chars extracted")

        except Exception as e:
            logger.debug(f"Error analyzing PDF {filename}: {e}")

        return result

    def _analyze_docx(self, data: bytes, filename: str) -> Dict[str, Any]:
        """Extract and analyze DOCX content."""
        result = {
            'text_content': None,
            'detected_keywords': [],
            'classification_hints': ['docx']
        }

        if not Document:
            logger.debug("python-docx not available, skipping DOCX analysis")
            return result

        try:
            from io import BytesIO
            doc = Document(BytesIO(data))

            # Extract text from all paragraphs
            text = "\n".join([para.text for para in doc.paragraphs])
            result['text_content'] = text[:1000] if text else None

            # Analyze extracted text
            if text:
                text_lower = text.lower()
                result['detected_keywords'] = self._extract_keywords(text_lower)
                result['classification_hints'].extend(self._get_classification_hints(text_lower))

                # Check for contract indicators
                if any(p in text_lower for p in ['contract', 'agreement', 'terms and conditions']):
                    result['classification_hints'].append('contract_document')

            logger.debug(f"Analyzed DOCX {filename}: {len(text)} chars extracted")

        except Exception as e:
            logger.debug(f"Error analyzing DOCX {filename}: {e}")

        return result

    def _extract_keywords(self, text: str) -> List[str]:
        """Extract keywords from text."""
        keywords = []

        # Financial keywords
        if any(p in text for p in ['invoice', 'bill', 'payment', 'receipt']):
            keywords.append('financial')
        if any(p in text for p in ['account', 'account number', 'acct #']):
            keywords.append('account_reference')
        if re.search(r'\$[\d,]+\.?\d*', text):
            keywords.append('price_found')

        # Legal keywords
        if any(p in text for p in ['contract', 'agreement', 'terms', 'legal']):
            keywords.append('legal_document')
        if any(p in text for p in ['signature', 'sign here', 'authorized']):
            keywords.append('signature_required')

        # Meeting keywords
        if any(p in text for p in ['meeting', 'agenda', 'minutes', 'discussion']):
            keywords.append('meeting_document')

        # Report keywords
        if any(p in text for p in ['report', 'analysis', 'summary', 'findings']):
            keywords.append('report_document')

        return keywords

    def _get_classification_hints(self, text: str) -> List[str]:
        """Get classification hints from text content."""
        hints = []

        # Financial emails
        if re.search(r'invoice\s*#?\d+', text, re.IGNORECASE):
            hints.append('has_invoice')
        if re.search(r'receipt\s*#?\d+', text, re.IGNORECASE):
            hints.append('has_receipt')
        if re.search(r'order\s*#?\d+', text, re.IGNORECASE):
            hints.append('has_order')

        # Authentication
        if re.search(r'\b\d{4,6}\b', text):
            hints.append('has_codes')

        # Transactional
        if any(p in text for p in ['tracking', 'shipped', 'delivery', 'order status']):
            hints.append('transactional')

        return hints
