"""GitHub site preset — repos + trending."""
from urllib.parse import urlparse
import re


class GitHub:
    def __init__(self, client):
        self.client = client

    def extract(self, url):
        path = urlparse(url).path.strip("/")
        if path == "trending" or path.startswith("trending"):
            return self._trending(url)
        return self._repo(url)

    def _repo(self, url):
        try:
            parts = [p for p in urlparse(url).path.strip("/").split("/") if p]
            if len(parts) < 2:
                return {"success": False, "data": {}, "source": "github-api", "error": "Need owner/repo in URL"}
            owner, repo = parts[0], parts[1]
            resp = self.client.fetch(f"https://api.github.com/repos/{owner}/{repo}", timeout=10)
            if resp.status_code == 200:
                d = resp.json()
                return {"success": True, "data": {
                    "full_name": d.get("full_name"),
                    "description": d.get("description"),
                    "stars": d.get("stargazers_count"),
                    "forks": d.get("forks_count"),
                    "language": d.get("language"),
                    "open_issues": d.get("open_issues_count"),
                }, "source": "github-api", "error": None}
            return {"success": False, "data": {}, "source": "github-api", "error": f"HTTP {resp.status_code}"}
        except Exception as e:
            return {"success": False, "data": {}, "source": "github-api", "error": str(e)}

    def _trending(self, url):
        """Extract trending repos from GitHub trending page or API."""
        try:
            # Try the unofficial GitHub trending API first
            resp = self.client.fetch("https://api.github.com/search/repositories?q=stars:>1000&sort=stars&order=desc&per_page=25", timeout=10)
            if resp.status_code == 200:
                items = resp.json().get("items", [])
                repos = []
                for r in items[:25]:
                    repos.append({
                        "name": r.get("full_name"),
                        "description": r.get("description", ""),
                        "stars": r.get("stargazers_count", 0),
                        "forks": r.get("forks_count", 0),
                        "language": r.get("language", ""),
                        "url": r.get("html_url", ""),
                    })
                return {"success": True, "data": {"repos": repos, "count": len(repos)}, "source": "github-api-search", "error": None}

            # Fallback: scrape the trending page
            resp2 = self.client.fetch("https://github.com/trending", timeout=15)
            if resp2.status_code == 200:
                repos = self._parse_trending_html(resp2.text)
                if repos:
                    return {"success": True, "data": {"repos": repos, "count": len(repos)}, "source": "github-trending-html", "error": None}

            return {"success": False, "data": {}, "source": "github-trending", "error": f"HTTP {resp.status_code}"}
        except Exception as e:
            return {"success": False, "data": {}, "source": "github-trending", "error": str(e)}

    def _parse_trending_html(self, html):
        """Parse trending repos from HTML."""
        repos = []
        # Each trending repo is in an <article> with class "Box-row"
        articles = re.split(r'<article\s+class="Box-row"', html)[1:]
        for article in articles[:25]:
            name_match = re.search(r'href="/([^"]+)"', article)
            desc_match = re.search(r'<p class="col-9[^"]*"[^>]*>\s*(.+?)\s*</p>', article, re.DOTALL)
            stars_match = re.search(r'href="/[^"]+/stargazers"[^>]*>\s*(?:<[^>]*>)*\s*([\d,]+)', article)
            lang_match = re.search(r'itemprop="programmingLanguage">([^<]+)', article)

            name = name_match.group(1).strip() if name_match else ""
            desc = re.sub(r'<[^>]+>', '', desc_match.group(1)).strip() if desc_match else ""
            stars_str = stars_match.group(1).replace(",", "").strip() if stars_match else "0"
            lang = lang_match.group(1).strip() if lang_match else ""

            if name:
                repos.append({
                    "name": name,
                    "description": desc,
                    "stars": int(stars_str) if stars_str.isdigit() else 0,
                    "language": lang,
                    "url": f"https://github.com/{name}",
                })
        return repos
