"""Helpers for extracting and formatting Outlook item data."""
import re
import urllib.parse

from outlook_desktop_mcp.tools._folder_constants import (
    BUSY_STATUS_NAMES,
    MEETING_STATUS_NAMES,
    RESPONSE_NAMES,
    TASK_STATUS_NAMES,
    IMPORTANCE_NAMES,
)


def truncate(text: str, max_length: int = 2000) -> str:
    if len(text) <= max_length:
        return text
    return text[:max_length] + "\n... [truncated]"


def strip_html(html: str) -> str:
    text = re.sub(r"<[^>]+>", "", html)
    text = re.sub(r"\s+", " ", text).strip()
    return text


def format_email_summary(item, encoding: str = "utf-8") -> dict:
    """Extract key fields from an Outlook MailItem into a dict."""
    return {
        "entry_id": item.EntryID,
        "subject": urllib.parse.unquote(item.Subject, encoding=encoding) if item.Subject else "(no subject)",
        "sender": getattr(item, "SenderEmailAddress", "unknown"),
        "sender_name": getattr(item, "SenderName", "unknown"),
        "received_time": str(item.ReceivedTime),
        "unread": bool(item.UnRead),
        "has_attachments": bool(item.Attachments.Count > 0),
        "attachment_count": item.Attachments.Count,
    }


def format_email_full(item, body_max_length: int = 5000, encoding: str = "utf-8") -> dict:
    """Extract full email details including body."""
    result = format_email_summary(item, encoding=encoding)
    result["to"] = item.To or ""
    result["cc"] = item.CC or ""
    result["body"] = truncate(item.Body or "", body_max_length)
    return result


# --- Calendar formatting ---


def format_event_summary(item, encoding: str = "utf-8") -> dict:
    """Extract key fields from an Outlook AppointmentItem."""
    return {
        "entry_id": item.EntryID,
        "subject": urllib.parse.unquote(item.Subject, encoding=encoding) if item.Subject else "(no subject)",
        "start": str(item.Start),
        "end": str(item.End),
        "duration": item.Duration,
        "location": item.Location or "",
        "organizer": item.Organizer or "",
        "is_recurring": bool(item.IsRecurring),
        "all_day": bool(item.AllDayEvent),
        "busy_status": BUSY_STATUS_NAMES.get(item.BusyStatus, "unknown"),
        "meeting_status": MEETING_STATUS_NAMES.get(item.MeetingStatus, "unknown"),
        "required_attendees": item.RequiredAttendees or "",
        "optional_attendees": item.OptionalAttendees or "",
    }


def format_event_full(item, body_max_length: int = 5000, encoding: str = "utf-8") -> dict:
    """Full event details including body."""
    result = format_event_summary(item, encoding=encoding)
    result["body"] = truncate(item.Body or "", body_max_length)
    result["reminder_set"] = bool(item.ReminderSet)
    result["reminder_minutes"] = (
        item.ReminderMinutesBeforeStart if item.ReminderSet else None
    )
    result["categories"] = item.Categories or ""
    result["response_status"] = RESPONSE_NAMES.get(item.ResponseStatus, "unknown")
    return result


# --- Task formatting ---


def format_task_summary(item, encoding: str = "utf-8") -> dict:
    """Extract key fields from an Outlook TaskItem."""
    return {
        "entry_id": item.EntryID,
        "subject": urllib.parse.unquote(item.Subject, encoding=encoding) if item.Subject else "(no subject)",
        "status": TASK_STATUS_NAMES.get(item.Status, "unknown"),
        "percent_complete": item.PercentComplete,
        "due_date": str(item.DueDate) if str(item.DueDate) != "01/01/4501" else None,
        "start_date": str(item.StartDate) if str(item.StartDate) != "01/01/4501" else None,
        "importance": IMPORTANCE_NAMES.get(item.Importance, "normal"),
        "complete": bool(item.Complete),
        "categories": item.Categories or "",
        "owner": item.Owner or "",
    }


def format_task_full(item, body_max_length: int = 5000, encoding: str = "utf-8") -> dict:
    """Full task details including body."""
    result = format_task_summary(item, encoding=encoding)
    result["body"] = truncate(item.Body or "", body_max_length)
    result["reminder_set"] = bool(item.ReminderSet)
    result["date_completed"] = (
        str(item.DateCompleted) if item.Complete else None
    )
    return result
