"""
BSS Skill: CV Profile Extractor
Parses a CV / résumé from PROMPT and outputs a structured profile:
name, contact, experience (with years), skills, education, languages.
"""
import re

text = PROMPT  # injected by BIBIVIDI sandbox wrapper

# ── Contact ───────────────────────────────────────────────────────────────────

def get_email(txt):
    m = re.search(r'[\w.+-]+@[\w.-]+\.\w{2,}', txt)
    return m.group(0) if m else ''


def get_phone(txt):
    m = re.search(
        r'(?:\+\d{1,3}[\s.\-]?)?(?:\(0\d\)|0\d)[\s.\-]?\d{2}[\s.\-]?\d{2}[\s.\-]?\d{2}[\s.\-]?\d{2}'
        r'|\+\d{1,3}[\s.\-]?\d{2,4}[\s.\-]?\d{2,4}[\s.\-]?\d{2,4}',
        txt,
    )
    return m.group(0).strip() if m else ''


def get_linkedin(txt):
    m = re.search(r'linkedin\.com/in/([\w\-]+)', txt, re.IGNORECASE)
    return f'linkedin.com/in/{m.group(1)}' if m else ''


def get_name(txt):
    """Name is typically the first prominent short line with no @, no digits."""
    for line in txt.splitlines():
        line = line.strip()
        if not line or len(line) < 3 or len(line) > 60:
            continue
        if re.search(r'[@\d|/\\]', line):
            continue
        if re.match(r'(?:résumé|cv|curriculum|profil|profile|summary|contact)', line, re.IGNORECASE):
            continue
        # 2–5 words, letters + spaces + hyphens only
        if re.match(r'^[A-ZÀ-Ÿa-zà-ÿ][\w\sÀ-ÿ\-]{1,55}$', line) and 1 < len(line.split()) <= 5:
            return line
    return ''


# ── Section splitting ─────────────────────────────────────────────────────────

SECTION_PATTERNS = {
    'experience':     r'(?:experience|expérience|work history|emplois?|parcours professionnel|employment)',
    'education':      r'(?:education|formation|études|academic|diplômes?|qualifications?)',
    'skills':         r'(?:skills?|compétences?|technical skills?|expertise|technologies)',
    'languages':      r'(?:languages?|langues?)',
    'certifications': r'(?:certifications?|certifiés?|licenses?)',
}


def split_sections(txt):
    """Return a dict {section_name: text_block}."""
    pattern = re.compile(
        r'^(?:#+\s*)?(' + '|'.join(SECTION_PATTERNS.values()) + r')\s*[:\-–]?\s*$',
        re.IGNORECASE | re.MULTILINE,
    )
    sections = {k: '' for k in SECTION_PATTERNS}
    boundaries = [(m.start(), m.end(), m.group(1)) for m in pattern.finditer(txt)]

    for i, (start, end, header) in enumerate(boundaries):
        next_start = boundaries[i + 1][0] if i + 1 < len(boundaries) else len(txt)
        block = txt[end:next_start].strip()
        for key, pat in SECTION_PATTERNS.items():
            if re.match(pat, header, re.IGNORECASE):
                sections[key] += '\n' + block
                break

    return sections


# ── Experience ────────────────────────────────────────────────────────────────

DATE_RANGE_RE = re.compile(
    r'((?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec'
    r'|jan|fév|mars|avr|mai|juin|juil|août)\.?\s*)?\d{4}'
    r'\s*[-–—]\s*'
    r'(?:((?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec'
    r'|jan|fév|mars|avr|mai|juin|juil|août)\.?\s*)?\d{4}'
    r'|present|current|aujourd\'hui|maintenant|now)',
    re.IGNORECASE,
)


def parse_experience(txt):
    """Extract job entries anchored on date ranges using finditer."""
    entries = []
    matches = list(DATE_RANGE_RE.finditer(txt))
    for i, m in enumerate(matches):
        # Look backwards for the role line (the last non-empty line before the date)
        before = txt[max(0, m.start() - 300):m.start()].strip()
        before_lines = [l.strip() for l in before.splitlines()
                        if l.strip() and not re.match(r'^[-•]', l.strip())]
        role_line = before_lines[-1][:80] if before_lines else ''

        # Split "Title @ Company" if the separator is present
        if ' @ ' in role_line:
            parts = role_line.split(' @ ', 1)
            title, company = parts[0].strip(), parts[1].strip()
        elif ' at ' in role_line.lower():
            parts = re.split(r'\bat\b', role_line, 1, flags=re.IGNORECASE)
            title, company = parts[0].strip(), parts[1].strip()
        else:
            title, company = role_line, ''

        if title:
            entries.append({'dates': m.group(0), 'title': title, 'company': company})
    return entries[:8]


def estimate_years(txt):
    years = [int(y) for y in re.findall(r'\b(20\d{2}|19\d{2})\b', txt)]
    if len(years) >= 2:
        return max(years) - min(years)
    return None


# ── Skills ────────────────────────────────────────────────────────────────────

def parse_skills(txt):
    items = re.split(r'[,\n•·|/;]+', txt)
    return [s.strip() for s in items if s.strip() and 1 < len(s.strip()) < 50][:25]


# ── Languages ─────────────────────────────────────────────────────────────────

LEVEL_RE = re.compile(
    r'(native|fluent|professional|intermediate|basic|elementary|'
    r'courant|natif|bilingue|débutant|[ABC][12])',
    re.IGNORECASE,
)


def parse_languages(txt):
    langs = []
    for line in txt.splitlines():
        line = line.strip()
        if not line or len(line) > 60:
            continue
        lang_m = re.match(r'^[-•]?\s*([A-ZÀ-Ÿa-zà-ÿ\s]{3,25})', line)
        if lang_m:
            lang = lang_m.group(1).strip()
            level_m = LEVEL_RE.search(line)
            level = level_m.group(1) if level_m else ''
            langs.append(f'{lang} ({level})' if level else lang)
    return list(dict.fromkeys(langs))[:6]


# ── Parse & output ────────────────────────────────────────────────────────────
name     = get_name(text)
email    = get_email(text)
phone    = get_phone(text)
linkedin = get_linkedin(text)
sections = split_sections(text)

# Fall back to full text for experience if section not found
exp_txt  = sections['experience'] or text
exp      = parse_experience(exp_txt)
exp_yrs  = estimate_years(exp_txt)
skills   = parse_skills(sections['skills'])
langs    = parse_languages(sections['languages'])
edu      = sections['education'][:400].strip() if sections['education'] else ''
certs    = sections['certifications'][:300].strip() if sections['certifications'] else ''

lines = ['=== BIBIVIDI: CV PROFILE ===']
if name:
    lines.append(f'Name    : {name}')

contact_parts = [p for p in [email, phone, linkedin] if p]
if contact_parts:
    lines.append(f'Contact : {" | ".join(contact_parts)}')

if exp_yrs is not None:
    lines.append(f'Exp     : ~{exp_yrs} years')

if exp:
    lines.append('\n[EXPERIENCE]')
    for e in exp:
        parts = [e['dates']]
        if e['title']:
            parts.append(e['title'])
        if e['company']:
            parts.append(e['company'])
        lines.append(f'  - {" @ ".join(p for p in [e["title"], e["company"]] if p)} ({e["dates"]})')

if skills:
    lines.append('\n[SKILLS]')
    lines.append('  ' + ', '.join(skills))

if langs:
    lines.append('\n[LANGUAGES]')
    for l in langs:
        lines.append(f'  - {l}')

if edu:
    lines.append('\n[EDUCATION]')
    for line in edu.splitlines():
        if line.strip():
            lines.append(f'  {line.strip()}')

if certs:
    lines.append('\n[CERTIFICATIONS]')
    for line in certs.splitlines():
        if line.strip():
            lines.append(f'  {line.strip()}')

lines.append(f'\n=== END (condensed from {len(text)} chars) ===')

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