"""
Boundary Commission Data Models
Extended models for boundary management, disputes, and interstate coordination
"""

from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any
from datetime import date, datetime
from enum import Enum


class BoundaryType(str, Enum):
    """Types of boundaries managed by the commission"""
    INTERSTATE = "interstate"  # Between states
    INTERNATIONAL = "international"  # Between countries
    ADMINISTRATIVE = "administrative"  # Within state (LGA, etc.)
    CUSTOMARY = "customary"  # Traditional boundaries
    DISPUTED = "disputed"  # Under dispute


class DisputeStatus(str, Enum):
    """Status of boundary disputes"""
    PENDING = "pending"
    UNDER_INVESTIGATION = "under_investigation"
    MEDIATION = "mediation"
    ADJUDICATION = "adjudication"
    RESOLVED = "resolved"
    APPEALED = "appealed"
    CLOSED = "closed"


class BoundaryMarkerType(str, Enum):
    """Types of physical boundary markers"""
    PILLAR = "pillar"
    BEACON = "beacon"
    MONUMENT = "monument"
    NATURAL = "natural"  # River, mountain, etc.
    GPS_COORDINATE = "gps_coordinate"


class Boundary(BaseModel):
    """Main boundary record"""
    id: Optional[int] = None
    boundary_number: str = Field(..., description="Unique boundary identifier")
    name: str = Field(..., description="Boundary name/description")
    boundary_type: BoundaryType
    state_a: str = Field(..., description="First state/entity")
    state_b: str = Field(..., description="Second state/entity")
    length_km: Optional[float] = None
    established_date: Optional[date] = None
    legal_basis: Optional[str] = None  # Treaty, law, etc.
    status: str = "active"
    description: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


class BoundaryCoordinate(BaseModel):
    """GIS coordinate for boundary points"""
    id: Optional[int] = None
    boundary_id: int
    sequence: int = Field(..., description="Order along boundary")
    latitude: float
    longitude: float
    elevation: Optional[float] = None
    coordinate_system: str = Field(default="WGS84", description="Coordinate reference system")
    accuracy: Optional[float] = None  # In meters
    survey_date: Optional[date] = None
    survey_method: Optional[str] = None  # GPS, satellite, etc.


class BoundaryMarker(BaseModel):
    """Physical boundary marker"""
    id: Optional[int] = None
    boundary_id: int
    marker_number: str = Field(..., description="Unique marker identifier")
    marker_type: BoundaryMarkerType
    latitude: float
    longitude: float
    elevation: Optional[float] = None
    marker_condition: Optional[str] = Field(None, description="Marker condition: good, damaged, missing")
    last_inspection_date: Optional[date] = None
    description: Optional[str] = None
    photos: Optional[List[str]] = None  # URLs to photos


class BoundaryDispute(BaseModel):
    """Boundary dispute case"""
    id: Optional[int] = None
    dispute_number: str = Field(..., description="Unique dispute identifier")
    boundary_id: Optional[int] = None
    title: str = Field(..., description="Dispute title/summary")
    description: str
    status: DisputeStatus = DisputeStatus.PENDING
    claimant_a: str = Field(..., description="First claimant (state/entity)")
    claimant_b: str = Field(..., description="Second claimant")
    disputed_area_km2: Optional[float] = None
    filed_date: date
    resolution_date: Optional[date] = None
    resolution_summary: Optional[str] = None
    legal_reference: Optional[str] = None
    assigned_officer: Optional[str] = None
    priority: str = "normal"  # low, normal, high, urgent
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


class DisputeEvidence(BaseModel):
    """Evidence document for disputes"""
    id: Optional[int] = None
    dispute_id: int
    document_type: str  # survey, treaty, map, testimony, etc.
    title: str
    description: Optional[str] = None
    document_url: Optional[str] = None
    file_path: Optional[str] = None
    submitted_by: Optional[str] = None
    submitted_date: date
    is_primary: bool = False  # Primary evidence vs supporting


class BoundarySurvey(BaseModel):
    """Survey data for boundaries"""
    id: Optional[int] = None
    boundary_id: int
    survey_number: str = Field(..., description="Survey reference number")
    survey_date: date
    survey_team: Optional[str] = None
    survey_method: str  # GPS, satellite, traditional, etc.
    accuracy: Optional[float] = None
    report_url: Optional[str] = None
    notes: Optional[str] = None
    approved: bool = False
    approved_by: Optional[str] = None
    approved_date: Optional[date] = None


class BoundaryTreaty(BaseModel):
    """Treaties and agreements related to boundaries"""
    id: Optional[int] = None
    boundary_id: Optional[int] = None
    treaty_number: str = Field(..., description="Treaty reference number")
    title: str
    signing_date: date
    effective_date: Optional[date] = None
    parties: List[str] = Field(..., description="Signatory states/entities")
    document_url: Optional[str] = None
    summary: Optional[str] = None
    status: str = "active"  # active, superseded, void


class Stakeholder(BaseModel):
    """Extended stakeholder information for disputes"""
    id: Optional[int] = None
    name: str
    entity_type: str  # state, lga, community, organization
    contact_person: Optional[str] = None
    email: Optional[str] = None
    phone: Optional[str] = None
    address: Optional[str] = None
    role: Optional[str] = None  # claimant, respondent, witness, etc.
    notes: Optional[str] = None


class BoundarySearchResult(BaseModel):
    """Search result for boundary queries"""
    boundary: Boundary
    coordinates: List[BoundaryCoordinate]
    markers: List[BoundaryMarker]
    active_disputes: List[BoundaryDispute]
    recent_surveys: List[BoundarySurvey]
    related_treaties: List[BoundaryTreaty]


class DisputeSearchResult(BaseModel):
    """Search result for dispute queries"""
    dispute: BoundaryDispute
    boundary: Optional[Boundary] = None
    evidence: List[DisputeEvidence] = Field(default_factory=list)
    stakeholders: List[Stakeholder] = Field(default_factory=list)
    timeline: List[Dict[str, Any]] = Field(default_factory=list)  # Event timeline
