"""
Enrich a company from PitchBook

Designed to run inside a Zapier "Run Python" step (or any environment that
exposes `input_data`). Given a company's name and/or website from Attio,
resolve the PitchBook ID, then pull:

  - Investor list (deduplicated)
  - Optional match against YOUR firm's top-investor watchlist
  - HQ geography (city, state, country)
  - Most recent financing round type
  - Total funding raised, last round size, last round valuation, last round date

All money fields are USD-enforced — the script raises if PitchBook returns
a non-USD currency so you don't silently mix currencies in the CRM.

# ──────────────────────────────────────────────────────────────────────
# TOP_INVESTORS watchlist
#
# Populate the TOP_INVESTORS set below with your own firm's preferred
# co-investors (one canonical spelling each, matching how they appear in
# your CRM). Add common alternate spellings to ALIASES so noisy PitchBook
# strings map back to your canonical names.
#
# Don't need the watchlist? Just leave TOP_INVESTORS empty — the rest of
# the enrichment (investors, geo, funding, valuation, round type) still
# works; `matched_investors` will simply come back as "None".
# ──────────────────────────────────────────────────────────────────────
"""

import requests

api_key = input_data['api_key']                      # PB API key
company_name = input_data.get('company_name')        # from Attio
company_website = input_data.get('company_website')  # from Attio

BASE_URL = "https://api.pitchbook.com"

# choose website if available, else name
search_query = company_website if company_website else company_name

headers = {
    "Authorization": f"PB-Token {api_key}",
    "Accept": "application/json"
}

# -------------------------
# Top investor set (canonical = CRM naming)
# Populate with your firm's watchlist, or leave empty to skip matching.
# -------------------------
TOP_INVESTORS = {
    # "Example Capital",
    # "Example Ventures",
}

# Aliases: alternate spelling/format (lowercased) → canonical name in TOP_INVESTORS
ALIASES = {
    # "example cap": "Example Capital",
}

# Case-insensitive lookup from canonical set
canonical_map = {name.lower(): name for name in TOP_INVESTORS}

# -------------------------
# Helper: safe GET (returns {} on any failure)
# -------------------------
def safe_get(url):
    try:
        resp = requests.get(url, headers=headers, timeout=15)
        if resp.ok:
            return resp.json() if resp.text else {}
        return {}
    except Exception:
        return {}

# -------------------------
# Helper: enforce USD-only
# -------------------------
def assert_usd(money_obj, field_name):
    if not money_obj:
        return
    currency = money_obj.get("currency") or money_obj.get("nativeCurrency")
    if currency and currency != "USD":
        raise Exception(f"Non-USD currency detected for {field_name}: {currency}")

# -------------------------
# Empty/no-data output shape (every field always present)
# -------------------------
def no_data_output(pb_id=None):
    return {
        "data_status": "no data",
        "pitchbook_company_id": pb_id,
        "search_used": search_query,
        "investors": "",
        "matched_investors": "None",
        "match_count": 0,
        "company_geography": "",
        "last_round_type": None,
        "total_funding_amount": None,
        "last_funding_amount": None,
        "last_funding_valuation": None,
        "last_funding_date": None
    }

# -------------------------
# 0. SEARCH → GET PB ID (graceful)
# -------------------------
if not search_query:
    return no_data_output()

search_resp = safe_get(f"{BASE_URL}/search?query={search_query}")
items = search_resp.get("items", [])

if not items:
    return no_data_output()

pb_id = None
for item in items:
    if item.get("primaryFirmType", {}).get("type") == "COMPANY":
        pb_id = item.get("pbId")
        break

if not pb_id:
    pb_id = items[0].get("pbId")

if not pb_id:
    return no_data_output()

# -------------------------
# 1. INVESTORS
# -------------------------
investors_resp = safe_get(f"{BASE_URL}/companies/{pb_id}/investors")

investors_array = investors_resp.get("investors", [])
if not isinstance(investors_array, list):
    investors_array = []

seen = set()
investor_names = []

for inv in investors_array:
    name = inv.get("investorName")
    if name and name not in seen:
        seen.add(name)
        investor_names.append(name)

investors_string = ", ".join(investor_names)

# -------------------------
# 2. MATCH TOP INVESTORS
# -------------------------
matched = []
matched_seen = set()

for name in investor_names:
    lower = name.lower()
    canonical = ALIASES.get(lower) or canonical_map.get(lower)
    if canonical and canonical not in matched_seen:
        matched.append(canonical)
        matched_seen.add(canonical)

matched_investors = ", ".join(matched) if matched else "None"
match_count = len(matched)

# -------------------------
# 3. COMPANY GEO (BIO)
# -------------------------
bio_resp = safe_get(f"{BASE_URL}/companies/{pb_id}/bio")

hq = bio_resp.get("hqLocation", {})

city = hq.get("city")
state = hq.get("stateProvince")
country = hq.get("country")

geo_parts = [p for p in [city, state, country] if p]
company_geography = ", ".join(geo_parts)

# -------------------------
# 4. MOST RECENT FINANCING
# -------------------------
fin_resp = safe_get(f"{BASE_URL}/companies/{pb_id}/most-recent-financing")

deal_type = fin_resp.get("lastFinancingDealType", {})
last_round_type = deal_type.get("description")

# -------------------------
# 5. FUNDING FIELDS (+ USD enforcement)
# -------------------------
assert_usd(bio_resp.get("totalMoneyRaised"), "totalMoneyRaised")
assert_usd(fin_resp.get("lastFinancingSize"), "lastFinancingSize")
assert_usd(fin_resp.get("lastFinancingValuation"), "lastFinancingValuation")
assert_usd(fin_resp.get("lastKnownValuation"), "lastKnownValuation")

total_funding_amount = (bio_resp.get("totalMoneyRaised") or {}).get("amount")
last_funding_amount = (fin_resp.get("lastFinancingSize") or {}).get("amount")
last_funding_date = fin_resp.get("lastFinancingDate")

last_funding_valuation = (
    (fin_resp.get("lastFinancingValuation") or {}).get("amount")
    or (fin_resp.get("lastKnownValuation") or {}).get("amount")
)

# -------------------------
# OUTPUT
# -------------------------
return {
    "data_status": "data exists",
    "pitchbook_company_id": pb_id,
    "search_used": search_query,
    "investors": investors_string,
    "matched_investors": matched_investors,
    "match_count": match_count,
    "company_geography": company_geography,
    "last_round_type": last_round_type,
    "total_funding_amount": total_funding_amount,
    "last_funding_amount": last_funding_amount,
    "last_funding_valuation": last_funding_valuation,
    "last_funding_date": last_funding_date
}
