#!/usr/bin/env python3
"""Extract body of the most recent Wentworth Point RFQ email + scan for
deadlines in body text."""
import json, urllib.request, urllib.error, base64, re, html as htmllib

TOKEN_PATH = '/root/.hermes/google_token.json'
tok = json.load(open(TOKEN_PATH))
access = tok['access_token']

def api_get(url, params=None):
    if params:
        url = url + '?' + urllib.parse.urlencode(params)
    req = urllib.request.Request(url, headers={'Authorization': f'Bearer {access}'})
    resp = urllib.request.urlopen(req, timeout=30)
    return json.loads(resp.read())

def extract_body_text(payload):
    if payload.get('body', {}).get('data'):
        raw = payload['body']['data']
        padded = raw + '=' * (-len(raw) % 4)
        return base64.urlsafe_b64decode(padded).decode('utf-8', 'replace')
    for p in payload.get('parts', []):
        if p.get('mimeType') == 'text/plain':
            raw = p.get('body', {}).get('data', '')
            if raw:
                padded = raw + '=' * (-len(raw) % 4)
                return base64.urlsafe_b64decode(padded).decode('utf-8', 'replace')
    for p in payload.get('parts', []):
        t = extract_body_text(p)
        if t:
            return t
    return ''

def extract_body_html(payload):
    if payload.get('mimeType') == 'text/html' and payload.get('body', {}).get('data'):
        raw = payload['body']['data']
        padded = raw + '=' * (-len(raw) % 4)
        return base64.urlsafe_b64decode(padded).decode('utf-8', 'replace')
    for p in payload.get('parts', []):
        t = extract_body_html(p)
        if t:
            return t
    return ''

def html_to_text(html):
    text = re.sub(r'<style[^>]*>.*?</style>', '', html, flags=re.S | re.I)
    text = re.sub(r'<[^>]+>', ' ', text)
    text = htmllib.unescape(text)
    text = re.sub(r'\s+', ' ', text)
    return text.strip()

# Fetch more unread to get more candidates
list_url = 'https://gmail.googleapis.com/gmail/v1/users/me/messages'
listing = api_get(list_url, {'q': 'is:unread in:inbox', 'maxResults': '50'})
msgs = listing.get('messages', [])
print(f"Total unread: {len(msgs)}")

# Print just headers + snippet + body for first 30 if no headers seen yet
# Already have first 15. Fetch the rest 15-29.
NOISE = ['unsubscribe', 'notification', 'wispr', 'stripe', 'recall']
DEADLINE = re.compile(r'(tender\s+(due|closes|closing|close)|due\s+date|closing\s+date|submission\s+deadline|closes\s*:|due\s*:|rfq\s+close|tender\s+open|closing\s+(on|at))', re.I)

all_emails = []
for m in msgs:
    full = api_get(f"{list_url}/{m['id']}", {'format': 'full'})
    headers = {h['name'].lower(): h['value'] for h in full.get('payload', {}).get('headers', [])}
    subj = headers.get('subject', '(no subject)')
    fro = headers.get('from', '')
    date = headers.get('date', '')
    msg_id = headers.get('message-id', '')
    snippet = full.get('snippet', '')
    body_plain = extract_body_text(full.get('payload', {}))
    body_html = extract_body_html(full.get('payload', {}))
    body_text = html_to_text(body_html) if body_html else ''
    body = body_plain or body_text[:2000]
    subj_l = subj.lower()
    fro_l = fro.lower()
    is_noise = (any(n in subj_l for n in NOISE) or
                any(n in fro_l for n in ['noreply', 'no-reply', 'mailer-daemon', 'notification@']))
    all_emails.append({
        'id': m['id'], 'subject': subj, 'from': fro, 'date': date,
        'snippet': snippet, 'body': body[:2000], 'is_noise': is_noise,
    })

print(f"\nFetched {len(all_emails)} total")
# Print all unique senders + subjects ordered by date desc
all_emails.sort(key=lambda e: e['date'], reverse=True)
for e in all_emails:
    flag = '[NOISE]' if e['is_noise'] else ''
    print(f"  {e['date'][:25]} | {e['from'][:40]} | {e['subject'][:60]} {flag}")

# Deadline hunt
print("\n=== DEADLINE MATCHES ===")
for e in all_emails:
    if e['is_noise']:
        continue
    blob = e['body'] + ' ' + e['snippet'] + ' ' + e['subject']
    dm = DEADLINE.search(blob)
    if dm:
        idx = dm.start()
        ctx = blob[max(0,idx-30):idx+200]
        print(f"  {e['subject'][:60]}")
        print(f"    -> {ctx[:240]}")

# Specific dive into latest Wentworth Point RFQ
print("\n=== LATEST WENTWORTH POINT BODY ===")
for e in all_emails:
    if 'Wentworth Point' in e['subject'] and not e['is_noise']:
        print(f"--- {e['subject']} ---")
        print(f"From: {e['from']}")
        print(f"Date: {e['date']}")
        print(f"Body (first 3000 chars):")
        print(e['body'][:3000])
        print()
        break  # most recent only

# EstimateOne EOT
print("\n=== ESTIMATEONE EOT ===")
for e in all_emails:
    if 'Concord West' in e['subject'] or 'estimateone' in e['from'].lower():
        print(f"--- {e['subject']} ---")
        print(f"From: {e['from']}")
        print(f"Date: {e['date']}")
        print(f"Snippet: {e['snippet']}")
        print(f"Body (first 1500):")
        print(e['body'][:1500])
        print()
        break

# Mahdi Jafari (timesheet/parking)
print("\n=== MAHDI JAFARI ===")
for e in all_emails:
    if 'mahdi' in e['from'].lower() or 'Mahdi' in e['from']:
        print(f"--- {e['subject']} ---")
        print(f"From: {e['from']}")
        print(f"Date: {e['date']}")
        print(f"Body (first 1500):")
        print(e['body'][:1500])
        break

# Ford Civil LED Strip
print("\n=== FORD CIVIL LED STRIP ===")
for e in all_emails:
    if 'LED Strip' in e['subject']:
        print(f"--- {e['subject']} ---")
        print(f"From: {e['from']}")
        print(f"Date: {e['date']}")
        print(f"Body (first 1500):")
        print(e['body'][:1500])
        break

# Admin Re: RFT Ford Civil (31 Jul)
print("\n=== LFCS ADMIN RFT FORD ===")
for e in all_emails:
    if 'admin@lfcs' in e['from'].lower() and 'Wentworth Point' in e['subject']:
        print(f"--- {e['subject']} ---")
        print(f"From: {e['from']}")
        print(f"Date: {e['date']}")
        print(f"Body (first 1500):")
        print(e['body'][:1500])
        break
