# revenue_tracker.py
import json
import time
import os
import redis
from datetime import datetime, timedelta
from typing import Dict, Any
from collections import defaultdict

class RevenueTracker:
    """
    Tracks revenue, calculates ROI, and generates reports.
    """
    def __init__(self):
        self.namespace = "genesis:revenue"
        self.redis_client = None
        
        # Load Redis config
        config_path = r"E:\genesis-system\genesis_config.json"
        if os.path.exists(config_path):
            with open(config_path, 'r') as f:
                config = json.load(f).get("redis")
                if config:
                    self.redis_client = redis.Redis(
                        host=config["host"],
                        port=config["port"],
                        password=config["password"],
                        ssl=config.get("ssl", False),
                        decode_responses=True
                    )
        self.roi_data = defaultdict(lambda: {"revenue": 0.0, "cost": 0.0})
        self.revenue_targets = {} # task_name: target_amount
        self.alerts = []

    def log_revenue(self, amount: float, task_name: str, details: Dict[str, Any] = None):
        """Log a revenue-generating event."""
        if not self.redis_client: return
        
        now = datetime.now()
        revenue_entry = {
            "timestamp": now.isoformat(),
            "amount": amount,
            "task_name": task_name,
            "details": details or {}
        }
        self.redis_client.lpush(f"{self.namespace}:revenue_logs", json.dumps(revenue_entry))
        self.redis_client.ltrim(f"{self.namespace}:revenue_logs", 0, 1000)

        # Update ROI data
        self.roi_data[task_name]["revenue"] += amount
        self._check_revenue_target(task_name, self.roi_data[task_name]["revenue"])

    def attribute_cost(self, amount: float, task_name: str):
        """Attribute a cost to a specific task."""
        if not self.redis_client: return
        self.roi_data[task_name]["cost"] += amount

    def calculate_roi(self, task_name: str) -> float:
        """Calculate ROI for a given task."""
        revenue = self.roi_data[task_name]["revenue"]
        cost = self.roi_data[task_name]["cost"]
        if cost == 0:
            return float('inf') if revenue > 0 else 0.0  # Avoid division by zero
        return (revenue - cost) / cost

    def get_highest_value_actions(self, top_n: int = 5) -> list:
        """Identify the highest-value actions based on ROI."""
        roi_results = {task: self.calculate_roi(task) for task in self.roi_data}
        sorted_actions = sorted(roi_results.items(), key=lambda item: item[1], reverse=True)
        return sorted_actions[:top_n]

    def forecast_revenue(self, planned_activities: list) -> float:
        """Predict revenue from planned activities (basic implementation)."""
        # This is a placeholder.  A real implementation would use a more sophisticated model.
        # For now, we just assume a fixed return per activity.
        estimated_revenue_per_activity = 5.0
        return len(planned_activities) * estimated_revenue_per_activity

    def generate_revenue_report(self, start_date: datetime, end_date: datetime) -> list:
        """Generate a revenue report for a given period."""
        if not self.redis_client: return []
        
        revenue_logs = []
        for log_json in self.redis_client.lrange(f"{self.namespace}:revenue_logs", 0, -1):
            log_entry = json.loads(log_json)
            log_time = datetime.fromisoformat(log_entry["timestamp"])
            if start_date <= log_time <= end_date:
                revenue_logs.append(log_entry)
        return revenue_logs

    def set_revenue_target(self, task_name: str, target_amount: float):
        """Set a revenue target for a specific task."""
        self.revenue_targets[task_name] = target_amount

    def _check_revenue_target(self, task_name: str, current_revenue: float):
        """Check if a revenue target has been reached."""
        if task_name in self.revenue_targets and current_revenue >= self.revenue_targets[task_name]:
            self.alerts.append(f"Revenue target reached for {task_name}: {current_revenue}")
            del self.revenue_targets[task_name] # Remove target after reaching it.

    def get_alerts(self) -> list:
        """Return any generated alerts."""
        return self.alerts

    def clear_alerts(self):
        """Clear the alerts list."""
        self.alerts = []


if __name__ == "__main__":
    rt = RevenueTracker()

    # Example Usage
    rt.log_revenue(amount=25.0, task_name="Lead Generation", details={"source": "Website"})
    rt.log_revenue(amount=50.0, task_name="Sales Conversion", details={"agent": "Bob"})
    rt.attribute_cost(amount=10.0, task_name="Lead Generation")
    rt.attribute_cost(amount=15.0, task_name="Sales Conversion")

    print(f"ROI for Lead Generation: {rt.calculate_roi('Lead Generation')}")
    print(f"ROI for Sales Conversion: {rt.calculate_roi('Sales Conversion')}")

    highest_value = rt.get_highest_value_actions(top_n=2)
    print(f"Highest Value Actions: {highest_value}")

    planned_activities = ["New Ad Campaign", "Email Marketing"]
    forecasted_revenue = rt.forecast_revenue(planned_activities)
    print(f"Forecasted Revenue: {forecasted_revenue}")

    start_date = datetime.now() - timedelta(days=1)
    end_date = datetime.now()
    report = rt.generate_revenue_report(start_date, end_date)
    print(f"Revenue Report: {report}")

    rt.set_revenue_target("Lead Generation", 50.0)
    rt.log_revenue(amount=30.0, task_name="Lead Generation")
    alerts = rt.get_alerts()
    print(f"Alerts: {alerts}")

    rt.clear_alerts()
    print(f"Alerts after clearing: {rt.get_alerts()}")