import pandas as pd
import numpy as np
from sklearn.metrics import classification_report, confusion_matrix

class PredictionBuilder:
    """
    Makes final predictions based on the engineered 'fraud_score' feature.
    This class applies a simple probability threshold to classify transactions.
    """
    def predict(self, engineered_features, threshold=0.5):
        """
        Predicts anomalies based on the 'fraud_score'.

        Args:
            engineered_features (pd.DataFrame): DataFrame containing the 'fraud_score'.
            threshold (float): The probability cutoff for classifying as fraud.
                               Transactions with a fraud_score >= threshold are flagged.

        Returns:
            np.array: An array of predictions (-1 for anomaly, 1 for normal).
        """
        if 'fraud_score' not in engineered_features.columns:
            raise ValueError("Engineered features must contain a 'fraud_score' column.")

        # Predict as fraud (-1) if the score is above the threshold, otherwise normal (1).
        predictions = np.where(engineered_features['fraud_score'] >= threshold, -1, 1)
        return predictions

    def evaluate(self, predictions, true_labels):
        """
        Compares final model predictions to true labels and prints a classification report.
        """
        # Map model output (-1 for anomaly, 1 for normal) to the label format (1 for anomaly, 0 for normal).
        mapped_predictions = pd.Series(predictions).map({1: 0, -1: 1})

        print("\n--- Evaluation ---")
        print("Comparing final predictions to true labels...")
        
        print("\nConfusion Matrix:")
        cm = confusion_matrix(true_labels, mapped_predictions)
        print(pd.DataFrame(cm,
                           index=['True Normal', 'True Fraud'],
                           columns=['Predicted Normal', 'Predicted Fraud']))
        
        print("\nClassification Report:")
        print(classification_report(true_labels, mapped_predictions, target_names=['Normal (0)', 'Fraud (1)']))
