import PyPDF2
from PIL import Image
import io
import re
import os
import platform
from typing import Optional, Tuple
from fastapi import UploadFile


class FileProcessor:
    """Utility class for processing files and extracting text content"""
    
    @staticmethod
    async def extract_text_from_file(file: UploadFile) -> str:
        """Extract text from uploaded file (PDF only, images not supported without OCR)"""
        try:
            content = await file.read()
            
            if file.content_type.startswith('image/'):
                # Return a message instead of processing image
                raise Exception(
                    "Image text extraction requires OCR software. "
                    "Please use PDF files for text extraction, or "
                    "manually type the text content from the image."
                )
            elif file.content_type == 'application/pdf':
                return FileProcessor._extract_text_from_pdf(content)
            else:
                raise ValueError(f"Unsupported file type: {file.content_type}")
                
        except Exception as e:
            raise Exception(f"Error processing file: {str(e)}")
    
    @staticmethod
    def _extract_text_from_pdf(pdf_content: bytes) -> str:
        """Extract text from PDF file"""
        try:
            pdf_reader = PyPDF2.PdfReader(io.BytesIO(pdf_content))
            text = ""
            
            for page in pdf_reader.pages:
                text += page.extract_text() + "\n"
            
            return text.strip()
        except Exception as e:
            raise Exception(f"Error extracting text from PDF: {str(e)}")
    
    @staticmethod
    def extract_name_from_text(text: str) -> Optional[str]:
        """Extract name patterns from text"""
        # Simple name pattern matching - can be enhanced based on requirements
        name_patterns = [
            r'\b[A-Z][a-z]+ [A-Z][a-z]+\b',  # First Last
            r'\b[A-Z][a-z]+ [A-Z]\. [A-Z][a-z]+\b',  # First M. Last
            r'\b[A-Z][a-z]+ [A-Z][a-z]+ [A-Z][a-z]+\b'  # First Middle Last
        ]
        
        for pattern in name_patterns:
            matches = re.findall(pattern, text)
            if matches:
                return matches[0]  # Return first match
        
        return None
    
    @staticmethod
    def extract_address_from_text(text: str) -> Optional[str]:
        """Extract address patterns from text"""
        # Address pattern matching - can be enhanced based on requirements
        address_patterns = [
            r'\d+\s+[A-Za-z\s]+(?:Street|St|Avenue|Ave|Road|Rd|Lane|Ln|Drive|Dr|Boulevard|Blvd|Way|Place|Pl)',
            r'\d+\s+[A-Za-z\s]+,\s*[A-Za-z\s]+,\s*[A-Z]{2}\s+\d{5}',  # US format
            r'\d+\s+[A-Za-z\s]+\s+[A-Za-z\s]+\s+\d{4,6}'  # General format
        ]
        
        for pattern in address_patterns:
            matches = re.findall(pattern, text, re.IGNORECASE)
            if matches:
                return matches[0]  # Return first match
        
        return None
    
    @staticmethod
    def match_text_content(extracted_text: str, search_text: str, match_type: str) -> Tuple[bool, Optional[str]]:
        """Match extracted content with search text based on type"""
        if match_type == "name":
            extracted_name = FileProcessor.extract_name_from_text(extracted_text)
            if extracted_name and search_text.lower() in extracted_name.lower():
                return True, extracted_name
        elif match_type == "address":
            extracted_address = FileProcessor.extract_address_from_text(extracted_text)
            if extracted_address and search_text.lower() in extracted_address.lower():
                return True, extracted_address
        
        return False, None