"""Graph validation and coverage reporting."""

from .models import FormGraph


def validate_graph(graph: FormGraph) -> list[str]:
    """
    Validate a FormGraph for completeness and consistency.

    Returns a list of warning strings. An empty list means the graph is valid.
    """
    warnings: list[str] = []

    if not graph.pages:
        warnings.append("Graph has no pages")
        return warnings

    all_field_ids: set[str] = set()

    for page in graph.pages:
        # Check for missing next_action_selector (except possibly the last page)
        if page.next_action_selector is None:
            warnings.append(f"Page '{page.page_id}' has no next_action_selector")

        if not page.fields:
            warnings.append(f"Page '{page.page_id}' has no fields")

        page_field_ids: set[str] = set()
        for field in page.fields:
            # Check for duplicate field_ids within a page
            if field.field_id in page_field_ids:
                warnings.append(f"Duplicate field_id '{field.field_id}' on page '{page.page_id}'")
            page_field_ids.add(field.field_id)
            all_field_ids.add(field.field_id)

            # Check for fields without value ranges
            if field.value_range is None:
                warnings.append(f"Field '{field.field_id}' on page '{page.page_id}' has no value_range")

            # Check visibility_condition references
            if field.visibility_condition is not None:
                rule_ids = {rule.rule_id for rule in page.conditionals}
                if field.visibility_condition not in rule_ids:
                    warnings.append(
                        f"Field '{field.field_id}' references visibility_condition "
                        f"'{field.visibility_condition}' which does not exist on page '{page.page_id}'"
                    )

        # Validate conditional rules
        for rule in page.conditionals:
            # Check trigger_field_id exists
            if rule.trigger_field_id not in page_field_ids:
                warnings.append(
                    f"Conditional rule '{rule.rule_id}' on page '{page.page_id}' references "
                    f"trigger_field_id '{rule.trigger_field_id}' which does not exist on this page"
                )

            # Check affected_field_ids exist
            for affected_id in rule.affected_field_ids:
                if affected_id not in page_field_ids:
                    warnings.append(
                        f"Conditional rule '{rule.rule_id}' on page '{page.page_id}' references "
                        f"affected_field_id '{affected_id}' which does not exist on this page"
                    )

            # Warn about unverified rules
            if not rule.verified:
                warnings.append(f"Conditional rule '{rule.rule_id}' on page '{page.page_id}' is not verified")

    return warnings


def get_coverage_report(graph: FormGraph) -> dict[str, int]:
    total_pages = len(graph.pages)
    total_fields = 0
    fields_with_value_range = 0
    fields_without_value_range = 0
    total_conditionals = 0
    verified_conditionals = 0
    unverified_conditionals = 0

    for page in graph.pages:
        total_fields += len(page.fields)
        for field in page.fields:
            if field.value_range is not None:
                fields_with_value_range += 1
            else:
                fields_without_value_range += 1

        total_conditionals += len(page.conditionals)
        for rule in page.conditionals:
            if rule.verified:
                verified_conditionals += 1
            else:
                unverified_conditionals += 1

    return {
        "total_pages": total_pages,
        "total_fields": total_fields,
        "fields_with_value_range": fields_with_value_range,
        "fields_without_value_range": fields_without_value_range,
        "total_conditionals": total_conditionals,
        "verified_conditionals": verified_conditionals,
        "unverified_conditionals": unverified_conditionals,
    }
