"""
Disambiguation Result Schema

Unified JSON schema for author disambiguation results.
Used for both structured output enforcement and validation.
"""

DISAMBIGUATION_RESULT_SCHEMA = {
    "type": "object",
    "properties": {
        # Status (required)
        "status": {
            "type": "string",
            "enum": ["success", "ambiguous", "not_found", "error"],
            "description": "Status of the disambiguation"
        },

        # Author candidates (always present, may be empty array)
        "author_candidates": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "rank": {
                        "type": "integer",
                        "description": "Rank of this candidate (1 = most likely)"
                    },
                    "author": {
                        "type": "object",
                        "properties": {
                            "openalex_id": {"type": "string"},
                            "openalex_url": {"type": "string"},
                            "name": {"type": "string"},
                            "orcid": {"type": ["string", "null"]},
                            "institution": {"type": ["string", "null"]},
                            "works_count": {"type": "integer"},
                            "cited_by_count": {"type": "integer"},
                         },
                        "required": ["openalex_id", "openalex_url", "name", "works_count", "cited_by_count"]
                    },
                    "evidence": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "List of evidence supporting this match"
                    },
                    "concerns": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "List of concerns or red flags about this match"
                    }
                },
                "required": ["rank", "author", "evidence"]
            },
            "description": "List of candidate authors (ordered by rank, may be empty)"
        },

        # Search summary (required)
        "search_summary": {
            "type": "object",
            "properties": {
                "embo_found": {"type": "boolean"},
                "orcid_source": {"type": "string"},
                "candidates_evaluated": {"type": "integer"},
                "disambiguation_needed": {"type": "boolean"}
            },
            "required": ["embo_found", "orcid_source", "candidates_evaluated", "disambiguation_needed"],
            "description": "Summary of search process"
        },

        # Message (optional - used for error, not_found, ambiguous cases)
        "message": {
            "type": "string",
            "description": "Human-readable message about the result"
        },

        # Error details (optional - used for error cases)
        "error": {
            "type": "string",
            "description": "Error message if status is 'error'"
        },

        # Additional info (optional - used for not_found cases)
        "possible_reasons": {
            "type": "array",
            "items": {"type": "string"},
            "description": "Possible reasons why no match was found"
        },
        "recommendation": {
            "type": "string",
            "description": "Recommendation for next steps"
        },

        # Comments (required)
        "comments": {
            "type": "string",
            "description": "Detailed process comments and reasoning"
        }
    },
    "required": ["status", "author_candidates", "search_summary", "comments"]
}


def validate_disambiguation_result(result: dict) -> tuple[bool, list[str]]:
    """
    Validate a disambiguation result against the schema.

    Args:
        result: Dictionary to validate

    Returns:
        Tuple of (is_valid, list_of_errors)
    """
    errors = []

    # Check required fields
    required_fields = ["status", "author_candidates", "search_summary", "comments"]
    for field in required_fields:
        if field not in result:
            errors.append(f"Missing required field: {field}")

    # Validate status
    if "status" in result:
        valid_statuses = ["success", "ambiguous", "not_found", "error"]
        if result["status"] not in valid_statuses:
            errors.append(f"Invalid status: {result['status']}. Must be one of {valid_statuses}")

    # Validate author_candidates
    if "author_candidates" in result:
        if not isinstance(result["author_candidates"], list):
            errors.append("author_candidates must be an array")
        else:
            for i, candidate in enumerate(result["author_candidates"]):
                if not isinstance(candidate, dict):
                    errors.append(f"author_candidates[{i}] must be an object")
                    continue

                # Check required candidate fields
                if "rank" not in candidate:
                    errors.append(f"author_candidates[{i}] missing required field: rank")
                if "author" not in candidate:
                    errors.append(f"author_candidates[{i}] missing required field: author")
                if "evidence" not in candidate:
                    errors.append(f"author_candidates[{i}] missing required field: evidence")

                # Validate author object
                if "author" in candidate and isinstance(candidate["author"], dict):
                    author_required = ["openalex_id", "openalex_url", "name", "works_count", "cited_by_count"]
                    for field in author_required:
                        if field not in candidate["author"]:
                            errors.append(f"author_candidates[{i}].author missing required field: {field}")

    # Validate search_summary
    if "search_summary" in result:
        if not isinstance(result["search_summary"], dict):
            errors.append("search_summary must be an object")
        else:
            summary_required = ["embo_found", "orcid_source", "candidates_evaluated", "disambiguation_needed"]
            for field in summary_required:
                if field not in result["search_summary"]:
                    errors.append(f"search_summary missing required field: {field}")

    return (len(errors) == 0, errors)
