"""Which parcels are 'middle-housing units' we track. Shared by enrich_assessor.py and build.py.

- Bellingham: every county parcel linked to a city middle-housing permit (by SITE_APN, else by address).
- All four cities (incl. Bellingham parcels with no permit match, e.g. UGA or pre-2015 permits): parcels built 2015+
  whose county use code is middle housing, plus inferred small-lot houses (<= 0.08 ac) and condos.
"""
import collections
from common import load, norm_addr

MH_CODES = {"1132": "Townhouse", "1133": "Townhouse", "1134": "Townhouse",
            "1220": "Duplex", "1230": "Triplex", "1240": "Fourplex", "1300": "Multiplex",
            "1305": "Multiplex", "1306": "Multiplex", "1307": "Multiplex", "1308": "Multiplex", "1309": "Multiplex"}
for c in range(1211, 1218):
    MH_CODES[str(c)] = "House + ADU"
SMALL_LOT_AC = 0.08
MAX_CONDO_PER_BLDG = 6  # condos in bigger buildings are apartments-as-condos, not middle housing
_condo_bldg = collections.Counter()  # (city, street address) -> condo parcels at that address; filled by build()

# City Housing_Type -> app product type (ADUs are just another type, per Ted 2026-10-29)
PERMIT_TYPE = {
    "TOWNHOUSE": "Townhouse", "TOWNHOUSE (ITK)": "Townhouse", "TOWNHOUSE W/AADU (ITK)": "Townhouse",
    "SFR (ATTACHED)": "Townhouse", "": "Townhouse",
    "SMALL LOT (ITK)": "Small lot", "SMALL LOT (ITK) W/ AADU": "Small lot",
    "COTTAGE (ITK)": "Cottage", "GARDEN COURT (ITK)": "Garden/shared court", "SHARED COURT (ITK)": "Garden/shared court",
    "DUPLEX": "Duplex", "DUPLEX (ITK)": "Duplex", "TRIPLEX": "Triplex", "TRIPLEX (ITK)": "Triplex",
    "FOURPLEX": "Fourplex", "FIVEPLEX": "Multiplex", "SIXPLEX": "Multiplex",
    "DADU": "DADU", "AADU": "AADU", "ADU": "ADU", "SFR W/ AADU": "House + ADU", "SFR W/  AADU": "House + ADU",
}


def permit_type(p):
    ht = (p.get("Housing_Type") or "").strip()
    if p.get("PermitSubType") == "ADU" and ht in ("", "ADU"):
        return "ADU"
    return PERMIT_TYPE.get(ht, ht.title() or "Townhouse")


def parcel_addr(q):
    return norm_addr(" ".join(x for x in (q.get("situs_num"), q.get("situs_street_prefix"), q.get("situs_street")) if x))


def city(q):
    return (q.get("situs_city") or "").strip().title()


def parcel_type(q):
    """Product type for a parcel found by use code (no permit). None = not middle housing."""
    if (q.get("yr_blt") or 0) < 2015:
        return None
    u = q.get("property_use_cd")
    if u in MH_CODES:
        return MH_CODES[u]
    if u == "1410":
        return "Condo" if _condo_bldg[(city(q), parcel_addr(q))] <= MAX_CONDO_PER_BLDG else None
    if u and u.startswith("11") and (q.get("legal_acreage") or 1) <= SMALL_LOT_AC:
        return "Small lot (inferred)"
    return None


def build():
    """Returns (permits, parcels_by_id, permit->prop_id link, set of tracked prop_ids, parcel-only prop_ids)."""
    permits = load("permits.json")
    parcels = {q["prop_id"]: q for q in load("county_parcels.json")}
    by_apn, by_addr = collections.defaultdict(list), collections.defaultdict(list)
    _condo_bldg.clear()
    _condo_bldg.update((city(q), parcel_addr(q)) for q in parcels.values() if q.get("property_use_cd") == "1410")
    for q in parcels.values():
        by_apn[q["TTRRSSXXXYYY"]].append(q)
        by_addr[parcel_addr(q)].append(q)
    link = {}
    for p in permits:
        cands = by_apn.get(p.get("SITE_APN") or "") or by_addr.get(norm_addr(p.get("SITE_ADDR"))) or by_apn.get(p.get("PARENT_SITE_APN") or "")
        if cands:
            link[p["PERMIT_NO"]] = cands[0]["prop_id"]
    permit_pids = set(link.values())
    parcel_only = {pid for pid, q in parcels.items() if pid not in permit_pids and parcel_type(q)}
    return permits, parcels, link, permit_pids | parcel_only, parcel_only
