"""Turn a plain-English investment thesis into a ranked Dealroom shortlist.

Install:
    pip install authlib requests python-dotenv

Run:
    Create a .env file with DEALROOM_CLIENT_ID and DEALROOM_CLIENT_SECRET.
    python thesis_to_shortlist.py
"""

import json
import os

from authlib.integrations.requests_client import OAuth2Session
from dotenv import load_dotenv

load_dotenv()

API_BASE = os.environ.get("DEALROOM_API_BASE", "https://api.beta.dealroom.app")
AUTH_URL = os.environ.get(
    "DEALROOM_AUTH_URL", "https://accounts.beta.dealroom.co/oauth/token"
)
AUDIENCE = os.environ.get(
    "DEALROOM_AUDIENCE", "https://api-next.beta.dealroom.co"
)
CLIENT_ID = os.environ["DEALROOM_CLIENT_ID"]
CLIENT_SECRET = os.environ["DEALROOM_CLIENT_SECRET"]
USER_AGENT = os.environ.get(
    "DEALROOM_USER_AGENT", "dealroom-cookbook-thesis-shortlist/1.0"
)


class DealroomClient:
    """Small OAuth2 client that refreshes once if an API request returns 401."""

    def __init__(self):
        self.session = OAuth2Session(
            client_id=CLIENT_ID,
            client_secret=CLIENT_SECRET,
            token_endpoint=AUTH_URL,
        )
        self.session.headers.update(
            {
                "X-Client-Id": CLIENT_ID,
                "User-Agent": USER_AGENT,
            }
        )
        self._fetch_token()

    def _fetch_token(self):
        self.session.fetch_token(
            url=AUTH_URL,
            grant_type="client_credentials",
            audience=AUDIENCE,
        )

    def get(self, path, **kwargs):
        response = self.session.get(f"{API_BASE}{path}", **kwargs)
        if response.status_code == 401:
            self._fetch_token()
            response = self.session.get(f"{API_BASE}{path}", **kwargs)
        response.raise_for_status()
        return response.json()


client = DealroomClient()


def exact_value(items, label, source_type=None):
    """Select an exact label from filter discovery results."""
    for item in items:
        item_label = item.get("label") or item.get("name", "")
        item_type = item.get("source_type") or item.get("type")
        label_matches = item_label.casefold() == label.casefold()
        type_matches = source_type is None or item_type == source_type
        if label_matches and type_matches:
            return str(item.get("value") or item["id"])
    raise LookupError(f"Could not resolve {label!r} in Dealroom taxonomy")


def resolve_location(label, location_type):
    result = client.get(
        "/reference/filters/location/values",
        params={"q": label, "type": location_type, "limit": 20},
    )
    return exact_value(result["data"], label, location_type)


def resolve_tag(label, source_type):
    result = client.get(
        "/reference/filters/search",
        params={"q": label, "scope": "companies", "limit": 20},
    )
    return exact_value(result["data"], label, source_type)


europe_id = resolve_location("Europe", "continent")
industrial_automation_id = resolve_tag("Industrial Automation", "sector")
artificial_intelligence_id = resolve_tag(
    "Artificial Intelligence", "technology"
)

filters = [
    f"tag_id[in_all]:{industrial_automation_id}|{artificial_intelligence_id}",
    f"hq_location[eq]:{europe_id}",
    "is_startup[eq]:true",
    "company_status[eq]:operational",
    "launch_date[gte]:2020",
    "total_funding[lte]:50000000",
    "signal_rating[gte]:65",
]

result = client.get(
    "/data/companies",
    params={
        "filter": f"and({','.join(filters)})",
        "sort": "-signal_rating",
        "limit": 8,
        "include_total": "true",
    },
)

shortlist = [
    {
        "name": company["name"],
        "tagline": company.get("tagline"),
        "location": ", ".join(
            value for value in [company.get("hq_city"), company.get("hq_country")] if value
        ),
        "founded": company.get("launch_year"),
        "total_funding_usd": company.get("funding_summary", {}).get(
            "total_funding"
        ),
        "signal_rating": company.get("company", {}).get("signal_rating"),
        "dealroom_url": company.get("dealroom_url"),
    }
    for company in result["data"]
]

print(json.dumps({"total_matches": result["page"]["total"], "companies": shortlist}, indent=2))
