
import unittest
import pandas as pd
import numpy as np
import os
from autoscore import AutoScore, BinningProcess

class TestAutoScore(unittest.TestCase):
    
    @classmethod
    def setUpClass(cls):
        # Create synthetic data
        np.random.seed(42)
        n = 500
        cls.df = pd.DataFrame({
            'age': np.random.randint(18, 70, n),
            'income': np.random.normal(50000, 15000, n),
            'target': np.random.binomial(1, 0.3, n),
            'category': np.random.choice(['A', 'B', 'C'], n)
        })
        
    def test_binning_process(self):
        binning = BinningProcess(max_bins=5)
        binning.fit(self.df[['age', 'income', 'category']], self.df['target'])
        
        self.assertIn('age', binning.rules)
        self.assertIn('income', binning.rules)
        self.assertIn('category', binning.rules)
        
        # Check transformation
        X_woe = binning.transform(self.df[['age', 'income', 'category']])
        self.assertEqual(X_woe.shape, (500, 3))
        self.assertFalse(X_woe.isnull().any().any())

    def test_full_pipeline(self):
        score = AutoScore(random_state=42)
        score.fit(
            X=self.df.drop(columns=['target']),
            y=self.df['target'],
            max_bins=5,
            selection_method='stepwise'
        )
        
        self.assertIsNotNone(score.scorecard_df)
        self.assertIsNotNone(score.model_metrics)
        self.assertIn('train', score.model_metrics)
        
        # Test Prediction
        probs = score.predict_proba(self.df.drop(columns=['target']))
        self.assertEqual(len(probs), 500)
        
    def test_reporting(self):
        score = AutoScore(random_state=42)
        score.fit(self.df.drop(columns=['target']), self.df['target'])
        
        report_file = 'test_report.xlsx'
        score.create_report(report_file)
        self.assertTrue(os.path.exists(report_file))
        os.remove(report_file)

if __name__ == '__main__':
    unittest.main()
