#!/usr/bin/env python3
"""Servidor do figma AlteVita + API de comentários compartilhados.
Serve os arquivos desta pasta e guarda comentários em comments.json (lista).
Endpoints:
  GET    /api/comments          -> lista de comentários
  POST   /api/comments          -> cria {screen,label,author,text}
  PATCH  /api/comments          -> edita {id,text[,author]}
  DELETE /api/comments          -> apaga {id}
Uso: python3 serve.py [porta]  (padrão 8080)
"""
import json, os, sys, time, uuid, datetime, threading
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlparse

DIR = os.path.dirname(os.path.abspath(__file__))
CF = os.path.join(DIR, "comments.json")
LOCK = threading.Lock()

def load():
    try:
        with open(CF, encoding="utf-8") as f:
            data = json.load(f)
        return data if isinstance(data, list) else []
    except Exception:
        return []

def save(items):
    tmp = CF + ".tmp"
    with open(tmp, "w", encoding="utf-8") as f:
        json.dump(items, f, ensure_ascii=False, indent=2)
    os.replace(tmp, CF)

class H(SimpleHTTPRequestHandler):
    def __init__(self, *a, **k):
        super().__init__(*a, directory=DIR, **k)

    def end_headers(self):
        # nunca cacheia: edição no HTML aparece no próximo F5
        self.send_header("Cache-Control", "no-store, must-revalidate")
        super().end_headers()

    def _json(self, obj, code=200):
        b = json.dumps(obj, ensure_ascii=False).encode("utf-8")
        self.send_response(code)
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.send_header("Content-Length", str(len(b)))
        self.send_header("Access-Control-Allow-Origin", "*")
        self.end_headers()
        self.wfile.write(b)

    def _body(self):
        try:
            n = int(self.headers.get("Content-Length", 0))
            return json.loads(self.rfile.read(n) or b"{}")
        except Exception:
            return None

    def do_GET(self):
        path = urlparse(self.path).path
        if path == "/api/comments":
            return self._json(load())
        if path == "/api/version":
            try:
                v = os.path.getmtime(os.path.join(DIR, "altevita-telas.html"))
            except Exception:
                v = 0
            return self._json({"v": v})
        return super().do_GET()

    def do_POST(self):
        if urlparse(self.path).path != "/api/comments":
            return self._json({"ok": False}, 404)
        data = self._body()
        if data is None:
            return self._json({"ok": False, "erro": "json"}, 400)
        text = (str(data.get("text") or "")).strip()[:2000]
        if not text:
            return self._json({"ok": False, "erro": "vazio"}, 400)
        item = {
            "id": uuid.uuid4().hex[:12],
            "screen": str(data.get("screen", "geral"))[:120],
            "label": (str(data.get("label") or "")).strip()[:160],
            "author": (str(data.get("author") or "Anônimo")).strip()[:40] or "Anônimo",
            "text": text,
            "t": time.time(),
            "ts": datetime.datetime.now().strftime("%d/%m %H:%M"),
        }
        with LOCK:
            items = load()
            items.append(item)
            save(items)
        return self._json({"ok": True, "item": item})

    def do_PATCH(self):
        if urlparse(self.path).path != "/api/comments":
            return self._json({"ok": False}, 404)
        data = self._body() or {}
        cid = data.get("id")
        if not cid:
            return self._json({"ok": False, "erro": "id"}, 400)
        text = (str(data.get("text") or "")).strip()[:2000]
        has_text = "text" in data and text
        has_resolved = "resolved" in data
        if not has_text and not has_resolved:
            return self._json({"ok": False, "erro": "dados"}, 400)
        with LOCK:
            items = load()
            found = False
            for it in items:
                if it.get("id") == cid:
                    if has_text:
                        it["text"] = text
                        it["ts"] = datetime.datetime.now().strftime("%d/%m %H:%M") + " (editado)"
                    if has_resolved:
                        it["resolved"] = bool(data["resolved"])
                        if it["resolved"]:
                            it["resolvedBy"] = (str(data.get("by") or "alguém")).strip()[:40]
                            it["resolvedAt"] = datetime.datetime.now().strftime("%d/%m %H:%M")
                        else:
                            it.pop("resolvedBy", None)
                            it.pop("resolvedAt", None)
                    found = True
                    break
            if found:
                save(items)
        return self._json({"ok": found})

    def do_DELETE(self):
        if urlparse(self.path).path != "/api/comments":
            return self._json({"ok": False}, 404)
        data = self._body() or {}
        cid = data.get("id")
        if not cid:
            return self._json({"ok": False, "erro": "id"}, 400)
        with LOCK:
            items = load()
            new = [it for it in items if it.get("id") != cid]
            save(new)
        return self._json({"ok": True, "removidos": len(items) - len(new)})

    def log_message(self, *a):
        pass

if __name__ == "__main__":
    port = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
    print("AlteVita — servindo em http://0.0.0.0:%d  (Ctrl+C p/ parar)" % port)
    print("Comentarios em:", CF)
    ThreadingHTTPServer(("0.0.0.0", port), H).serve_forever()
