import time
import webbrowser
import ctypes
import json
import os
from pathlib import Path
from datetime import datetime

from mcp.server.fastmcp import FastMCP


# =========================================================
# 1. MCP SERVER
# =========================================================

mcp = FastMCP("Focus Break MCP Server")


# =========================================================
# 2. PATHS
# =========================================================

BASE_DIR = Path(__file__).resolve().parent.parent

DATA_DIR = BASE_DIR / "data"

SHAME_LOG_FILE = DATA_DIR / "shame_log.txt"

SESSION_FILE = DATA_DIR / "session.json"


DATA_DIR.mkdir(
    parents=True,
    exist_ok=True
)


# =========================================================
# 3. CREATE SHAME LOG
# =========================================================

if not SHAME_LOG_FILE.exists():

    SHAME_LOG_FILE.write_text(
        "",
        encoding="utf-8"
    )


# =========================================================
# 4. CREATE PERSISTENT SESSION
# =========================================================

if not SESSION_FILE.exists():

    SESSION_FILE.write_text(
        json.dumps(
            {
                "started_at": time.time()
            }
        ),
        encoding="utf-8"
    )


# =========================================================
# 5. SONG CATALOG
# =========================================================

SONGS = {

    "lofi": {
        "name": "Chill Lofi",
        "url": "https://www.youtube.com/watch?v=jfKfPfyJRdk"
    },

    "bollywood": {
        "name": "Bollywood Energy",
        "url": "https://www.youtube.com/"
    },

    "metal": {
        "name": "Heavy Metal",
        "url": "https://www.youtube.com/"
    },

    "fun": {
        "name": "Random Fun Break",
        "url": "https://www.youtube.com/"
    }
}


# =========================================================
# RESOURCE 1: TIMER
# =========================================================

@mcp.resource(
    "timer://session",
    mime_type="application/json"
)
def get_timer_session() -> dict:

    session_data = json.loads(
        SESSION_FILE.read_text(
            encoding="utf-8"
        )
    )

    started_at = session_data["started_at"]

    elapsed_seconds = (
        time.time() - started_at
    )

    active_minutes = int(
        elapsed_seconds / 60
    )

    return {
        "status": "working",
        "active_minutes": active_minutes
    }


# =========================================================
# RESOURCE 2: SHAME LOG
# =========================================================

@mcp.resource(
    "shame://log",
    mime_type="text/plain"
)
def get_shame_log() -> str:

    content = SHAME_LOG_FILE.read_text(
        encoding="utf-8"
    ).strip()

    if not content:

        return "No break violations recorded yet."

    return content


# =========================================================
# RESOURCE 3: SONG CATALOG
# =========================================================

@mcp.resource(
    "songs://catalog",
    mime_type="application/json"
)
def get_song_catalog() -> dict:

    return SONGS


# =========================================================
# TOOL 1: SET VOLUME
# =========================================================

@mcp.tool()
def set_volume(level: int = 50) -> str:

    if level < 0 or level > 100:

        return (
            "Volume must be between "
            "0 and 100."
        )

    try:

        from pycaw.pycaw import (
            AudioUtilities
        )

        device = AudioUtilities.GetSpeakers()

        volume = device.EndpointVolume

        volume.SetMasterVolumeLevelScalar(
            level / 100,
            None
        )

        return (
            f"System volume set "
            f"to {level}%."
        )

    except Exception as error:

        return (
            f"Could not change volume: "
            f"{error}"
        )


# =========================================================
# TOOL 2: PLAY SONG
# =========================================================
@mcp.tool()
def play_song(song_url: str) -> str:
    """
    Opens the YouTube URL immediately
    using the Windows default browser.
    """

    if not song_url.startswith(
        ("http://", "https://")
    ):
        return "Invalid song URL."

    try:
        os.startfile(song_url)

        return f"Browser launched: {song_url}"

    except Exception as error:
        return f"Could not open browser: {error}"


# =========================================================
# TOOL 3: LOCK SCREEN
# =========================================================

@mcp.tool()
def lock_screen() -> str:

    try:

        ctypes.windll.user32.LockWorkStation()

        return "Windows workstation locked."

    except Exception as error:

        return (
            f"Could not lock screen: "
            f"{error}"
        )


# =========================================================
# TOOL 4: WRITE SHAME LOG
# =========================================================

@mcp.tool()
def write_shame_log(message: str) -> str:

    timestamp = datetime.now().strftime(
        "%d %B %Y, %I:%M %p"
    )

    entry = (
        f"{timestamp}: "
        f"{message}\n"
    )

    with SHAME_LOG_FILE.open(
        "a",
        encoding="utf-8"
    ) as file:

        file.write(entry)

    return (
        f"Shame log updated: "
        f"{entry.strip()}"
    )


# =========================================================
# TOOL 5: RESET SESSION
# =========================================================

@mcp.tool()
def reset_session() -> str:

    SESSION_FILE.write_text(
        json.dumps(
            {
                "started_at": time.time()
            }
        ),
        encoding="utf-8"
    )

    return "Focus session timer reset."


# =========================================================
# MCP PROMPT
# =========================================================

@mcp.prompt(
    name="check-focus",
    description=(
        "Decide whether the user needs "
        "a forced focus break."
    )
)
def check_focus() -> str:

    return """
You are a strict focus-break assistant.

TEST MODE IS ACTIVE.

A break is required when active_minutes >= 1.

Choose a song based on session duration.

Rules:

1-2 minutes:
Choose lofi.

3-4 minutes:
Choose Bollywood or fun energetic music.

5+ minutes:
Choose the strongest energetic option.

Read the shame history.

If the user has cheated previous breaks,
your break message should become stricter.

Never execute volume changes,
browser actions or screen locking
without human approval.

Return a suitable song choice and
a short break message.
"""


# =========================================================
# START MCP SERVER
# =========================================================

if __name__ == "__main__":

    mcp.run()