from __future__ import annotations

import html
import re
import urllib.request
import xml.etree.ElementTree as ET
from typing import List, Optional

from ..models import JobDescription
from .base import JobSource


def _strip_html(text: str) -> str:
    # Very lightweight: strip tags and normalize whitespace.
    text = re.sub(r"<[^>]+>", " ", text)
    text = html.unescape(text)
    text = re.sub(r"\s+", " ", text).strip()
    return text


class RemoteOKSource(JobSource):
    """
    RSS-based job source.

    RemoteOK is one of the few job boards that provides an RSS feed without requiring login.
    Other sources (Indeed/LinkedIn) typically require auth and are not included by default.
    """

    def __init__(self, feed_url: str = "https://remoteok.com/remote-dev-jobs.rss") -> None:
        self.feed_url = feed_url

    def search(self, *, query: str, max_jobs: int) -> List[JobDescription]:
        q_terms = [t.lower() for t in re.split(r"\s+", query.strip()) if t.strip()]
        items = self._fetch_rss_items()

        matches: List[JobDescription] = []
        for item in items:
            title = (item.get("title") or "").strip()
            description = item.get("description") or ""
            url = item.get("link") or None

            raw_text = f"{title}\n\n{description}".strip()
            haystack = raw_text.lower()

            if q_terms and not all(t in haystack for t in q_terms):
                continue

            matches.append(
                JobDescription(
                    raw_text=raw_text,
                    title=title or "RemoteOK Job",
                    url=url,
                    company=None,
                    location="Remote",
                )
            )
            if len(matches) >= max_jobs:
                break

        return matches

    def _fetch_rss_items(self) -> List[dict]:
        req = urllib.request.Request(
            self.feed_url,
            headers={"User-Agent": "job_search_agent/0.1 (+https://example.invalid)"},
        )
        with urllib.request.urlopen(req, timeout=20) as resp:
            data = resp.read()

        # Parse RSS XML.
        root = ET.fromstring(data)
        channel = root.find("channel")
        if channel is None:
            return []

        out: List[dict] = []
        for item in channel.findall("item"):
            title_el = item.find("title")
            link_el = item.find("link")
            desc_el = item.find("description")

            title = title_el.text if title_el is not None and title_el.text else ""
            link = link_el.text if link_el is not None and link_el.text else ""
            description = desc_el.text if desc_el is not None and desc_el.text else ""

            out.append(
                {
                    "title": title,
                    "link": link,
                    "description": _strip_html(description),
                }
            )
        return out

