#!/usr/bin/env python3
"""
Plaud MCP Server for MPM
Connects to the Plaud API and exposes tools for listing, searching,
and reading transcripts, summaries, and notes from Plaud recordings.

Credentials (checked in order):
  1. PLAUD_TOKEN environment variable
  2. ~/.plaud/tokens-mcp.json  (desktop app authToken — valid ~6 months)
  3. ~/.plaud/config.json      (manually imported 24-hour web token)

To renew: re-run plaud_decrypt_tokens.py from the Claude CoWork folder.
"""

import gzip
import json
import os
import subprocess
import urllib.parse
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional

from mcp.server.fastmcp import FastMCP

# ── Configuration ─────────────────────────────────────────────────────────────
PLAUD_REGION = os.environ.get("PLAUD_REGION", "us")
BASE_URL = "https://api.plaud.eu" if PLAUD_REGION == "eu" else "https://api.plaud.ai"
CONFIG_PATH      = Path.home() / ".plaud" / "config.json"
TOKENS_MCP_PATH  = Path.home() / ".plaud" / "tokens-mcp.json"


# ── Token resolution ──────────────────────────────────────────────────────────

def _load_token() -> Optional[str]:
    # 1. Environment variable override
    env_token = os.environ.get("PLAUD_TOKEN", "").strip()
    if env_token:
        return env_token

    # 2. tokens-mcp.json — desktop app authToken (~6-month expiry)
    #    Written by plaud_decrypt_tokens.py; renew by re-running that script.
    if TOKENS_MCP_PATH.exists():
        try:
            data = json.loads(TOKENS_MCP_PATH.read_text())
            t = data.get("access_token", "").strip()
            if t:
                return t
        except Exception:
            pass

    # 3. config.json — manually imported 24-hour web token (legacy fallback)
    if CONFIG_PATH.exists():
        try:
            data = json.loads(CONFIG_PATH.read_text())
            token_block = data.get("token")
            if isinstance(token_block, dict):
                t = (token_block.get("token") or token_block.get("accessToken") or "").strip()
                if t:
                    return t
            if isinstance(token_block, str) and token_block.strip():
                return token_block.strip()
        except Exception:
            pass

    return None


def _get_token() -> str:
    token = _load_token()
    if not token:
        raise RuntimeError(
            "No Plaud token found. Run the plaud-connector import-token command "
            "or set the PLAUD_TOKEN environment variable."
        )
    return token


# ── HTTP helpers ──────────────────────────────────────────────────────────────

def _api_get(path: str, params: Optional[dict] = None) -> dict:
    """GET request to the Plaud API using curl (bypasses Cloudflare browser check)."""
    token = _get_token()
    url = f"{BASE_URL}{path}"
    if params:
        query = "&".join(
            f"{k}={urllib.parse.quote(str(v))}"
            for k, v in params.items() if v is not None
        )
        if query:
            url = f"{url}?{query}"

    result = subprocess.run(
        ["curl", "-s", "-f",
         "-H", f"Authorization: Bearer {token}",
         "-H", "Accept: application/json",
         url],
        capture_output=True, text=True, timeout=30,
    )
    if result.returncode != 0:
        raise RuntimeError(
            f"Plaud API error (curl exit {result.returncode}): {result.stderr[:300]}"
        )
    try:
        return json.loads(result.stdout)
    except json.JSONDecodeError:
        raise RuntimeError(f"Invalid JSON from Plaud API: {result.stdout[:300]}")


def _fetch_s3_json(url: str) -> object:
    """Fetch and decompress a gzipped JSON from a signed S3 URL."""
    result = subprocess.run(
        ["curl", "-s", "-f", url],
        capture_output=True, timeout=30,
    )
    if result.returncode != 0:
        raise RuntimeError(f"S3 fetch failed (curl exit {result.returncode})")
    try:
        content = gzip.decompress(result.stdout)
    except OSError:
        content = result.stdout  # Not gzipped
    return json.loads(content.decode("utf-8"))


# ── Data helpers ──────────────────────────────────────────────────────────────

def _fmt_duration(ms: int) -> str:
    mins = ms // 60000
    if mins < 60:
        return f"{mins}m"
    return f"{mins // 60}h {mins % 60}m"


def _fmt_date(ts_ms: int) -> str:
    try:
        dt = datetime.fromtimestamp(ts_ms / 1000, tz=timezone.utc)
        return dt.strftime("%Y-%m-%d %H:%M UTC")
    except Exception:
        return str(ts_ms)


def _summarise_recording(r: dict) -> dict:
    """Return a compact dict suitable for listing."""
    return {
        "id": r.get("id", ""),
        "title": r.get("filename") or r.get("file_name") or r.get("title") or "(untitled)",
        "date": _fmt_date(r.get("start_time", 0)),
        "duration": _fmt_duration(r.get("duration", 0)),
        "has_transcript": bool(r.get("is_trans")),
        "has_summary": bool(r.get("auto_sum_note") or r.get("is_sum")),
    }


def _format_transcript(segments: list) -> str:
    """Format transcript segments into readable text."""
    lines = []
    current_speaker = None
    for seg in segments:
        speaker = seg.get("speaker") or seg.get("original_speaker") or ""
        content = seg.get("content", "").strip()
        if not content:
            continue
        if speaker and speaker != current_speaker:
            if lines:
                lines.append("")
            lines.append(f"[{speaker}]")
            current_speaker = speaker
        lines.append(content)
    return "\n".join(lines)


def _get_content_url(content_list: list, data_type: str) -> Optional[str]:
    """Find a data_link URL from content_list by data_type."""
    for item in content_list:
        if item.get("data_type") == data_type and item.get("data_link"):
            return item["data_link"]
    return None


# ── MCP server ────────────────────────────────────────────────────────────────
mcp = FastMCP("plaud-mpm")


@mcp.tool()
def plaud_list_recordings(
    limit: int = 50,
    only_with_transcript: bool = False,
) -> str:
    """
    List Plaud recordings newest-first.

    Args:
        limit: Max number to return (default 50, max 200).
        only_with_transcript: If true, only return recordings that have a transcript.
    """
    resp = _api_get("/file/simple/web")
    if isinstance(resp, dict):
        recordings = resp.get("data_file_list") or resp.get("data") or []
    else:
        recordings = resp if isinstance(resp, list) else []

    if only_with_transcript:
        recordings = [r for r in recordings if r.get("is_trans")]

    recordings = recordings[:min(limit, 200)]
    return json.dumps([_summarise_recording(r) for r in recordings], indent=2)


@mcp.tool()
def plaud_search_recordings(
    title_contains: Optional[str] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    only_with_transcript: bool = False,
    max_results: int = 20,
) -> str:
    """
    Search recordings by title and/or date range.

    Args:
        title_contains: Substring to match in the recording title (case-insensitive).
        start_date: ISO date string, e.g. '2026-04-01'. Only recordings on or after this date.
        end_date: ISO date string, e.g. '2026-05-01'. Only recordings on or before this date.
        only_with_transcript: If true, only return recordings thave a transcript.
        max_results: Max number of results to return (default 20).
    """
    resp = _api_get("/file/simple/web")
    if isinstance(resp, dict):
        recordings = resp.get("data_file_list") or resp.get("data") or []
    else:
        recordings = resp if isinstance(resp, list) else []

    def matches(r: dict) -> bool:
        if only_with_transcript and not r.get("is_trans"):
            return False
        title = (r.get("filename") or r.get("file_name") or r.get("title") or "").lower()
        if title_contains and title_contains.lower() not in title:
            return False
        if start_date or end_date:
            ts_ms = r.get("start_time", 0)
            rec_date = datetime.fromtimestamp(ts_ms / 1000, tz=timezone.utc).date()
            if start_date and rec_date < datetime.fromisoformat(start_date).date():
                return False
            if end_date and rec_date > datetime.fromisoformat(end_date).date():
                return False
        return True

    matched = [r for r in recordings if matches(r)][:max_results]
    return json.dumps([_summarise_recording(r) for r in matched], indent=2)


@mcp.tool()
def plaud_get_transcript(recording_id: str) -> str:
    """
    Get the full transcript for a Plaud recording.

    Args:
        recording_id: The recording ID (from plaud_list_recordings).
    """
    resp = _api_get(f"/file/detail/{recording_id}")
    data = resp.get("data", resp) if isinstance(resp, dict) else resp

    title = data.get("file_name") or data.get("filename") or data.get("title") or "(untitled)"
    content_list = data.get("content_list") or []
    transcript = ""

    # Try polished transcript first, fall back to raw
    for dtype in ("transaction_polish", "transaction"):
        url = _get_content_url(content_list, dtype)
        if url:
            try:
                segments = _fetch_s3_json(url)
                if isinstance(segments, list):
                    transcript = _format_transcript(segments)
                    if transcript:
                        break
            except Exception as e:
                transcript = f"Error fetching transcript: {e}"
                break

    return json.dumps({
        "id": recording_id,
        "title": title,
        "date": _fmt_date(data.get("start_time", 0)),
        "duration": _fmt_duration(data.get("duration", 0)),
        "transcript": transcript or "No transcript available for this recording.",
    }, indent=2)


@mcp.tool()
def plaud_get_summary(recording_id: str) -> str:
    """
    Get the AI-generated summary/outline for a Plaud recording.

    Args:
        recording_id: The recording ID (from plaud_list_recordings).
    """
    resp = _api_get(f"/file/detail/{recording_id}")
    data = resp.get("data", resp) if isinstance(resp, dict) else resp

    title = data.get("file_name") or data.get("filename") or data.get("title") or "(untitled)"
    content_list = data.get("content_list") or []
    summary = ""

    url = _get_content_url(content_list, "outline")
    if url:
        try:
            outline_data = _fetch_s3_json(url)
            if isinstance(outline_data, dict):
                summary = json.dumps(outline_data, indent=2)
            elif isinstance(outline_data, list):
                parts = []
                for item in outline_data:
                    if isinstance(item, dict):
                        parts.append(item.get("content") or item.get("text") or str(item))
                    else:
                        parts.append(str(item))
                summary = "\n\n".join(p for p in parts if p)
            else:
                summary = str(outline_data)
        except Exception as e:
            summary = f"Error fetching summary: {e}"

    return json.dumps({
        "id": recording_id,
        "title": title,
        "date": _fmt_date(data.get("start_time", 0)),
        "summary": summary or "No summary available for this recording.",
    }, indent=2)


@mcp.tool()
def plaud_get_notes(recording_id: str) -> str:
    """
    Get AI-generated notes and action items for a Plaud recording.
    Returns all note entries from the content_list (action items, key points, etc.).

    Args:
        recording_id: The recording ID (from plaud_list_recordings).
    """
    resp = _api_get(f"/file/detail/{recording_id}")
    data = resp.get("data", resp) if isinstance(resp, dict) else resp

    title = data.get("file_name") or data.get("filename") or data.get("title") or "(untitled)"
    content_list = data.get("content_list") or []
    notes = []

    for item in content_list:
        dtype = item.get("data_type", "")
        url = item.get("data_link")
        if not url or dtype in ("transaction", "transaction_polish"):
            continue  # Skip raw transcript types

        note_title = item.get("data_title") or item.get("data_tab_name") or dtype
        try:
            note_data = _fetch_s3_json(url)
            if isinstance(note_data, list):
                content = "\n".join(
                    str(seg.get("content") or seg.get("text") or seg)
                    for seg in note_data if seg
                )
            elif isinstance(note_data, dict):
                content = json.dumps(note_data, indent=2)
            else:
                content = str(note_data)

            if content.strip():
                notes.append({"type": dtype, "title": note_title, "content": content})
        except Exception as e:
            notes.append({"type": dtype, "title": note_title, "content": f"Error: {e}"})

    return json.dumps({
        "id": recording_id,
        "title": title,
        "date": _fmt_date(data.get("start_time", 0)),
        "notes": notes if notes else [{"type": "none", "content": "No notes available for this recording."}],
    }, indent=2)


@mcp.tool()
def plaud_get_recording_detail(recording_id: str) -> str:
    """
    Get full metadata for a Plaud recording including title, date, duration,
    transcript availability, and available content types.

    Args:
        recording_id: The recording ID (from plaud_list_recordings).
    """
    resp = _api_get(f"/file/detail/{recording_id}")
    data = resp.get("data", resp) if isinstance(resp, dict) else resp

    content_list = data.get("content_list") or []
    content_types = [item.get("data_type") for item in content_list if item.get("data_type")]

    return json.dumps({
        "id": recording_id,
        "title": data.get("file_name") or data.get("filename") or data.get("title") or "(untitled)",
        "date": _fmt_date(data.get("start_time", 0)),
        "duration": _fmt_duration(data.get("duration", 0)),
        "has_transcript": "transaction" in content_types or "transaction_polish" in content_types,
        "has_summary": "outline" in content_types,
        "content_types": content_types,
        "device": data.get("serial_number") or data.get("device_name") or "unknown",
        "tags": data.get("filetag_id_list") or data.get("filetag") or [],
    }, indent=2)


@mcp.tool()
def plaud_user_info() -> str:
    """Get the current Plaud account information and connection status."""
    return json.dumps({
        "region": PLAUD_REGION,
        "api_base": BASE_URL,
        "token_loaded": bool(_load_token()),
    }, indent=2)


if __name__ == "__main__":
    mcp.run()
