"""
Unified Full Pipeline Evaluation Script

This script orchestrates the entire end-to-end evaluation pipeline:
1. INFLUENCER: Loads raw data and runs ML predictions .
   -> Output: `influencer/influencer_predictions.csv` (The "Cleaned CSV" - integrated logic)
   -> Output: `influencer/influencer_predictions.json` (Database for matching)

2. BUSINESS: Loads synthetic businesses data and runs ML predictions.
   -> Output: `business/business_predictions.json` (The Queries)

3. RECOMMENDATION: Matches businesses to influencers using the production logic.
   -> Output: `recommendation/recommendation_results.csv` (Final matches)

Usage:
    cd ml_service/evaluation
    python run_full_evaluation.py [--skip-influencer-pred] [--skip-business-pred]
"""

import sys
import argparse
import subprocess
from pathlib import Path
from dotenv import load_dotenv

# Add ml_service root to path
ML_SERVICE_ROOT = str(Path(__file__).resolve().parents[1])
if ML_SERVICE_ROOT not in sys.path:
    sys.path.insert(0, ML_SERVICE_ROOT)

load_dotenv(Path(ML_SERVICE_ROOT) / ".env")

def run_step(step_name, command, cwd=None):
    """Run a shell command and handle errors"""
    print(f"\n{'='*60}")
    print(f"STEP: {step_name}")
    print(f"CMD: {command}")
    print(f"{'='*60}")
    
    try:
        subprocess.check_call(command, shell=True, cwd=cwd)
        print(f"✅ {step_name} completed successfully.")
    except subprocess.CalledProcessError as e:
        print(f"❌ {step_name} failed with error code {e.returncode}.")
        sys.exit(1)

def main():
    parser = argparse.ArgumentParser(description="Run full evaluation pipeline")
    parser.add_argument("--skip-influencer-pred", action="store_true", help="Skip running new influencer predictions (use existing JSON)")
    parser.add_argument("--skip-business-pred", action="store_true", help="Skip running new business predictions (use existing JSON)")
    args = parser.parse_args()

    # Paths
    EVAL_ROOT = Path(__file__).resolve().parent
    INF_DIR = EVAL_ROOT / "influencer"
    BIZ_DIR = EVAL_ROOT / "business"
    REC_DIR = EVAL_ROOT / "recommendation"

    # 1. Influencer Evaluation (Prediction + Enrichment)
    if not args.skip_influencer_pred:
        # Runs the new merged evaluate_influencer.py
        # It internally produces influencer_predictions.csv
        run_step(
            "Influencer predictions",
            f"python evaluate_influencer.py --sample-size 0 --delay 0.5",
            cwd=str(INF_DIR)
        )
    else:
        print("Skipping Influencer Prediction (using existing results).")
        # Ensure the file exists or prompt user
        if not (INF_DIR / "influencer_predictions.csv").exists():
             print(f"Warning: {INF_DIR / 'influencer_predictions.csv'} not found. Next steps may fail.")

    # 2. Business Prediction
    if not args.skip_business_pred:
        run_step(
            "Business Requirements Prediction",
            f"python evaluate_business.py",
            cwd=str(BIZ_DIR)
        )

    # 4. Recommendation Matching
    run_step(
        "Recommendation Matching",
        f"python evaluate_recommendation.py",
        cwd=str(REC_DIR)
    )

    print(f"Final Matches:  {REC_DIR / 'recommendation_results.csv'}")
    
    # 5. Generate Merged Report (The "Cleaned CSV" request)
    run_step(
        "Generate Final Merged Report",
        f"python generate_final_report.py",
        cwd=str(EVAL_ROOT)
    )

    print(f"\n{'='*60}")
    print("🎉 FULL PIPELINE COMPLETE")
    print(f"{'='*60}")
    print(f"Cleaned Data:   {INF_DIR / 'influencer_predictions.csv'}")
    print(f"Business Preds: {BIZ_DIR / 'business_predictions.json'}")
    print(f"Final Matches:  {REC_DIR / 'recommendation_results.csv'}")
    print(f"Final Report:   {EVAL_ROOT / 'final_evaluation_report.csv'}")

if __name__ == "__main__":
    main()
