from __future__ import annotations

from app.models import Job, Profile


def score_job_for_profile(job: Job, profile: Profile) -> tuple[float, list[str]]:
    score = 0.0
    reasons: list[str] = []
    text = f"{job.title} {job.company} {job.location} {job.description} {' '.join(job.tags or [])}".lower()

    skills = [s.lower() for s in (profile.skills or [])]
    keywords = [k.lower() for k in (profile.keywords or [])]
    roles = [r.lower() for r in (getattr(profile, "desired_roles", None) or [])]
    categories = [c.lower() for c in (getattr(profile, "job_categories", None) or [])]
    employment = [e.lower() for e in (getattr(profile, "employment_types", None) or [])]

    skill_hits = [s for s in skills if s and s in text]
    kw_hits = [k for k in keywords if k and k in text]
    role_hits = [r for r in roles if r and r in text]
    if skill_hits:
        bonus = min(40.0, len(skill_hits) * 4.0)
        score += bonus
        reasons.append(f"Skills: {', '.join(skill_hits[:6])}")
    if kw_hits:
        score += min(15.0, len(kw_hits) * 3.0)
        reasons.append(f"Keywords: {', '.join(kw_hits[:4])}")
    if role_hits:
        score += min(20.0, len(role_hits) * 5.0)
        reasons.append(f"Roles: {', '.join(role_hits[:4])}")

    cat_map = {
        "tech": ["developer", "software", "devops", "datos", "it", "programador", "engineer"],
        "health": ["enfermer", "médic", "salud", "nurse", "clinic", "sanitar"],
        "services": ["limpieza", "hogar", "atención", "cliente", "hostelería", "comercio"],
        "sales": ["ventas", "sales", "comercial", "account"],
        "education": ["profesor", "teacher", "educación", "formador"],
        "executive": ["director", "manager", "responsable", "chief", "head of"],
        "junior": ["junior", "becario", "prácticas", "graduate", "trainee"],
        "general": [],
    }
    for cat in categories:
        tokens = cat_map.get(cat, [cat])
        if any(t in text for t in tokens if t):
            score += 8.0
            reasons.append(f"Categoría {cat}")
            break

    if "remote" in employment or "remoto" in employment:
        if job.remote or "remote" in text or "remoto" in text:
            score += 10.0
            reasons.append("Tipo remoto deseado")
    if "hybrid" in employment and ("híbrid" in text or "hybrid" in text):
        score += 6.0
        reasons.append("Híbrido")

    if profile.remote_only:
        if job.remote or "remote" in text or "remoto" in text:
            score += 20.0
            reasons.append("Remoto compatible")
        else:
            score -= 25.0
            reasons.append("No remoto (penalización)")
    elif job.remote:
        score += 8.0
        reasons.append("Opción remota")

    if profile.salary_min and job.salary_min:
        job_min = job.salary_min
        if (job.salary_currency or "").upper() == "EUR" and (profile.salary_currency or "").upper() == "USD":
            job_min = int(job_min * 1.08)
        if job_min >= profile.salary_min:
            score += 20.0
            reasons.append(f"Salario >= {profile.salary_min} {profile.salary_currency}")
        elif job_min >= profile.salary_min * 0.75:
            score += 8.0
            reasons.append("Salario cercano al mínimo")
        else:
            score -= 10.0
            reasons.append("Salario por debajo del objetivo")
    elif profile.salary_min and not job.salary_min:
        reasons.append("Salario no publicado")

    targets = [c.upper() for c in (profile.target_countries or [])]
    loc = (job.location or "").upper()
    if targets:
        if any(t in loc or t == "WORLDWIDE" or "WORLDWIDE" in loc or "ANYWHERE" in loc for t in targets):
            score += 10.0
            reasons.append("Ubicación / país objetivo")
        if "ES" in targets and ("SPAIN" in loc or "ESPA" in loc or "VALENCIA" in loc or job.hire_from_spain_ok):
            score += 5.0
            reasons.append("Compatible con España")

    if job.requires_english_fluent and not profile.english_fluent:
        score -= 18.0
        reasons.append("Requiere inglés fluido (tú no)")
    elif not job.requires_english_fluent and job.lang == "es":
        score += 6.0
        reasons.append("Oferta en español / sin EN fluido")

    spanish_friendly_sources = {
        "getonboard",
        "infojobs",
        "tecnoempleo",
        "infoempleo",
        "jooble",
        "indeed_es",
        "empleate",
        "computrabajo_es",
    }
    if job.source in spanish_friendly_sources and not job.requires_english_fluent:
        score += 8.0
        reasons.append("Fuente ES/LATAM o sin EN fluido")
    if job.remote and job.lang == "es":
        score += 5.0
        reasons.append("Remoto en español")

    # Ubicación del perfil
    ploc = (profile.location or "").lower()
    if ploc and ploc.split(",")[0].strip() in text:
        score += 10.0
        reasons.append(f"Cerca de {profile.location}")

    score = max(0.0, min(100.0, score))
    if not reasons:
        reasons.append("Sin señales fuertes de match")
    return round(score, 1), reasons
