from __future__ import annotations

import html
import json
import re
import urllib.request
from typing import List

from ..models import JobDescription
from .base import JobSource


def _strip_html(text: str) -> str:
    text = re.sub(r"<[^>]+>", " ", text)
    text = html.unescape(text)
    text = re.sub(r"\s+", " ", text).strip()
    return text


class RemotiveSource(JobSource):
    """
    JSON API-based job source (public):
    https://remotive.com/api/remote-jobs
    """

    API_URL = "https://remotive.com/api/remote-jobs"

    def search(self, *, query: str, max_jobs: int) -> List[JobDescription]:
        url = f"{self.API_URL}?search={urllib.request.quote(query)}&limit={max_jobs}"
        req = urllib.request.Request(
            url,
            headers={"User-Agent": "job_search_agent/0.1 (+https://example.invalid)"},
        )
        with urllib.request.urlopen(req, timeout=20) as resp:
            data = json.loads(resp.read())

        jobs = data.get("jobs", [])
        matches: List[JobDescription] = []

        for job in jobs:
            title = job.get("title", "") or ""
            company = job.get("company_name", "") or ""
            description = _strip_html(job.get("description", "") or "")
            job_url = job.get("url", "") or ""
            location = job.get("candidate_required_location", "Remote") or "Remote"

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

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

        return matches
