"""PlaceOfServiceValidator -- validates POS codes against CMS table."""

from __future__ import annotations

from claim_validator.constants import Severity
from claim_validator.models.claim import ClaimData
from claim_validator.models.results import Finding, ValidatorOutput
from claim_validator.shared.code_tables.pos import lookup_pos
from claim_validator.validators.base import BaseValidator


class PlaceOfServiceValidator(BaseValidator):
    """Validates place of service codes at claim and line level."""

    name = "PlaceOfServiceValidator"

    def validate(self, claim: ClaimData) -> ValidatorOutput:
        findings: list[Finding] = []

        # Claim-level POS
        if claim.place_of_service is not None and claim.place_of_service.strip():
            if lookup_pos(claim.place_of_service) is None:
                findings.append(
                    self._make_finding(
                        code="INVALID_PLACE_OF_SERVICE",
                        message=(
                            f"Place of service code {claim.place_of_service}"
                            " is not a valid CMS POS code"
                        ),
                        severity=Severity.ERROR,
                        field_name="place_of_service",
                        suggestion=(
                            "Use a valid 2-digit CMS Place of Service code"
                            " (e.g., 11=Office, 21=Inpatient Hospital)"
                        ),
                    )
                )

        # Line-level POS
        for idx, line in enumerate(claim.lines, start=1):
            if line.place_of_service is not None and line.place_of_service.strip():
                if lookup_pos(line.place_of_service) is None:
                    findings.append(
                        self._make_finding(
                            code="INVALID_PLACE_OF_SERVICE",
                            message=(
                                f"Place of service code {line.place_of_service}"
                                " is not a valid CMS POS code"
                            ),
                            severity=Severity.ERROR,
                            field_name="place_of_service",
                            line_number=idx,
                            suggestion=(
                                "Use a valid 2-digit CMS Place of Service code"
                                " (e.g., 11=Office, 21=Inpatient Hospital)"
                            ),
                        )
                    )

        return self._make_output(findings)
