import pytest
from sklearn.base import BaseEstimator, RegressorMixin

from snaplab.evaluation.base import BaseEvaluator


# -----------------------------------
# Dummy Evaluator for testing
# -----------------------------------
class DummyEvaluator(BaseEvaluator):
    def evaluate(self):
        return {"ok": True}


# -----------------------------------
# Dummy sklearn-compatible model
# -----------------------------------
class DummyModel(BaseEstimator, RegressorMixin):
    def predict(self, X):
        return X


# -----------------------------------
# Tests
# -----------------------------------

def test_base_initialization_valid():
    model = DummyModel()
    X = [1, 2, 3]
    y = [1, 2, 3]

    evaluator = DummyEvaluator(model, X, y)

    assert evaluator.model is model
    assert evaluator.X_test == X
    assert evaluator.y_test == y


def test_invalid_model():
    with pytest.raises(TypeError):
        DummyEvaluator(object(), [1], [1])


def test_length_mismatch():
    model = DummyModel()
    with pytest.raises(ValueError):
        DummyEvaluator(model, [1, 2], [1])


def test_none_inputs():
    model = DummyModel()
    with pytest.raises(ValueError):
        DummyEvaluator(model, None, None)


# -----------------------------------
# Summary tests
# -----------------------------------
from snaplab.evaluation.result import EvaluationResult


def test_summary_classification():
    result = EvaluationResult(
        metrics={
            "accuracy": 0.95,
            "precision": 0.94,
            "recall": 0.93,
            "f1_score": 0.94,
        },
        model_type="classification",
    )
    summary = result.summary()
    assert "Classification:" in summary
    assert "accuracy=0.950" in summary


def test_summary_regression():
    result = EvaluationResult(
        metrics={
            "r2_score": 0.88,
            "rmse": 2.34,
            "mae": 1.23,
        },
        model_type="regression",
    )
    summary = result.summary()
    assert "Regression:" in summary
    assert "r2_score=0.880" in summary


def test_summary_generic():
    result = EvaluationResult(
        metrics={"metric1": 0.5, "metric2": 0.6, "metric3": 0.7},
        model_type="unknown",
    )
    summary = result.summary()
    assert "Evaluation:" in summary
    assert "metric1=0.500" in summary


def test_summary_empty():
    result = EvaluationResult(metrics={}, model_type="")
    assert result.summary() == "No metrics available"