"""Schema validation — defines lead schema with validation rules.

Validates lead structure on save, ensures required fields, type checking,
enum validation for status fields.
"""

from typing import Any

LEAD_SCHEMA = {
    "required": [
        "id", "name", "lead_status",
        # Harvest metadata
        "filing_date", "harvested_at", "harvest_source", "temporal_category"
    ],
    "optional": [
        # Identity
        "entity_type", "citizenship", "naics", "agent_name", "agent_address",
        "business_id",
        
        # Location
        "city", "state", "zip", "street_address",
        
        # Contact
        "phone",

        # Email quality
        "email_is_filing_service",

        # Agent data (from Agents dataset)
        "agent_type",
        "agent_is_self",

        # Principal data (from Principals dataset)
        "principals",
        "principal_names",
        "primary_principal_name",
        "principal_designation",
        "greeting_name_source",
        "greeting_name",

        # Filing activity signals (from Filing History dataset)
        "last_filing_date",
        "last_filing_type",
        "filing_count",
        "has_recent_amendment",
        "uses_paper_filing",
        "annual_report_current",

        # Reply handling
        "reply_received",
        "reply_received_at",
        "reply_text",
        "reply_action",
        "response_drafted",
        "response_body",

        # Autoresponder tracking
        "last_autoresponder",

        # Bounce tracking
        "email_bounced",
        "email_bounce_reason",
        "email_bounced_at",

        # Competitive intelligence flags
        "principal_competitor_overlap",
        "principal_competitor_detail",
        "address_competitor_overlap",
        "address_competitor_detail",

        # Deal tracking (future)
        "deal_outcome",
        "deal_closed_at",
        
        # Temporal/milestone metadata (harvest-computed)
        "business_age_days", "business_age_months",
        "temporal_category",  # fresh/recent/historical
        "milestone_year", "milestone_window_hit", "milestone_proximity_days",
        
        # Enrichment
        "research_note", "touches", "current_sequence_position",
        "next_touch_due", "score", "priority", "readiness_weight",
        "has_research", "researched_at",
        "legacy_draft", "is_shell", "domain", "website_url",
        "website_exists", "website_last_checked", "brave_summary",
        "brave_phone", "brave_descriptions", "brave_website", "brave_last_searched", "county", "competitor_displacement",
        "competitor_brands", "competitor_summary", "equipment",
        "source", "pushed_to_zoho", "zoho_id", "first_seen", "last_updated", "lead_type",
        # Drafting
        "draft_subject", "draft_body", "draft_anchor", "draft_scenario",
        "draft_model", "draft_model_position", "drafted_at", "draft_status", "reviewed_at",
        "regen_count",
        "draft_error",

        # Operator intel
        "operator_intel",

        # Outreach control
        "burn_reason", "burned_at",
        "paused_at", "paused_reason",

        # Zoho push enrichment
        "description_pushed", "description_pushed_at",

        # Sequence engine
        "sequence",

        # Renewal-specific fields
        "equipment_model", "equipment_serial",
        "equipment_mono_meter", "equipment_color_meter",
        "equipment_age_months",
        "contract_expiration", "days_until_expiration",
        "contract_value", "contract_length_months",
        "recommended_upgrade", "upgrade_reason",
        "meter_insight", "upgrade_urgency",
        "zoho_deal_id",

        # Renewal classification (expired/upcoming)
        "renewal_classification", "renewal_urgency",

        # Enrichment status
        "enrichment_status",   # "enriched" or None
        "enriched_at",         # ISO timestamp
        "enrichment_phases",   # which phases produced data
    ],
    "enums": {
        "lead_status": ["imported_legacy", "active", "paused", "burned", "completed", "dead", "cancelled"],
        "channel": ["email", "phone", "linkedin"],
        "touch_status": ["sent", "delivered", "opened", "clicked", "replied", "bounced"],
        "temporal_category": ["fresh", "recent", "historical", "renewal_30", "renewal_60", "renewal_90", "renewal_120", "renewal_expired", "renewal_expired_recent"],
        "harvest_source": ["ct_sos", "zoho_renewal", "csv_import"],
        "draft_status": ["none", "drafted", "sent"],
    }
}


def validate_lead(lead: dict) -> tuple[bool, list[str]]:
    """Validate lead against schema.
    
    Args:
        lead: Lead dict to validate
    
    Returns:
        Tuple of (is_valid, list of error messages)
    """
    errors = []
    
    # Check required fields
    for field in LEAD_SCHEMA["required"]:
        if field not in lead:
            errors.append(f"Missing required field: {field}")
    
    # Check enum fields
    for field, allowed_values in LEAD_SCHEMA["enums"].items():
        if field in lead and lead[field] not in allowed_values:
            errors.append(f"Invalid value for {field}: {lead[field]} (expected one of {allowed_values})")
    
    # Check filing_date is present and valid ISO format
    if "filing_date" in lead and not lead["filing_date"]:
        errors.append("filing_date is required and cannot be empty")
    
    return (len(errors) == 0, errors)


def validate_research_note(note: dict) -> tuple[bool, list[str]]:
    """Validate research note structure.
    
    Args:
        note: Research note dict
    
    Returns:
        Tuple of (is_valid, list of error messages)
    """
    errors = []
    
    required_fields = ["researched_at", "sources", "findings"]
    for field in required_fields:
        if field not in note:
            errors.append(f"Missing required research note field: {field}")
    
    if note.get("findings") is not None and not isinstance(note.get("findings"), list):
        errors.append("research_note.findings must be a list")
    
    return (len(errors) == 0, errors)


def validate_touch(touch: dict) -> tuple[bool, list[str]]:
    """Validate touch structure.
    
    Args:
        touch: Touch dict
    
    Returns:
        Tuple of (is_valid, list of error messages)
    """
    errors = []
    
    required_fields = ["id", "sequence_position", "sent_at", "channel", "status"]
    for field in required_fields:
        if field not in touch:
            errors.append(f"Missing required touch field: {field}")
    
    # Check channel enum
    if touch.get("channel") not in ["email", "phone", "linkedin"]:
        errors.append(f"Invalid touch channel: {touch.get('channel')}")
    
    return (len(errors) == 0, errors)