"""ValueCodeValidator — validates UB-04 value codes and amounts."""

from __future__ import annotations

import re

from claim_validator.constants import Severity
from claim_validator.models.institutional import InstitutionalClaimData
from claim_validator.models.results import Finding, ValidatorOutput
from claim_validator.validators.base import BaseValidator

_VALUE_CODE_PATTERN = re.compile(r"^[A-Z0-9]{2}$")

# Value codes that require an associated amount
_AMOUNT_REQUIRED_CODES: set[str] = set()

for _start, _end in [
    (1, 24), (31, 44), (45, 49), (50, 99),
]:
    for _i in range(_start, _end + 1):
        _AMOUNT_REQUIRED_CODES.add(f"{_i:02d}")

# Alpha codes A1-A9 require amounts
for _digit in range(1, 10):
    _AMOUNT_REQUIRED_CODES.add(f"A{_digit}")


class ValueCodeValidator(BaseValidator):
    """Validates value codes and amounts on institutional (UB-04) claims."""

    name = "ValueCodeValidator"

    def validate(self, claim: InstitutionalClaimData) -> ValidatorOutput:
        """Validate value codes on an institutional claim."""
        findings: list[Finding] = []

        if not hasattr(claim, "value_codes") or not claim.value_codes:
            return self._make_output(findings)

        for vc in claim.value_codes:
            upper_code = vc.code.upper()
            if not _VALUE_CODE_PATTERN.match(upper_code):
                findings.append(
                    self._make_finding(
                        code="INST_INVALID_VALUE_CODE",
                        message=f"Value code '{vc.code}' does not match the required 2-character alphanumeric format",
                        severity=Severity.ERROR,
                        field_name="value_codes",
                    )
                )
            elif upper_code in _AMOUNT_REQUIRED_CODES and (vc.amount is None or vc.amount <= 0):
                findings.append(
                    self._make_finding(
                        code="INST_MISSING_VALUE_CODE_AMOUNT",
                        message=f"Value code {upper_code} has no associated amount",
                        severity=Severity.WARNING,
                        field_name="value_codes",
                    )
                )

        return self._make_output(findings)
