"""Airtable IDs + constants for the LFCS Pricing Agent (M0/M1 build, 2026-05-07).

Single source of truth for table + field IDs. Update here when schema changes;
nothing else in the codebase should hard-code these.
"""

BASE_ID = "appE43UvTyARe5oJs"  # LFCS-Operations (also holds _methodology_* tables per T1-fail fallback)


# Operational tables (existing or new)
TBL = {
    # Existing
    "Jobs": "tblcL2EX2w34c1VPe",
    "Drawings": "tblZPi452zZKvLliE",
    "Drawing_Elements": "tbl3wYZTpiuNxaRvH",
    "Revisions": "tblC04YN5rtqlKvNK",
    "Specifications": "tblLyH61zVNI9I2Zu",
    "Suppliers": "tblPCBJeNz8XpDum0",
    "Bids": "tblbDMfYrPHOE3wOX",
    "Bid_Line_Items": "tbllVlBA0X0pwoCdv",
    "RFIs": "tbl6cWepHgiVMpt40",
    "Rates": "tbl9fewvyRmL18UrA",
    "Variations": "tblpyDAPubw1V9cNO",
    # New operational (M0)
    "Bid_Line_Item_Overrides": "tblPp9hjyWvWdRYIK",
    "Commercial_Events": "tbl6LXA7evO4CzZTD",
    "_Internal_Audit_Trail": "tblSjvdXg8imY3rUy",
    "_Internal_Session_Logs": "tblrkb9vRtgiSPNtC",
    "_Internal_Sanitisation_Log": "tblZ1syjOOeoaR8SP",
    # Methodology (M0, _methodology_* prefix per T1-fail fallback)
    "_methodology_Element_Taxonomy": "tblDg9GpOdpYxcbTk",
    "_methodology_Reason_Code_Taxonomy": "tblt6UKtvUR91yS5u",
    "_methodology_Concept_Patterns": "tblZO2Xd6ptyn4Ix2",
    "_methodology_Common_Misses_Patterns": "tbla5FNdVt2jpI9Fw",
    "_methodology_Pre_Pricing_Grill_Templates": "tblGO7F1bCFvrQZL5",
    "_methodology_Productivity_Benchmarks": "tblxfJcdJ9hu8Pqf7",
    "_methodology_Rate_Templates": "tblZjsFrLp0AJwLDw",
    "_methodology_Exclusion_Library": "tblzrBAVpgvTzLxjZ",
}


# Field IDs grouped by table — only the fields we read/write programmatically.
# Add more as the codebase needs them; no need to mirror every field.
FIELD = {
    "Bid_Line_Item_Overrides": {
        "id": "fldfR7ld549jvU62A",
        "bid_line_item": "fldrlOPnXSEDhe7sy",
        "original_rate_ex_gst": "fldiekihpSR3vEOLZ",
        "override_rate_ex_gst": "fldahatis66oes4aN",
        "original_qty": "fldJWkdVR0rBSopBR",
        "override_qty": "fld9snMPoUwAtLhEL",
        "reason_codes": "fldwFFfU3MuQ1YVCx",
        "reviewer_type": "fldUtCoO3QYFztWHP",
        "reviewer_name": "fldTyYt2StEa989Je",
        "free_text_rationale": "fldSoJPvr5khqTcKB",
        "verbal_capture": "fldWPVpe5Ug5UURxV",
        "verbal_transcript_excerpt": "fldXbgDZqaMwnlrGL",
        "created_at": "fldpCSmivns7QKykP",
        "session_ref": "fldvHp1gYTnrnpuuq",
        "linked_session_log": "fldbUKYjdoDVhkN72",
        "linked_methodology_pattern": "fldEqmNUf95tMlYye",
        "feedback_to_methodology": "fldWVBqcxCflrJpVQ",
        "_internal_agent_first_pass_confidence": "fldeXq48Xb2Widpcr",
        "_internal_agent_prompt_ref": "fld4vGuCIcS1jAQpq",
        "linked_rate_template": "fldsScSalLIsBDJCb",
        "delta_dollars": "fldPQ5cXXTdQyhYyn",
        "delta_pct": "fldqu7LV4YbGhXrR7",
    },
    "_Internal_Session_Logs": {
        "id": "fldZeBQNrSodY6vDS",
        "session_ref": "fldhXU2nj7N7csxst",
        "agent_id": "fld1sLr8sYEgXXgZH",
        "started_at": "fldW2Nx3XfjPOMMxo",
        "ended_at": "fldVxwiXkNzkNxZ4N",
        "participant_names": "fldDBStYb4rT5z0vD",
        "transcript_summary": "fldoYYuGSD7Vtdc6k",
        "linked_bid": "fldGcehKbF1vU8Wwq",
        "capture_mode": "fldadKKZipvmdRB8r",
    },
    "_Internal_Audit_Trail": {
        "id": "fldBvXzbOJZqv0YLr",
        "event_type": "fld7iOdGKbhohWOzS",
        "linked_record_table": "fldHhnIGJ2qb4p5NA",
        "linked_record_id": "fldJnHVtwlZiKoUc2",
        "agent_id": "fldXjj9XCmX19Bbrp",
        "agent_model": "fldVokiMCnw1K20Lb",
        "prompt_ref": "fldoG97u8HHAj0jny",
        "confidence": "fldHhiKH1pvdddgZ0",
        "created_at": "fldqsKTruV9ZChQCM",
        "notes": "fldjnwLFW7Rpb01Cg",
    },
    "_Internal_Sanitisation_Log": {
        "id": "fld6Ey1YdNAR2ry8U",
        "source_artefact_ref": "fld0Oaoo2t7TgMRDV",
        "target_artefact_drive_id": "fldRyIG7ILQgaMIMW",
        "target_artefact_recipient": "fldtIfJPAUi2YzxNQ",
        "fields_stripped": "fld9TcTpCCrDWowDS",
        "regex_strips_applied": "fldF9sSS2qOWfOdbv",
        "metadata_overrides": "fldnYxzV4TRXgoeFj",
        "sanitised_at": "fldXV684XbxHxEPVX",
        "sanitised_by_skill": "fldzv46u2wvFJW4yD",
        "linked_bid": "fld3F4fz45c1hSGF5",
        "verified_by_human": "fldwtXRI5xZJ3pgKc",
        "layer1_pass": "fld73bUnGJA6fcQnl",
        "layer2_pass": "fld4a3frZkY2zJ4UX",
        "layer2_failures": "fldxZHOmPqLv5seb3",
    },
    "Bid_Line_Items": {
        "Line_ID": "fldErIB6fIOCYtePC",
        "Bid": "fldviWPaBDbsK1pfY",
        "Item_no": "fldAbIJiQxphvYiQc",
        "Description": "fld956CUCqRkNRjf7",
        "Unit": "fld1TeiM7ZMGqbP2q",
        "Qty": "fld53GFFutWmgiQL8",
        "Rate_ex_GST": "fldYeBAISvJRO7yDB",
        "Source_Rate": "flddEtE3bKDVMIrXM",
        "Element": "fldEGRiiySEBpaX7H",
        "Notes": "fldzWKU4uL38n2iFQ",
        "Total_ex_GST": "fldN7j1DTCFckd6mu",
        "complexity_factors": "fldgP9oUE8IoqDAcl",
        "_internal_first_pass_rate": "fldECjfyeOMluG24O",
        "_internal_first_pass_confidence": "fld0FtFWHzLVrMDDk",
        "_internal_methodology_template_ref": "fldNTPUVbUoY0x4an",
    },
    "Bids": {
        "Bid_ID": "fldIYUlIQjMlplDM4",
        "Job": "fldtxeGaQSh0tuo5h",
        "Status": "fldYx8bnZrL1oNWR3",
        "Pricing_Basis": "fldK6ZiZfajDRp5VN",
        "Bid_Due": "fldK0xTCuMn4PrVst",
        "Submitted_Date": "fldC5REPgOpzauKQq",
        "Total_ex_GST": "fldzUuqfPjeuluBf1",
        "Margin_pct": "fld3QhnPVqRKm7THZ",
        "final_submitted_total_ex_gst": "fldNK5havIdnGRqHp",
        "final_submitted_date": "fldwQBp7u6Fm6gKV5",
        "final_authored_by": "fldQOH7ViqHsyZnoM",
        "final_artefact_drive_id": "fldISXPQIzXYuGBSF",
        "final_artefact_email_thread_id": "fldabVu1lwzntbyjT",
        "_internal_first_pass_total_ex_gst": "fldcq89xoxDsIex0J",
        "_internal_first_pass_confidence_avg": "fldI32qtFwX0uv0Rf",
    },
    "Jobs": {
        "Job_Number": "fldyqepkJiEsUnqUW",
        "Name": "fldn0UXmn8pGcFmaZ",
        "Client": "fld8ORg1dZHgfQ0li",
        "Status": "fldNpgvbY6XoLK8E8",
        "job_category": "fldoowi1D9qNbvgFF",
        "_internal_first_pass_authored_by": "fldPd3XuNG2EcFfq8",
    },
}


# Reason code domain → record ID map (M0 seed)
REASON_CODES = {
    "SCOPE-SHIFT": "receJ0ljnWhdNf57n",
    "RATE-BASIS": "recM948o52t9NV97E",
    "PRELIM-VISIBILITY": "rec5xOvsDdl9QJjyL",
    "STRUCTURAL-ADD": "rec8PwMucSnvffIYR",
    "STRUCTURAL-DEDUCT": "recoZs4z9cEy4Nasm",
    "POSTURE-MISMATCH": "rec0xLDWNbq2GvWwq",
    "BOILERPLATE-CARRY": "recFvhzvwxWxoHfF9",
    "PRODUCTIVITY-CALIBRATION": "recc1esxiNPMcIa4S",
    "LOSS-CATEGORY": "rec7ZvZ6rXZrVweJ5",
}

REASON_CODE_DOMAINS = list(REASON_CODES.keys())


# Reviewer types — exact singleSelect choice strings on Bid Line Item Overrides.reviewer_type
REVIEWER_TYPES = {
    "trades_internal_rocky": "Trades-Internal-Rocky",
    "trades_internal_liam": "Trades-Internal-Liam",
    "trades_internal_hasibul": "Trades-Internal-Hasibul",
    "commercial_external_robert": "Commercial-External-Robert",
    "commercial_external_civilexperts": "Commercial-External-CivilExperts",
    "commercial_external_other": "Commercial-External-Other",
    "post_submission_outcome": "Post-Submission-Outcome",
}


# Diversity criteria for feedback aggregator — Stage 4 § 3.3
FEEDBACK_TRIGGER = {
    "min_overrides": 3,
    "min_distinct_jobs": 2,
    "min_days_span": 30,
    "min_distinct_reason_domains": 2,
}

COMMON_MISSES_TRIGGER = {
    "min_overrides": 2,
    "min_distinct_jobs": 2,
    "min_days_span": 30,
    "min_distinct_reason_domains": 2,
    "min_total_dollars": 5000,
    "min_median_pct": 10.0,
}
