TOOL_NAME = "extract_email_attachments"
TOOL_DESCRIPTION = """Fetch emails from Outlook that contain attachments, extract and save attachments to a specified folder, returning the list of saved file paths"""
TOOL_ARGS = '{"folder_path": {"type": "string", "description": "Directory path where attachments should be saved"}, "count": {"type": "integer", "default": 50, "description": "Maximum number of emails to check"}, "unread_only": {"type": "boolean", "default": false, "description": "Only check unread emails"}, "since": {"type": "string", "description": "Filter emails received on or after this date (YYYY-MM-DD)"}, "sender": {"type": "string", "description": "Filter by sender email address (partial match)"}, "subject_contains": {"type": "string", "description": "Filter by subject containing this text"}}'

import os
import pythoncom
import win32com.client
from datetime import datetime
from tools._std import tool_ok, tool_error

def run(args: dict) -> str:
    folder_path = args.get('folder_path', '.')
    count = args.get('count', 50)
    unread_only = args.get('unread_only', False)
    since = args.get('since')
    sender = args.get('sender')
    subject_contains = args.get('subject_contains')
    
    # Ensure folder exists
    os.makedirs(folder_path, exist_ok=True)
    
    # Initialize COM
    pythoncom.CoInitialize()
    
    try:
        outlook = win32com.client.Dispatch('Outlook.Application')
        namespace = outlook.GetNamespace('MAPI')
        inbox = namespace.GetDefaultFolder(6)  # 6 = Inbox
        
        items = inbox.Items
        items.Sort('[ReceivedTime]', True)  # Newest first
        
        # Build filter if needed
        filters = []
        if since:
            try:
                since_date = datetime.strptime(since, '%Y-%m-%d')
                since_str = since_date.strftime('%m/%d/%Y')
                filters.append(f"[ReceivedTime] >= '{since_str}'")
            except ValueError:
                return tool_error(
                    "'since' must be in YYYY-MM-DD format",
                    {'since': since},
                )
        
        if unread_only:
            filters.append("[Unread] = True")
        
        if filters:
            filter_str = " AND ".join(filters)
            items = items.Restrict(filter_str)
        
        extracted_files = []
        processed = 0
        
        for item in items:
            if processed >= count:
                break
            processed += 1
            
            # Check sender filter
            if sender and sender.lower() not in str(item.Sender).lower():
                continue
            
            # Check subject filter
            if subject_contains and subject_contains.lower() not in str(item.Subject).lower():
                continue
            
            # Check for attachments
            if item.Attachments.Count == 0:
                continue
            
            email_info = f"[{item.ReceivedTime}] {item.Subject}"
            
            for i in range(1, item.Attachments.Count + 1):
                try:
                    attachment = item.Attachments.Item(i)
                    filename = attachment.FileName
                    
                    # Skip inline/cid attachments (small images usually)
                    if attachment.Size < 1024 and filename.lower().endswith(('.png', '.jpg', '.gif', '.jpeg')):
                        continue
                    
                    save_path = os.path.join(folder_path, filename)
                    
                    # Handle duplicate filenames
                    counter = 1
                    base_name, ext = os.path.splitext(filename)
                    while os.path.exists(save_path):
                        save_path = os.path.join(folder_path, f"{base_name}_{counter}{ext}")
                        counter += 1
                    
                    attachment.SaveAsFile(save_path)
                    extracted_files.append({
                        'file': save_path,
                        'email': email_info,
                        'size': attachment.Size
                    })
                except Exception as e:
                    continue
        
        if not extracted_files:
            return tool_ok({"files": [], "checked": processed}, f"No attachments found. Checked {processed} emails.")
        
        return tool_ok({"files": extracted_files, "checked": processed}, f"Extracted {len(extracted_files)} attachment(s) from {processed} email(s)")
        
    except Exception as e:
        return tool_error(f"Error extracting attachments: {str(e)}")
    finally:
        pythoncom.CoUninitialize()
