"""US states named in a posting's location string.

Location strings are free text ("San Mateo, CA, United States", "US-WA-Bellevue",
"Remote - Texas", "Nuro HQ - Mountain View, CA"). states(text) returns the
two-letter codes it can name with confidence, plus "REMOTE_US" when the string
offers remote work across the United States without naming a state. A city
without a state is resolved only from the CITY table below, which lists the
cities that occur in the 10 November 2026 read; anything else gives nothing,
and the role is then counted as "state not named", never guessed.
"""
import re

STATES = {
    'AL': 'Alabama', 'AK': 'Alaska', 'AZ': 'Arizona', 'AR': 'Arkansas', 'CA': 'California', 'CO': 'Colorado',
    'CT': 'Connecticut', 'DE': 'Delaware', 'DC': 'District of Columbia', 'FL': 'Florida', 'GA': 'Georgia',
    'HI': 'Hawaii', 'ID': 'Idaho', 'IL': 'Illinois', 'IN': 'Indiana', 'IA': 'Iowa', 'KS': 'Kansas',
    'KY': 'Kentucky', 'LA': 'Louisiana', 'ME': 'Maine', 'MD': 'Maryland', 'MA': 'Massachusetts', 'MI': 'Michigan',
    'MN': 'Minnesota', 'MS': 'Mississippi', 'MO': 'Missouri', 'MT': 'Montana', 'NE': 'Nebraska', 'NV': 'Nevada',
    'NH': 'New Hampshire', 'NJ': 'New Jersey', 'NM': 'New Mexico', 'NY': 'New York', 'NC': 'North Carolina',
    'ND': 'North Dakota', 'OH': 'Ohio', 'OK': 'Oklahoma', 'OR': 'Oregon', 'PA': 'Pennsylvania',
    'RI': 'Rhode Island', 'SC': 'South Carolina', 'SD': 'South Dakota', 'TN': 'Tennessee', 'TX': 'Texas',
    'UT': 'Utah', 'VT': 'Vermont', 'VA': 'Virginia', 'WA': 'Washington', 'WV': 'West Virginia',
    'WI': 'Wisconsin', 'WY': 'Wyoming'}

CITY = {
    'san francisco': 'CA', 'sf': 'CA', 'bay area': 'CA', 'palo alto': 'CA', 'mountain view': 'CA',
    'san mateo': 'CA', 'menlo park': 'CA', 'foster city': 'CA', 'redwood city': 'CA', 'sunnyvale': 'CA',
    'san jose': 'CA', 'oakland': 'CA', 'hawthorne': 'CA', 'long beach': 'CA', 'los angeles': 'CA',
    'san diego': 'CA', 'irvine': 'CA', 'pasadena': 'CA', 'berkeley': 'CA', 'burlingame': 'CA',
    'santa clara': 'CA', 'hayward': 'CA', 'vandenberg': 'CA', 'socal': 'CA',
    'new york': 'NY', 'nyc': 'NY', 'brooklyn': 'NY',
    'seattle': 'WA', 'bellevue': 'WA', 'redmond': 'WA', 'kitsap': 'WA',
    'austin': 'TX', 'dallas': 'TX', 'houston': 'TX', 'bastrop': 'TX', 'starbase': 'TX', 'brownsville': 'TX',
    'mcgregor': 'TX', 'frisco': 'TX', 'college station': 'TX',
    'boston': 'MA', 'cambridge, ma': 'MA', 'chicago': 'IL', 'champaign': 'IL', 'denver': 'CO', 'boulder': 'CO',
    'littleton': 'CO', 'colorado springs': 'CO', 'atlanta': 'GA', 'miami': 'FL', 'cape canaveral': 'FL',
    'jacksonville': 'FL', 'washington dc': 'DC', 'washington, d.c.': 'DC', 'washington d.c.': 'DC',
    'washington, dc': 'DC', 'raleigh': 'NC', 'durham': 'NC', 'charlotte': 'NC', 'fayetteville, nc': 'NC',
    'pittsburgh': 'PA', 'philadelphia': 'PA', 'princeton': 'NJ', 'memphis': 'TN', 'nashville': 'TN',
    'tucson': 'AZ', 'phoenix': 'AZ', 'salt lake city': 'UT', 'cottonwood heights': 'UT', 'portland': 'OR',
    'detroit': 'MI', 'ann arbor': 'MI', 'st. louis': 'MO', 'kansas city': 'MO', 'omaha': 'NE',
    'honolulu': 'HI', 'chantilly': 'VA', 'mclean': 'VA', 'norfolk': 'VA', 'laurel': 'MD', 'helena': 'MT',
    'canandaigua': 'NY', 'columbus, ohio': 'OH',
}
NAMES = {v.lower(): k for k, v in STATES.items()}
REMOTE_US = re.compile(r'remote\W{0,4}(?:-\s*)?(?:in the\s+)?(?:us|u\.s\.?|usa|united states)\b|'
                       r'(?:us|u\.s\.?|usa|united states)\W{0,4}(?:-\s*)?(?:\(?remote)|remote-friendly, united states|'
                       r'remote,? us\b|us/remote|-remote, usa-|remote-friendly us\b', re.I)


def states(text):
    t = text or ''
    found = set()
    low = t.lower()
    # "Washington, DC" and "Washington, D.C." before the state of Washington
    for k in ('washington, district of columbia', 'washington, d.c.', 'washington d.c.', 'washington, dc', 'washington dc', 'district of columbia'):
        if k in low:
            found.add('DC')
            low = low.replace(k, ' ')
    for name, code in NAMES.items():
        if code == 'DC':
            continue
        if re.search(r'\b' + re.escape(name) + r'\b', low):
            if name == 'new york' and not re.search(r'new york,? (new york|ny|state)|\bnew york\b(?! city)', low):
                pass
            found.add(code)
    for code in STATES:
        if re.search(r'(?:,\s*|\b(?:US|USA)\s*[-–]\s*|^|;\s*|\|\s*|-\s*)' + code + r'(?=\b(?!\.)|\s*[-–,;|)]|$)', t):
            found.add(code)
    for city, code in CITY.items():
        if re.search(r'\b' + re.escape(city) + r'\b', low):
            found.add(code)
    if re.search(r'\bSEA\b', t):
        found.add('WA')
    if REMOTE_US.search(t):
        found.add('REMOTE_US')
    return found
