"""Talent scouting — rank candidates for employer discovery panel."""

from app.schemas.common import JobStatus
from app.schemas.talent_scouting import (
    RankedCandidate,
    TalentScoutRankRequest,
    TalentScoutRankResponse,
)
from app.services.ai_generate import generate_json


class TalentScoutingService:
    async def rank(self, payload: TalentScoutRankRequest) -> TalentScoutRankResponse:
        system = (
            "Rank candidates for a hiring scout panel. Return JSON: "
            "{\"ranked\":[{\"candidate_id\",\"scout_score\",\"rationale\",\"matched_skills\":[]}]}"
        )
        user = (
            f"Role: {payload.role_title}\nJD: {payload.job_description}\n"
            f"Required skills: {payload.required_skills}\nNiche: {payload.niche}\n"
            f"Candidates: {[c.model_dump() for c in payload.candidates]}\n"
            f"Top K: {payload.top_k}"
        )

        def local() -> dict:
            scored: list[tuple[float, object, list[str]]] = []
            req = {s.lower() for s in payload.required_skills}
            for c in payload.candidates:
                skills_l = {s.lower() for s in c.skills}
                match = sorted(req & skills_l) if req else list(c.skills)[:3]
                base = 0.4
                if c.interview_pass_rate is not None:
                    base += 0.25 * max(0.0, min(1.0, c.interview_pass_rate))
                if c.task_score is not None:
                    base += 0.2 * max(
                        0.0,
                        min(
                            1.0,
                            c.task_score / 100.0 if c.task_score > 1 else c.task_score,
                        ),
                    )
                base += min(0.15, 0.03 * c.badge_count)
                if req:
                    base += 0.2 * (len(match) / max(1, len(req)))
                if payload.niche and c.niche and payload.niche.lower() == c.niche.lower():
                    base += 0.05
                scored.append((round(min(1.0, base), 3), c, match))
            scored.sort(key=lambda t: t[0], reverse=True)
            ranked = []
            for i, (score, c, match) in enumerate(scored[: payload.top_k], start=1):
                ranked.append(
                    {
                        "candidate_id": c.candidate_id,
                        "scout_score": score,
                        "rationale": f"Ranked #{i} for {payload.role_title} using skills/pass-rate/badges",
                        "matched_skills": match,
                    }
                )
            return {"ranked": ranked}

        data, stub, provider = await generate_json(
            system=system, user=user, local_factory=local
        )
        ranked: list[RankedCandidate] = []
        for i, row in enumerate(data.get("ranked") or [], start=1):
            if not isinstance(row, dict) or not row.get("candidate_id"):
                continue
            ranked.append(
                RankedCandidate(
                    candidate_id=str(row["candidate_id"]),
                    rank=i,
                    scout_score=float(row.get("scout_score") or 0),
                    rationale=row.get("rationale"),
                    matched_skills=list(row.get("matched_skills") or []),
                )
            )
        return TalentScoutRankResponse(
            correlation_id=payload.correlation_id,
            role_title=payload.role_title,
            status=JobStatus.SUCCEEDED,
            stub=stub,
            message=f"Talent scout ranking via {provider}",
            ranked=ranked,
        )
