import re
import spacy
import pandas as pd

nlp = spacy.load("en_core_web_sm")

joblike_verbs = {
    "eat","stop","avoid","manage","reduce","improve","learn","organize",
    "control","find","save","track","lose","build","make","change","start",
    "finish","get","keep","stay","quit"
}

def expand_single_word(job, text):
    """If extracted job is a single word, try to expand using next word(s)."""
    words = text.split()
    if job in words:
        idx = words.index(job)
        # Check next 2 words as possible objects
        if idx + 1 < len(words):
            next_word = words[idx+1]
            return f"{job} {next_word}"
    return job

def extract_explicit_jobs(text):
    if not isinstance(text, str):
        return []

    patterns = [
        r"\bI want to\s+([^.,;!?]+)",
        r"\bI need to\s+([^.,;!?]+)",
        r"\bSo I can\s+([^.,;!?]+)",
        r"\bIn order to\s+([^.,;!?]+)",
        r"\bIt(?:'s| is) important to\s+([^.,;!?]+)",
        r"\bHelp me\s+([^.,;!?]+)",
        rf"\bI(?:'m)?\s*try(?:ing)? to\s+({'|'.join(joblike_verbs)})\s*([^.,;!?]+)"
    ]

    jobs = []
    for pat in patterns:
        matches = re.findall(pat, text, re.IGNORECASE)
        if matches:
            if isinstance(matches[0], tuple):
                for m in matches:
                    jobs.append(" ".join(m).strip())
            else:
                jobs.extend([m.strip() for m in matches])

    # Expand single-word matches
    expanded = [expand_single_word(j, text) if len(j.split()) == 1 else j for j in jobs]
    return list(set(expanded))


def extract_implicit_jobs(text):
    if not isinstance(text, str):
        return []

    doc = nlp(text)
    jobs = []

    for token in doc:
        if token.pos_ == "VERB" and token.lemma_ in joblike_verbs:
            phrase = token.lemma_

            objs = [child.text for child in token.children if child.dep_ in ("dobj","pobj","attr")]
            mods = [child.text for child in token.children if child.dep_ in ("advmod","amod")]

            if objs:
                phrase += " " + " ".join(objs)
            if mods:
                phrase += " " + " ".join(mods)

            jobs.append(phrase.strip())

    # Expand single words
    expanded = [expand_single_word(j, text) if len(j.split()) == 1 else j for j in jobs]
    return list(set(expanded))


def extract_jobs(text):
    explicit = extract_explicit_jobs(text)
    implicit = extract_implicit_jobs(text)
    combined = list(set(explicit + implicit))
    return combined if combined else None
