"""Policy-derived constants and deterministic workflow helpers."""

from datetime import datetime, timedelta, timezone


COMPANY_NAME = "Al Wattan Medical Group"
POLICY_REFERENCE = "SMC-GP-LD-017"
FORM_REFERENCE = "Form-LD-017-A"

PERSON_TYPES = ["Patient", "Staff", "Family/Visitor", "Other"]
REPORT_TYPES = ["Incident", "Reportable Event", "Sentinel Event", "Near Miss", "Unsafe Condition"]
INJURY_TYPES = ["Physical", "Psychological"]
HARM_LEVELS = ["Insignificant", "Minor", "Moderate", "Major", "Catastrophic"]
LIKELIHOODS = ["Rare", "Unlikely", "Possible", "Likely", "Almost Certain"]

CLASSIFICATIONS = {
    "Clinical Practice / Procedure": [
        "Documentation", "Missing Files", "Medical records unavailable", "Policy not available",
        "Confidentiality", "Procedure/s not followed", "Other",
    ],
    "Medication": [
        "Wrong drug", "Wrong time", "Wrong route", "Wrong dose", "Wrong patient",
        "I.V. not given", "I.V. infiltration", "Allergic reaction", "Prescribing error",
        "Transcribing error", "Dispensing error", "Administration error", "Monitoring error", "Other",
    ],
    "Patient / Family / Visitor": [
        "Dissatisfaction", "Violence", "Needle stick/prick", "Verbal aggression", "Fall", "HAI", "Other",
    ],
    "Staff / Employee": [
        "Infection control issue", "Infectious substance exposure", "Needle stick/prick", "Fall",
        "Misconduct/behavior", "Policy/procedure issue", "Other",
    ],
    "Equipment / Supplies": [
        "Improper handling", "Not available", "Missing/damaged", "Failure/malfunction",
        "Wrong equipment", "Improper storage", "Other",
    ],
    "Safety": ["Injury", "Electric shock", "Physical assault", "Structural", "Other"],
    "Fire / Security": ["Fire/smoke incident", "Property missing", "Unauthorized entry", "False alarm", "Other"],
    "Patient Behavior": ["Assault", "Verbal aggression", "Violent behavior", "Sexual harassment", "Other"],
    "Laboratory": ["Specimen identification", "Wrong sample entered", "Late verification", "Wrong result", "Other"],
    "Occupational / Environment of Care": [
        "Disability", "Exposure to hazards", "Unconsciousness", "Work-related illness", "Other",
    ],
}

CONTRIBUTORY_FACTORS = [
    "Patient / Family Factors",
    "Task and Technology Factors",
    "Individual (Staff) Factors",
    "Team / Communication Factors",
    "Work Environmental Factors",
    "Organizational & Management Factors",
    "Institutional Context Factors",
]

MEDICATION_HARM = {
    "A": "Unsafe condition with capacity to cause or facilitate an error.",
    "B": "An error occurred but did not reach the patient.",
    "C": "An error reached the patient but caused no harm.",
    "D": "An error reached the patient and required monitoring or intervention to preclude harm.",
    "E": "Temporary harm requiring a simple intervention.",
    "F": "Temporary harm requiring initial or prolonged hospitalization.",
    "G": "Permanent patient harm, significant intervention, prolonged stay, or extensive follow-up.",
    "H": "Life-threatening injury or multiple permanent serious harms requiring life-sustaining intervention.",
    "I": "The error may have contributed to or resulted in the patient's death.",
}

SENTINEL_EVENTS = [
    "Wrong patient", "Major medication error leading to death or major morbidity", "Wrong-site surgery",
    "Maternal death", "Hemolytic blood transfusion reaction", "Infant discharged to wrong family",
    "Suicide in an inpatient unit", "Infant abduction", "Retained instrument or sponge", "Unexpected death",
    "Intravascular gas embolism", "Unexpected loss of limb or function",
    "Medical equipment/device error leading to death or permanent harm",
]

STATUS_LABELS = {
    "DRAFT": "Draft",
    "SUBMITTED": "Awaiting Manager Review",
    "QPS_REVIEW": "QPS Review & Analysis",
    "RCA_REQUIRED": "Sentinel / RCA Investigation",
    "ACTION_REQUIRED": "Department Action Required",
    "QPS_FINAL": "QPS Final Review",
    "CLOSED": "Closed",
}

RISK_COLORS = {"Low": "gray", "Moderate": "green", "High": "yellow", "Extreme": "red"}
RISK_INVESTIGATION_DAYS = {"Low": 5, "Moderate": 10, "High": 14, "Extreme": 14}


def utcnow():
    """Naive UTC for cross-database DateTime compatibility without deprecated utcnow()."""
    return datetime.now(timezone.utc).replace(tzinfo=None)


def risk_score(consequence, likelihood):
    """Return a conventional 5x5 score using policy harm and likelihood scales."""
    try:
        return (HARM_LEVELS.index(consequence) + 1) * (LIKELIHOODS.index(likelihood) + 1)
    except (ValueError, AttributeError):
        return None


def risk_level(score):
    """Use Appendix D's complete bands (resolves gaps printed on the legacy form)."""
    if score is None:
        return None
    if score <= 3:
        return "Low"
    if score <= 7:
        return "Moderate"
    if score <= 12:
        return "High"
    return "Extreme"


def add_working_days(value, days):
    current = value
    added = 0
    while added < days:
        current += timedelta(days=1)
        if current.weekday() < 5:
            added += 1
    return current


def due_date_for_risk(level, start=None):
    start = start or utcnow()
    return add_working_days(start, RISK_INVESTIGATION_DAYS[level]) if level in RISK_INVESTIGATION_DAYS else None


def action_plan_due(start=None):
    return add_working_days(start or utcnow(), 30)
