"""
BSS Skill: Email Thread Condenser
Parses an email thread from PROMPT, extracts participants, action items,
decisions and the last message body — drastically reducing token count.
"""
import re

text = PROMPT  # injected by BIBIVIDI sandbox wrapper

# ── Split thread into individual messages ─────────────────────────────────────
# Handles common separators: "From:", forwarded/original message banners

MSG_SEP = re.compile(
    r'(?:^|\n)(?:>*\s*)?'
    r'(?:From\s*:\s*.+|'
    r'[-─_]{3,}\s*(?:Forwarded|Original|Message)\s*[-─_]*|'
    r'On\s+.{10,80}wrote\s*:)',
    re.IGNORECASE,
)


def split_messages(txt):
    parts = MSG_SEP.split(txt)
    return [p.strip() for p in parts if p.strip()]


def strip_quotes(txt):
    """Remove '>'-prefixed reply lines."""
    return '\n'.join(l for l in txt.splitlines() if not re.match(r'^\s*>', l))


def get_header(txt, key):
    m = re.search(rf'^{key}\s*:\s*(.+)', txt, re.IGNORECASE | re.MULTILINE)
    return m.group(1).strip() if m else ''


def extract_participants(txt):
    seen, result = set(), []
    for m in re.finditer(r'(?:From|To|Cc|De)\s*:\s*([^\n]+)', txt, re.IGNORECASE):
        chunk = m.group(1)
        for addr in re.findall(r'[\w.+-]+@[\w.-]+\.\w{2,}', chunk):
            if addr not in seen:
                seen.add(addr)
                result.append(addr)
    # Fall back to any email address in the text
    if not result:
        for addr in re.findall(r'[\w.+-]+@[\w.-]+\.\w{2,}', txt):
            if addr not in seen:
                seen.add(addr)
                result.append(addr)
    return result[:8]


ACTION_RE = re.compile(
    r'(?:'
    r'(?:action item|todo|à faire)\s*[:\-–]\s*(.{8,120})'
    r'|(?:please|kindly|pouvez.vous|merci de|veuillez)\s+(.{8,100})'
    r'|(?:can you|could you|would you|pourriez.vous)\s+(.{8,100})'
    r'|(?:\[ \]|\[\s\])\s*(.{8,100})'
    r'|@[\w.]+\s+(.{8,100})'
    r')',
    re.IGNORECASE,
)

DEADLINE_RE = re.compile(
    r'(?:by|before|deadline|due|avant le|pour le)\s+'
    r'(?:\w+day|\d{1,2}[/-]\d{1,2}(?:[/-]\d{2,4})?|\d{4}-\d{2}-\d{2}|EOD|COB)',
    re.IGNORECASE,
)

DECISION_RE = re.compile(
    r'(?:decided?|agreed?|confirmed?|approved?|validated?|'
    r'décidé|convenu|validé|résolu)\s*[:\-–]?\s*(.{8,150})',
    re.IGNORECASE,
)


def extract_actions(txt):
    items = []
    for m in ACTION_RE.finditer(txt):
        item = next((g for g in m.groups() if g), '').strip()
        if len(item) > 8:
            # Append deadline hint if found nearby
            context = txt[max(0, m.start() - 10):m.end() + 80]
            dl = DEADLINE_RE.search(context)
            if dl:
                item = f'{item} [{dl.group(0).strip()}]'
            items.append(item[:130])
    return list(dict.fromkeys(items))[:8]


def extract_decisions(txt):
    items = []
    for m in DECISION_RE.finditer(txt):
        item = m.group(1).strip()[:130]
        if len(item) > 8:
            items.append(item)
    return list(dict.fromkeys(items))[:6]


# ── Parse ─────────────────────────────────────────────────────────────────────
messages = split_messages(text)

subject   = ''
last_date = ''
last_sender = ''
all_actions   = []
all_decisions = []

for raw in messages:
    if not subject:
        subject = get_header(raw, 'subject')
    date = get_header(raw, 'date') or get_header(raw, 'sent')
    if date:
        last_date = date
    sender = get_header(raw, 'from') or get_header(raw, 'de')
    if sender:
        last_sender = sender
    body = strip_quotes(raw)
    all_actions.extend(extract_actions(body))
    all_decisions.extend(extract_decisions(body))

participants  = extract_participants(text)
all_actions   = list(dict.fromkeys(all_actions))[:8]
all_decisions = list(dict.fromkeys(all_decisions))[:6]

# Last message body — walk backwards to find one that isn't empty after stripping quotes
last_body = ''
for raw in reversed(messages):
    candidate = strip_quotes(raw).strip()
    # Remove header lines (From:/Date:/Subject:)
    candidate = re.sub(r'^(?:from|to|cc|date|subject|sent)\s*:[^\n]+\n?', '', candidate,
                       flags=re.IGNORECASE | re.MULTILINE).strip()
    if len(candidate) > 20:
        last_body = candidate[:400]
        break
if not last_body:
    last_body = text[-400:].strip()

# ── Output ────────────────────────────────────────────────────────────────────
lines = ['=== BIBIVIDI: EMAIL THREAD SUMMARY ===']
lines.append(f'Subject  : {subject or "(not detected)"}')
lines.append(f'Messages : {len(messages)}  |  Last: {last_date or "unknown date"}')
lines.append(f'From     : {last_sender or "unknown"}')
if participants:
    lines.append(f'Participants: {", ".join(participants)}')

if all_actions:
    lines.append('\n[ACTION ITEMS]')
    for item in all_actions:
        lines.append(f'  - {item}')

if all_decisions:
    lines.append('\n[DECISIONS]')
    for item in all_decisions:
        lines.append(f'  - {item}')

lines.append('\n[LAST MESSAGE]')
lines.append(last_body)
lines.append(f'\n=== END (condensed from {len(text)} chars) ===')

print('\n'.join(lines))
