"""notes feishu sidecar：HTTP 包一层 markdown-to-feishu。

POST /convert  {md_path, title?, existing_doc_id?}
  → 跑 markdown-to-feishu，parse 最后那段 JSON，返回 {doc_id, url}
"""

import json
import logging
import os
import re
import subprocess
from pathlib import Path
from typing import Optional

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(name)s: %(message)s')
log = logging.getLogger('feishu')

app = FastAPI()


@app.get('/healthz')
def healthz():
    return {'ok': True}


class ConvertReq(BaseModel):
    md_path: str
    title: Optional[str] = None
    existing_doc_id: Optional[str] = None


@app.post('/convert')
def convert(req: ConvertReq):
    md = Path(req.md_path)
    if not md.exists():
        raise HTTPException(400, f'md not found: {md}')

    cmd = ['/usr/local/bin/markdown-to-feishu', str(md), '--as', 'user']
    if req.existing_doc_id:
        cmd += ['--update', req.existing_doc_id]
    if req.title:
        cmd += ['--title', req.title]
    log.info("run: %s", ' '.join(cmd))

    env = os.environ.copy()
    # markdown-to-feishu state file 放 PVC，重启不丢
    env['MD2FEISHU_STATE_DIR'] = '/data/feishu-state'
    Path('/data/feishu-state').mkdir(parents=True, exist_ok=True)

    try:
        proc = subprocess.run(
            cmd, capture_output=True, text=True, timeout=600, env=env,
            cwd=str(md.parent),
        )
    except subprocess.TimeoutExpired:
        raise HTTPException(504, 'markdown-to-feishu timeout (>10min)')

    # exit code 2 = embeds 有失败，但 doc 创建成功，仍 parse stdout
    if proc.returncode not in (0, 2):
        log.warning("md2feishu exit=%d stderr=%s", proc.returncode, proc.stderr[-500:])
        raise HTTPException(502, f'md2feishu exit {proc.returncode}: '
                                 f'{proc.stderr.strip()[-400:]}')

    # 取 stdout 里最后一段 JSON 对象（script 的 final print）
    out = proc.stdout.strip()
    # 从后往前找第一个 '{'，取到末尾
    last_open = out.rfind('{')
    if last_open < 0:
        raise HTTPException(502, f'md2feishu no json output. stdout tail: {out[-400:]}')
    try:
        data = json.loads(out[last_open:])
    except json.JSONDecodeError as e:
        raise HTTPException(502, f'md2feishu json parse: {e}; tail: {out[-400:]}')

    doc_id = data.get('doc_id')
    url = data.get('url')
    if not doc_id or not url:
        raise HTTPException(502, f'md2feishu missing doc_id/url: {data}')
    log.info("ok: doc_id=%s url=%s embeds=%s",
             doc_id, url, data.get('embeds_inserted'))
    return {
        'doc_id': doc_id,
        'url': url,
        'embeds_inserted': data.get('embeds_inserted', 0),
        'embeds_failed': data.get('embeds_failed', 0),
    }
