import json
import urllib.request
import xml.etree.ElementTree as ET
from datetime import datetime, timezone
from email.utils import format_datetime
from xml.dom import minidom

API_URL = "https://api.printables.com/graphql/"
OUTPUT = "/rss/printables-new.xml"

query = """
query SearchModels($query: String!, $limit: Int, $ordering: SearchChoicesEnum) {
  result: searchPrints2(
    query: $query,
    printType: print,
    limit: $limit,
    ordering: $ordering
  ) {
    items {
      id
      name
      slug
      likesCount
      downloadCount
      datePublished
      user {
        publicUsername
      }
      image {
        filePath
      }
    }
  }
}
"""

payload = json.dumps({
    "operationName": "SearchModels",
    "query": query,
    "variables": {
        "query": "",
        "limit": 50,
        "ordering": "latest"
    }
}).encode()

req = urllib.request.Request(
    API_URL,
    data=payload,
    headers={
        "Content-Type": "application/json",
        "User-Agent": "3d-rss/1.0"
    },
    method="POST"
)

with urllib.request.urlopen(req, timeout=30) as response:
    result = json.loads(response.read().decode())

items = result["data"]["result"]["items"]

rss = ET.Element("rss", version="2.0")
channel = ET.SubElement(rss, "channel")

ET.SubElement(channel, "title").text = "Printables - Nouveaux modèles"
ET.SubElement(channel, "link").text = "https://www.printables.com/model"
ET.SubElement(channel, "description").text = (
    "Les 50 modèles les plus récemment publiés sur Printables"
)
ET.SubElement(channel, "language").text = "fr"
ET.SubElement(channel, "lastBuildDate").text = format_datetime(
    datetime.now(timezone.utc)
)

for model in items:

    model_id = str(model["id"])
    name = model.get("name") or "Sans titre"
    slug = model.get("slug") or ""
    author = (model.get("user") or {}).get("publicUsername") or "Inconnu"

    likes = model.get("likesCount", 0)
    downloads = model.get("downloadCount", 0)

    model_url = f"https://www.printables.com/model/{model_id}-{slug}"

    image_path = (model.get("image") or {}).get("filePath")
    image_url = ""

    if image_path:
        image_url = f"https://media.printables.com/{image_path.lstrip('/')}"

    item = ET.SubElement(channel, "item")

    ET.SubElement(item, "title").text = name
    ET.SubElement(item, "link").text = model_url
    ET.SubElement(item, "guid", isPermaLink="true").text = model_url

    description = (
        f"<p><strong>Créateur :</strong> {author}</p>"
        f"<p>❤️ {likes} &nbsp; ⬇️ {downloads}</p>"
    )

    if image_url:
        description += (
            f'<p><img src="{image_url}" '
            f'alt="{name}" style="max-width:600px;"></p>'
        )

    ET.SubElement(item, "description").text = description

    published = model.get("datePublished")

    if published:
        try:
            dt = datetime.fromisoformat(
                published.replace("Z", "+00:00")
            )
            ET.SubElement(item, "pubDate").text = format_datetime(dt)
        except Exception:
            pass

xml_bytes = ET.tostring(rss, encoding="utf-8")

pretty_xml = minidom.parseString(xml_bytes).toprettyxml(
    indent="  ",
    encoding="UTF-8"
)

with open(OUTPUT, "wb") as f:
    f.write(pretty_xml)

print(f"RSS créé : {OUTPUT}")
print(f"Modèles : {len(items)}")
