import logging

# Configure basic logging for visibility within the AIVA system
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class EpistemicHumilityEngine:
    """
    The Epistemic Humility Engine prevents overconfidence in AIVA by
    enforcing confidence ceilings, enabling "I don't know" responses,
    and triggering escalations when necessary.
    """

    def __init__(self,
                 confidence_ceiling: float = 0.95,
                 idk_threshold: float = 0.40,
                 escalation_low_confidence_threshold: float = 0.20,
                 escalation_cap_difference_threshold: float = 0.05,
                 knowledge_gap_keywords: list[str] = None):
        """
        Initializes the Humility Engine with its operational parameters.

        Args:
            confidence_ceiling (float): The maximum confidence AIVA is allowed to express.
                                        Any raw confidence above this will be capped.
            idk_threshold (float): If raw confidence falls below this, AIVA is prompted
                                   to respond with "I don't know" or similar.
            escalation_low_confidence_threshold (float): If raw confidence falls below this
                                                         critical threshold, an escalation is triggered.
            escalation_cap_difference_threshold (float): If the confidence ceiling caps the raw
                                                         confidence by more than this difference,
                                                         an escalation is triggered (potential overconfidence).
            knowledge_gap_keywords (list[str]): Keywords in AIVA's internal thought process
                                                that explicitly signal a knowledge gap,
                                                triggering "I don't know" and escalation.
        """
        if not (0.0 <= confidence_ceiling <= 1.0):
            raise ValueError("confidence_ceiling must be between 0.0 and 1.0")
        if not (0.0 <= idk_threshold <= 1.0):
            raise ValueError("idk_threshold must be between 0.0 and 1.0")
        if not (0.0 <= escalation_low_confidence_threshold <= 1.0):
            raise ValueError("escalation_low_confidence_threshold must be between 0.0 and 1.0")
        if not (0.0 <= escalation_cap_difference_threshold <= 1.0):
            raise ValueError("escalation_cap_difference_threshold must be between 0.0 and 1.0")

        self.confidence_ceiling = confidence_ceiling
        self.idk_threshold = idk_threshold
        self.escalation_low_confidence_threshold = escalation_low_confidence_threshold
        self.escalation_cap_difference_threshold = escalation_cap_difference_threshold
        self.knowledge_gap_keywords = [k.lower() for k in (knowledge_gap_keywords or [])]

        logger.info(f"Epistemic Humility Engine initialized with: "
                    f"Ceiling={self.confidence_ceiling}, IDK_Threshold={self.idk_threshold}, "
                    f"Low_Conf_Esc_Threshold={self.escalation_low_confidence_threshold}, "
                    f"Cap_Diff_Esc_Threshold={self.escalation_cap_difference_threshold}, "
                    f"Knowledge_Keywords={self.knowledge_gap_keywords}")

    def apply_humility_check(self, raw_confidence: float, internal_thought_process: str = "") -> dict:
        """
        Applies humility checks to AIVA's raw confidence and internal state.

        Args:
            raw_confidence (float): AIVA's internally calculated raw confidence for a given task/statement.
            internal_thought_process (str): A string representation of AIVA's internal reasoning,
                                            used to detect explicit knowledge gaps.

        Returns:
            dict: A dictionary containing the adjusted confidence and flags for actions.
                  - 'adjusted_confidence': The confidence after applying the ceiling.
                  - 'should_say_idk': Boolean, true if AIVA should express uncertainty.
                  - 'should_escalate': Boolean, true if an escalation process should be triggered.
                  - 'humility_reason': String explaining why certain flags were set.
        """
        adjusted_confidence = raw_confidence
        should_say_idk = False
        should_escalate = False
        humility_reason = []

        # 1. Enforce Confidence Ceiling
        if raw_confidence > self.confidence_ceiling:
            adjusted_confidence = self.confidence_ceiling
            cap_difference = raw_confidence - adjusted_confidence
            humility_reason.append(f"Confidence capped from {raw_confidence:.2f} to {adjusted_confidence:.2f} (ceiling {self.confidence_ceiling:.2f}).")

            # Check for escalation due to significant overconfidence cap
            if cap_difference > self.escalation_cap_difference_threshold:
                should_escalate = True
                humility_reason.append(f"Escalation triggered: Significant confidence cap difference ({cap_difference:.2f} > {self.escalation_cap_difference_threshold:.2f}).")
                logger.warning(f"AIVA's confidence capped significantly. Raw: {raw_confidence:.2f}, Adjusted: {adjusted_confidence:.2f}. Escalating.")
        else:
            adjusted_confidence = raw_confidence # Ensure it's explicitly set if not capped

        # 2. Check for "I don't know" conditions
        if raw_confidence < self.idk_threshold:
            should_say_idk = True
            humility_reason.append(f"Triggered 'I don't know': Raw confidence ({raw_confidence:.2f}) is below threshold ({self.idk_threshold:.2f}).")
            logger.info(f"AIVA's confidence {raw_confidence:.2f} is below 'I don't know' threshold. Suggesting 'I don't know'.")

        # 3. Check for explicit knowledge gaps in internal thought process
        if internal_thought_process:
            lower_internal_thought = internal_thought_process.lower()
            for keyword in self.knowledge_gap_keywords:
                if keyword in lower_internal_thought:
                    should_say_idk = True
                    should_escalate = True # Explicit knowledge gap definitely warrants escalation
                    humility_reason.append(f"Triggered 'I don't know' and escalation: Detected knowledge gap keyword '{keyword}' in internal thought process.")
                    logger.warning(f"AIVA's internal thought process indicates a knowledge gap ('{keyword}'). Triggering 'I don't know' and escalation.")
                    break # Only need one keyword to trigger

        # 4. Check for escalation due to critically low confidence
        if raw_confidence < self.escalation_low_confidence_threshold:
            should_escalate = True
            humility_reason.append(f"Escalation triggered: Raw confidence ({raw_confidence:.2f}) is below critical low confidence threshold ({self.escalation_low_confidence_threshold:.2f}).")
            logger.critical(f"AIVA's confidence {raw_confidence:.2f} is critically low. Escalating.")

        return {
            "adjusted_confidence": max(0.0, adjusted_confidence), # Ensure confidence is not negative
            "should_say_idk": should_say_idk,
            "should_escalate": should_escalate,
            "humility_reason": "; ".join(humility_reason) if humility_reason else "No specific humility checks triggered."
        }