#!/usr/bin/env bash
# Prints the set of jobs the user has ALREADY engaged with, for deduplication
# during a job search — so the same job is never found/imported twice, also on
# LATER runs. Combines existing Bewerbungen (/applications) and already-imported
# Jobangebote (/joboffers) from the Bewerbungs-Tracker API.
#
# Output: EINE Zeile pro bereits erfasster FIRMA (company-level), tab-separated:
#   firma_slug <TAB> firma <TAB> stelle <TAB> ort <TAB> quelle_url <TAB> external_id
#
#   firma_slug = robuster Firmen-Schlüssel (lowercase, Umlaute ae/oe/ue/ss,
#                Diakritika entfernt, (m/w/d) raus, End-Rechtsform-Tokens wie
#                gmbh/ag/kg entfernt, mit "-" verbunden). Identisch zu firmaSlug
#                in lib/blacklist.js des Servers — deckt Schreibweisen-/
#                Rechtsform-/Umlaut-Varianten EINER Firma ab.
#
# Regel: eine FIRMA darf nur EINMAL gefunden werden. Ein neuer Treffer gilt als
# Dublette (→ verwerfen), wenn seine Firma zu EINER Zeile hier passt:
#   * gleicher firma_slug, ODER
#   * ein firma_slug ist ein führendes Bindestrich-Präfix des anderen (≥2 Tokens)
#     — d. h. Kurzname vs. voller Firmenname ("it-problemloeser" ⊂
#     "it-problemloeser-verwaltungs-und-handels"), ODER
#   * gleiche quelle_url ODER gleiche external_id.
# Es wird bewusst NICHT mehr nach Stellentitel unterschieden — eine bereits
# erfasste Firma taucht mit KEINEM (auch nicht neuem) Titel wieder auf.
# HTML-Entities werden dekodiert.
#
# Reuses the bewerbungs-tracker skill's helper for auth/base-URL.
set -euo pipefail

BT="${BT_SCRIPT:-$HOME/.claude/skills/bewerbungs-tracker/scripts/bt.sh}"
if [[ ! -x "$BT" ]]; then
  echo "applied-set.sh: bewerbungs-tracker helper not found at $BT" >&2
  exit 2
fi

# In Tempdateien schreiben (NICHT in Env-Vars): die kombinierte JSON aus
# /applications + /joboffers wird groß; als Env-Var würde sie ARG_MAX (argv+envp)
# sprengen ("Argument list too long" beim python3-Start). Dateien lesen umgeht das.
TMPDIR_AS="$(mktemp -d)"
trap 'rm -rf "$TMPDIR_AS"' EXIT
APPS_FILE="$TMPDIR_AS/apps.json"
OFFERS_FILE="$TMPDIR_AS/offers.json"
"$BT" GET '/applications?limit=500' > "$APPS_FILE"
"$BT" GET '/joboffers'              > "$OFFERS_FILE"

APPS_FILE="$APPS_FILE" OFFERS_FILE="$OFFERS_FILE" python3 <<'PY'
import os, json, html, re, sys, unicodedata

def load(name):
    with open(os.environ[name], encoding='utf-8') as fh:
        raw = fh.read().split('<http')[0]
    try:
        return json.loads(raw)
    except Exception:
        return []

def clean(v):
    return html.unescape(str(v or '')).replace('\t', ' ').strip()

# Robuster Firmen-Schlüssel — MUSS mit firmaSlug() in lib/blacklist.js des
# Servers übereinstimmen (Umlaut-Translit, (m/w/d) raus, End-Rechtsform-Tokens
# entfernt, mit "-" verbunden), damit Skill- und Server-Dedup dieselbe Firma
# gleich erkennen.
_GENDER = re.compile(r'\((?:[mwdfax](?:\s*/\s*[mwdfax])*)\)', re.I)  # (m/w/d), (w/m/x)…
_LEGAL_FORMS = {
    'gmbh', 'ggmbh', 'mbh', 'ug', 'haftungsbeschraenkt', 'ag', 'kg', 'kgaa',
    'ohg', 'gbr', 'se', 'ek', 'eg', 'ev', 'partg', 'partmbb', 'co', 'cie',
    'inc', 'incorporated', 'llc', 'ltd', 'limited', 'plc', 'corp', 'corporation',
    'company', 'sa', 'sarl', 'sas', 'bv', 'nv', 'oy', 'ab', 'as', 'aps', 'srl', 'spa',
}
def firma_slug(s):
    t = html.unescape(str(s or '')).lower()
    t = (t.replace('ä', 'ae').replace('ö', 'oe').replace('ü', 'ue').replace('ß', 'ss'))
    t = unicodedata.normalize('NFKD', t)
    t = ''.join(c for c in t if not unicodedata.combining(c))
    t = _GENDER.sub(' ', t)
    t = re.sub(r'[^a-z0-9]+', ' ', t)
    t = re.sub(r'\s+', ' ', t).strip()
    if not t:
        return ''
    words = t.split(' ')
    kept = words[:]
    while len(kept) > 1 and kept[-1] in _LEGAL_FORMS:
        kept.pop()
    return '-'.join(kept if kept else words)

# Eine Firma nur EINMAL: pro firma_slug genau eine Zeile (erste gewinnt).
seen = set()
def emit(firma, stelle, ort, url, ext):
    slug = firma_slug(firma)
    if not slug or slug in seen:
        return
    seen.add(slug)
    print('\t'.join([slug, clean(firma), clean(stelle), clean(ort),
                     clean(url), clean(ext)]))

for a in load('APPS_FILE'):
    emit(a.get('firma'), a.get('stelle'), a.get('ort'), a.get('quelle_url'), '')
for o in load('OFFERS_FILE'):
    emit(o.get('firma'), o.get('stelle'), o.get('ort'), o.get('quelle_url'),
         o.get('external_id'))

print(f'# {len(seen)} bereits erfasste Firmen (Bewerbungen + Jobangebote)', file=sys.stderr)
PY
