"""
Domain Entities and Value Objects for Inverse-BIM Constraint Solver
and Tri-Source Truth Grounding (Reconciliation Engine).
Strict Hexagonal Architecture & Zero-Tolerance Synthetic Data.
"""

from __future__ import annotations

from datetime import datetime
from decimal import Decimal

from pydantic import BaseModel, Field


class CulvertCrossSection(BaseModel):
    """Parametric cross-section constraints of a reinforced concrete box culvert."""
    clear_span_m: Decimal = Field(default=Decimal("2.5000"), description="Khẩu độ thoát nước B (m)")
    clear_height_m: Decimal = Field(default=Decimal("2.5000"), description="Chiều cao thông thủy H (m)")
    wall_thickness_m: Decimal = Field(default=Decimal("0.3000"), description="Chiều dày thành cống t (m)")
    bottom_slab_thickness_m: Decimal = Field(default=Decimal("0.2500"), description="Chiều dày bản đáy (m)")
    top_slab_thickness_m: Decimal = Field(default=Decimal("0.2500"), description="Chiều dày bản mặt mái (m)")
    bottom_slab_width_m: Decimal = Field(default=Decimal("3.4000"), description="Bề rộng đáy móng cống B_day (m)")
    lean_concrete_thickness_m: Decimal = Field(default=Decimal("0.1000"), description="Chiều dày bê tông lót (m)")
    lean_concrete_width_m: Decimal = Field(default=Decimal("3.4000"), description="Bề rộng bê tông lót (m)")
    bamboo_pile_density_per_m2: Decimal = Field(default=Decimal("25.0000"), description="Mật độ cọc tre (cọc/m2)")
    bamboo_pile_length_m: Decimal = Field(default=Decimal("2.5000"), description="Chiều dài cọc tre (m)")
    haunch_size_m: Decimal = Field(default=Decimal("0.1500"), description="Kích thước vát nách/haunch (m)")


class CulvertSegmentModel(BaseModel):
    """Parametric model for an individual construction segment."""
    segment_id: int
    segment_name: str
    length_m: Decimal
    cross_section: CulvertCrossSection


class InverseBimParametricModel(BaseModel):
    """Inverse-BIM Parametric Constraint Model for civil and hydraulic structures."""
    structure_type: str = Field(default="box_culvert", description="Loại kết cấu: box_culvert, revetment, bridge")
    structure_name: str = Field(..., description="Tên công trình/hạng mục")
    total_length_m: Decimal = Field(..., description="Tổng chiều dài công trình (m)")
    num_segments: int = Field(default=5, description="Số phân đoạn thi công")
    segments: list[CulvertSegmentModel] = Field(default_factory=list)
    has_inlet_outlet_wings: bool = Field(default=True)
    inlet_outlet_wings_count: int = Field(default=2)
    cofferdam_larsen_pile_length_m: Decimal = Field(default=Decimal("12.0000"))
    cofferdam_sheet_perimeter_m: Decimal = Field(default=Decimal("96.0800"))


class SolidTakeoffQuantities(BaseModel):
    """Deterministic solid geometry quantities computed from Inverse-BIM constraints."""
    # Foundation
    lean_concrete_volume_m3: Decimal = Field(default=Decimal("0.0000"))
    bottom_slab_concrete_volume_m3: Decimal = Field(default=Decimal("0.0000"))
    bamboo_piles_total_100m: Decimal = Field(default=Decimal("0.0000"))
    bamboo_piles_count: int = Field(default=0)
    lean_concrete_formwork_100m2: Decimal = Field(default=Decimal("0.0000"))
    bottom_slab_formwork_100m2: Decimal = Field(default=Decimal("0.0000"))
    sand_cushion_volume_m3: Decimal = Field(default=Decimal("0.0000"))
    
    # Body walls & deck
    wall_concrete_volume_m3: Decimal = Field(default=Decimal("0.0000"))
    wall_formwork_100m2: Decimal = Field(default=Decimal("0.0000"))
    top_slab_concrete_volume_m3: Decimal = Field(default=Decimal("0.0000"))
    top_slab_formwork_100m2: Decimal = Field(default=Decimal("0.0000"))
    waterstop_m2: Decimal = Field(default=Decimal("0.0000"))

    # Inlet & outlet wing walls
    wing_bamboo_piles_100m: Decimal = Field(default=Decimal("0.0000"))
    wing_lean_concrete_m3: Decimal = Field(default=Decimal("0.0000"))
    wing_bottom_slab_concrete_m3: Decimal = Field(default=Decimal("0.0000"))
    wing_wall_concrete_m3: Decimal = Field(default=Decimal("0.0000"))
    wing_formwork_100m2: Decimal = Field(default=Decimal("0.0000"))

    # Earthwork & temporary measures
    slush_mud_suction_m3: Decimal = Field(default=Decimal("0.0000"))
    foundation_excavation_100m3: Decimal = Field(default=Decimal("0.0000"))
    mass_excavation_100m3: Decimal = Field(default=Decimal("0.0000"))
    soil_haul_100m3: Decimal = Field(default=Decimal("0.0000"))
    soil_backfill_100m3: Decimal = Field(default=Decimal("0.0000"))
    mountain_soil_material_m3: Decimal = Field(default=Decimal("0.0000"))
    larsen_pile_driving_100m: Decimal = Field(default=Decimal("0.0000"))
    larsen_pile_rental_m: Decimal = Field(default=Decimal("0.0000"))
    water_pumping_shifts: Decimal = Field(default=Decimal("0.0000"))
    ground_mat_segments: Decimal = Field(default=Decimal("0.0000"))
    geotextile_100m2: Decimal = Field(default=Decimal("0.0000"))


class BbsRebarScheduleItem(BaseModel):
    """Bar Bending Schedule (BBS) structural rebar schedule entry."""
    component_name: str = Field(..., description="Cấu kiện: Đáy cống, Thành cống, Bản mặt, Cửa cống")
    bar_mark: str = Field(..., description="Số hiệu thanh thép: 1, 2, 3...")
    diameter_mm: int = Field(..., description="Đường kính (mm)")
    length_per_bar_mm: Decimal = Field(..., description="Chiều dài 1 thanh (mm)")
    count_per_component: int = Field(...)
    total_bars_count: int = Field(...)
    total_length_m: Decimal = Field(...)
    unit_weight_kg_per_m: Decimal = Field(...)
    total_weight_kg: Decimal = Field(...)
    total_weight_ton: Decimal = Field(...)


class ReconciliationItem(BaseModel):
    """Single work item cross-audit entry across 3 sources of truth."""
    item_order: int
    wbs_code: str
    norm_code: str
    item_name: str
    unit: str
    source_cad_geometry_qty: Decimal | None = None
    source_bbs_rebar_qty: Decimal | None = None
    source_hsmt_tender_qty: Decimal
    unit_price_vnd: Decimal = Field(default=Decimal("0.0000"))
    total_amount_vnd: Decimal = Field(default=Decimal("0.0000"))
    variance_delta: Decimal = Field(default=Decimal("0.0000"))
    variance_percentage: Decimal = Field(default=Decimal("0.0000"))
    status: str = Field(default="MATCHED_100%", description="MATCHED_100%, DISCREPANCY_FLAGGED, REFERENCE_ONLY")
    reconciliation_note: str = ""


class TriSourceAuditReport(BaseModel):
    """Tri-Source Truth Grounding Comprehensive Reconciliation Audit Report."""
    project_name: str
    package_name: str
    contractor_tax_id: str = "0202111150"
    contractor_name: str = "Công ty TNHH Xây Dựng Định Sơn"
    legal_basis: str = "Luật Xây dựng 2025, Định mức 2026, TT38/TT11/TT14"
    audit_timestamp: datetime = Field(default_factory=datetime.utcnow)
    total_items_audited: int
    matched_items_count: int
    discrepancy_items_count: int
    overall_confidence_score: int = 100
    confidence_level: str = "tri_source_grounded_100"
    total_direct_cost_vnd: Decimal
    total_construction_bid_vnd: Decimal
    reconciliation_items: list[ReconciliationItem] = Field(default_factory=list)
    executive_summary: str = ""
    audit_notes: list[str] = Field(default_factory=list)
