"""DEVONthink Bridge — AppleScript REST API 래퍼 (port 8093)"""

import json
import logging
import os
import subprocess

from dotenv import load_dotenv
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

load_dotenv()

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger("devonthink_bridge")

DT_APP = os.getenv("DEVONTHINK_APP_NAME", "DEVONthink")

app = FastAPI()


def _run_applescript(script: str, timeout: int = 15) -> str:
    """AppleScript 실행."""
    result = subprocess.run(
        ["osascript", "-e", script],
        capture_output=True, text=True, timeout=timeout,
    )
    if result.returncode != 0:
        raise RuntimeError(f"AppleScript error: {result.stderr.strip()}")
    return result.stdout.strip()


def _escape_as(s: str) -> str:
    """AppleScript 문자열 이스케이프."""
    return s.replace("\\", "\\\\").replace('"', '\\"')


@app.post("/save")
async def save_record(request: Request):
    body = await request.json()
    title = body.get("title", "Untitled")
    content = body.get("content", "")
    record_type = body.get("type", "markdown")
    database = body.get("database")
    group = body.get("group")
    tags = body.get("tags", [])

    # Map type to DEVONthink record type
    type_map = {"markdown": "markdown", "text": "txt", "html": "html"}
    dt_type = type_map.get(record_type, "markdown")

    # Build AppleScript
    esc_title = _escape_as(title)
    esc_content = _escape_as(content)
    tags_str = ", ".join(f'"{_escape_as(t)}"' for t in tags) if tags else ""

    if database:
        db_line = f'set theDB to open database "{_escape_as(database)}"'
    else:
        db_line = "set theDB to first database"

    if group:
        group_line = f'set theGroup to get record at "/{_escape_as(group)}" in theDB'
    else:
        group_line = "set theGroup to incoming group of theDB"

    script = f'''tell application "{DT_APP}"
    {db_line}
    {group_line}
    set theRecord to create record with {{name:"{esc_title}", type:{dt_type}, plain text:"{esc_content}"}} in theGroup
    {f'set tags of theRecord to {{{tags_str}}}' if tags_str else ''}
    set theUUID to uuid of theRecord
    set theName to name of theRecord
    return theUUID & "|" & theName
end tell'''

    try:
        result = _run_applescript(script)
        parts = result.split("|", 1)
        uuid_val = parts[0] if parts else result
        name_val = parts[1] if len(parts) > 1 else title
        logger.info(f"Record saved: {uuid_val} '{name_val}'")
        return JSONResponse({"success": True, "uuid": uuid_val, "name": name_val})
    except Exception as e:
        logger.error(f"Save failed: {e}")
        return JSONResponse({"success": False, "error": str(e)}, status_code=500)


@app.get("/databases")
async def list_databases():
    script = f'''tell application "{DT_APP}"
    set dbList to {{}}
    repeat with theDB in databases
        set end of dbList to (name of theDB) & "|" & (uuid of theDB)
    end repeat
    set AppleScript's text item delimiters to "\\n"
    return dbList as text
end tell'''

    try:
        result = _run_applescript(script)
        databases = []
        for line in result.strip().split("\n"):
            if "|" in line:
                parts = line.split("|", 1)
                databases.append({"name": parts[0], "uuid": parts[1]})
        return JSONResponse({"databases": databases})
    except Exception as e:
        logger.error(f"List databases failed: {e}")
        return JSONResponse({"databases": [], "error": str(e)}, status_code=500)


@app.get("/health")
async def health():
    devonthink_running = False
    try:
        result = _run_applescript(
            f'tell application "System Events" to return (name of processes) contains "{DT_APP}"',
            timeout=5,
        )
        devonthink_running = result.lower() == "true"
    except Exception:
        pass

    return {"status": "ok", "devonthink_running": devonthink_running}
