"""
Kevin's Personal Email MCP Server
=================================

一個極簡、安全、完全自控的 IMAP 郵件 MCP Server。

設計原則：
1. 最小化程式碼 - 只做需要的功能
2. 完全透明 - 每一行程式碼都可以審查
3. 無外部依賴（除了 fastmcp 和 imap-tools）
4. 只連接到你設定的郵件伺服器

功能：
- 讀取郵件列表
- 讀取郵件內容
- 移動郵件到資料夾
- 標記已讀/未讀
- 列出資料夾

作者: Kevin
版本: 0.1.0
"""

import sys
import os
from typing import Optional
from dataclasses import dataclass

# 確保 Windows 編碼正確
sys.stdout.reconfigure(encoding='utf-8')

from fastmcp import FastMCP
from imap_tools import MailBox, AND, OR

# ============================================================
# 設定區 - 修改這裡來配置你的郵件伺服器
# ============================================================

@dataclass
class EmailConfig:
    """郵件伺服器設定"""
    # IMAP 設定
    imap_host: str = os.getenv("IMAP_HOST", "imail.com.tw")
    imap_port: int = int(os.getenv("IMAP_PORT", "993"))

    # 認證資訊（建議使用環境變數）
    username: str = os.getenv("EMAIL_USERNAME", "")
    password: str = os.getenv("EMAIL_PASSWORD", "")

    # 預設資料夾
    default_folder: str = "INBOX"


# 載入設定
config = EmailConfig()

# 建立 MCP Server
mcp = FastMCP(
    name="Kevin Email Server",
    version="0.1.0",
    description="個人郵件管理 MCP Server - 極簡安全版"
)


# ============================================================
# 工具函數 - 內部使用
# ============================================================

def get_mailbox():
    """建立 IMAP 連線"""
    if not config.username or not config.password:
        raise ValueError("請設定 EMAIL_USERNAME 和 EMAIL_PASSWORD 環境變數")

    return MailBox(config.imap_host, config.imap_port)


# ============================================================
# MCP Tools - Claude 可以呼叫的功能
# ============================================================

@mcp.tool
def list_folders() -> list[str]:
    """
    列出所有郵件資料夾。

    Returns:
        資料夾名稱列表
    """
    with get_mailbox().login(config.username, config.password) as mailbox:
        folders = [folder.name for folder in mailbox.folder.list()]
        return folders


@mcp.tool
def list_emails(
    folder: str = "INBOX",
    unread_only: bool = False,
    limit: int = 20
) -> list[dict]:
    """
    列出資料夾中的郵件。

    Args:
        folder: 資料夾名稱（預設 INBOX）
        unread_only: 是否只顯示未讀郵件
        limit: 最多顯示幾封（預設 20）

    Returns:
        郵件摘要列表，包含 uid, from, subject, date, is_read
    """
    emails = []

    with get_mailbox().login(config.username, config.password) as mailbox:
        mailbox.folder.set(folder)

        # 建立查詢條件
        criteria = AND(seen=False) if unread_only else None

        for msg in mailbox.fetch(criteria, limit=limit, reverse=True):
            emails.append({
                "uid": msg.uid,
                "from": str(msg.from_),
                "subject": msg.subject or "(無主旨)",
                "date": msg.date.isoformat() if msg.date else None,
                "is_read": "\\Seen" in msg.flags
            })

    return emails


@mcp.tool
def read_email(uid: str, folder: str = "INBOX") -> dict:
    """
    讀取單封郵件的完整內容。

    Args:
        uid: 郵件 UID
        folder: 資料夾名稱

    Returns:
        郵件完整內容，包含 from, to, subject, date, body
    """
    with get_mailbox().login(config.username, config.password) as mailbox:
        mailbox.folder.set(folder)

        for msg in mailbox.fetch(AND(uid=uid)):
            return {
                "uid": msg.uid,
                "from": str(msg.from_),
                "to": [str(addr) for addr in msg.to],
                "cc": [str(addr) for addr in msg.cc],
                "subject": msg.subject or "(無主旨)",
                "date": msg.date.isoformat() if msg.date else None,
                "body": msg.text or msg.html or "(無內容)",
                "attachments": [att.filename for att in msg.attachments]
            }

    return {"error": f"找不到 UID={uid} 的郵件"}


@mcp.tool
def move_email(uid: str, from_folder: str, to_folder: str) -> dict:
    """
    移動郵件到另一個資料夾。

    Args:
        uid: 郵件 UID
        from_folder: 來源資料夾
        to_folder: 目標資料夾

    Returns:
        操作結果
    """
    with get_mailbox().login(config.username, config.password) as mailbox:
        mailbox.folder.set(from_folder)
        mailbox.move(uid, to_folder)

        return {
            "success": True,
            "message": f"已將郵件 {uid} 從 {from_folder} 移動到 {to_folder}"
        }


@mcp.tool
def mark_as_read(uid: str, folder: str = "INBOX") -> dict:
    """
    標記郵件為已讀。

    Args:
        uid: 郵件 UID
        folder: 資料夾名稱

    Returns:
        操作結果
    """
    with get_mailbox().login(config.username, config.password) as mailbox:
        mailbox.folder.set(folder)
        mailbox.flag(uid, "\\Seen", True)

        return {
            "success": True,
            "message": f"已將郵件 {uid} 標記為已讀"
        }


@mcp.tool
def mark_as_unread(uid: str, folder: str = "INBOX") -> dict:
    """
    標記郵件為未讀。

    Args:
        uid: 郵件 UID
        folder: 資料夾名稱

    Returns:
        操作結果
    """
    with get_mailbox().login(config.username, config.password) as mailbox:
        mailbox.folder.set(folder)
        mailbox.flag(uid, "\\Seen", False)

        return {
            "success": True,
            "message": f"已將郵件 {uid} 標記為未讀"
        }


@mcp.tool
def search_emails(
    keyword: str,
    folder: str = "INBOX",
    in_subject: bool = True,
    in_body: bool = False,
    limit: int = 20
) -> list[dict]:
    """
    搜尋郵件。

    Args:
        keyword: 搜尋關鍵字
        folder: 資料夾名稱
        in_subject: 是否搜尋主旨
        in_body: 是否搜尋內文
        limit: 最多顯示幾封

    Returns:
        符合條件的郵件列表
    """
    emails = []

    with get_mailbox().login(config.username, config.password) as mailbox:
        mailbox.folder.set(folder)

        # 建立搜尋條件
        criteria = None
        if in_subject and in_body:
            criteria = OR(subject=keyword, body=keyword)
        elif in_subject:
            criteria = AND(subject=keyword)
        elif in_body:
            criteria = AND(body=keyword)

        for msg in mailbox.fetch(criteria, limit=limit, reverse=True):
            emails.append({
                "uid": msg.uid,
                "from": str(msg.from_),
                "subject": msg.subject or "(無主旨)",
                "date": msg.date.isoformat() if msg.date else None,
            })

    return emails


@mcp.tool
def create_folder(folder_name: str) -> dict:
    """
    建立新資料夾。

    Args:
        folder_name: 資料夾名稱

    Returns:
        操作結果
    """
    with get_mailbox().login(config.username, config.password) as mailbox:
        mailbox.folder.create(folder_name)

        return {
            "success": True,
            "message": f"已建立資料夾: {folder_name}"
        }


# ============================================================
# 主程式入口
# ============================================================

if __name__ == "__main__":
    # 檢查設定
    if not config.username or not config.password:
        print("錯誤：請設定環境變數 EMAIL_USERNAME 和 EMAIL_PASSWORD")
        print("")
        print("範例：")
        print("  set EMAIL_USERNAME=your@email.com")
        print("  set EMAIL_PASSWORD=your_app_password")
        print("  set IMAP_HOST=imail.com.tw")
        sys.exit(1)

    print(f"啟動 Kevin Email MCP Server...")
    print(f"IMAP: {config.imap_host}:{config.imap_port}")
    print(f"帳號: {config.username}")
    print("")

    # 啟動 MCP Server
    mcp.run()