import json
import urllib.parse
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
from html import escape

API_URL = "https://api.bambulab.com/v1/search-service/select/design2"
OUTPUT = "/rss/makerworld-new.xml"

params = {
    "keyword": "",
    "offset": 0,
    "limit": 50,
    "orderBy": "newUploads"
}

url = API_URL + "?" + urllib.parse.urlencode(params)

req = urllib.request.Request(
    url,
    headers={
        "User-Agent": "3d-rss/1.0",
        "Accept": "application/json",
        "Accept-Language": "fr-FR,fr;q=0.9,en;q=0.8",
        "Referer": "https://makerworld.com/"
    }
)

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

items = result.get("hits", [])

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

ET.SubElement(channel, "title").text = "MakerWorld - Nouveaux modèles"
ET.SubElement(channel, "link").text = "https://makerworld.com/fr/models"
ET.SubElement(channel, "description").text = (
    "Les 50 modèles les plus récemment publiés sur MakerWorld"
)
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.get("id", ""))
    name = model.get("title") or "Sans titre"
    slug = model.get("slug") or ""
    cover = model.get("cover") or ""

    creator = model.get("designCreator") or {}
    author = creator.get("name") or creator.get("handle") or "Inconnu"

    likes = model.get("likeCount", 0)
    downloads = model.get("downloadCount", 0)
    prints = model.get("printCount", 0)

    model_url = f"https://makerworld.com/fr/models/{model_id}-{slug}"

    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> {escape(author)}</p>"
        f"<p>❤️ {likes} &nbsp; ⬇️ {downloads} &nbsp; 🖨️ {prints}</p>"
    )

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

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

    published = model.get("createTime")

    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)}")
