"""Tests for eapctf.ctf.pipeline — end-to-end dry run integration."""

from __future__ import annotations

from pathlib import Path

import pandas as pd
import pytest

from eapctf.ctf.pipeline import CTFReport, pipeline


class TestPipeline:
    def test_dry_run_returns_report(
        self,
        minimal_model_script: Path,
        minimal_ctf_data_dir: Path,
        tmp_path: Path,
    ) -> None:
        report = pipeline(
            script_path=minimal_model_script,
            data_dir=minimal_ctf_data_dir,
            submitter={"first_name": "Jane", "last_name": "Doe", "email": "jane@test.com"},
            model_name="TestModel",
            output_dir=tmp_path / "bundle",
            submit=False,
        )
        assert isinstance(report, CTFReport)

    def test_report_has_validation(
        self,
        minimal_model_script: Path,
        minimal_ctf_data_dir: Path,
        tmp_path: Path,
    ) -> None:
        report = pipeline(
            script_path=minimal_model_script,
            data_dir=minimal_ctf_data_dir,
            submitter={"first_name": "A", "last_name": "B", "email": "a@b.com"},
            model_name="X",
            output_dir=tmp_path / "bundle",
        )
        assert report.validation is not None
        assert len(report.validation.checks) > 0

    def test_report_has_metrics(
        self,
        minimal_model_script: Path,
        minimal_ctf_data_dir: Path,
        tmp_path: Path,
    ) -> None:
        report = pipeline(
            script_path=minimal_model_script,
            data_dir=minimal_ctf_data_dir,
            submitter={"first_name": "A", "last_name": "B", "email": "a@b.com"},
            model_name="X",
            output_dir=tmp_path / "bundle",
        )
        # metrics requires daily_ret — should be loaded from data_dir
        assert report.metrics is not None

    def test_report_has_bundle(
        self,
        minimal_model_script: Path,
        minimal_ctf_data_dir: Path,
        tmp_path: Path,
    ) -> None:
        report = pipeline(
            script_path=minimal_model_script,
            data_dir=minimal_ctf_data_dir,
            submitter={"first_name": "A", "last_name": "B", "email": "a@b.com"},
            model_name="X",
            output_dir=tmp_path / "bundle",
        )
        assert report.bundle.script_path.exists()
        assert report.bundle.weights_path.exists()

    def test_no_submission_on_dry_run(
        self,
        minimal_model_script: Path,
        minimal_ctf_data_dir: Path,
        tmp_path: Path,
    ) -> None:
        report = pipeline(
            script_path=minimal_model_script,
            data_dir=minimal_ctf_data_dir,
            submitter={"first_name": "A", "last_name": "B", "email": "a@b.com"},
            model_name="X",
            output_dir=tmp_path / "bundle",
            submit=False,
        )
        assert report.submission is None

    def test_precomputed_weights_skips_run_local(
        self,
        minimal_model_script: Path,
        minimal_ctf_data_dir: Path,
        ctf_weights_df: pd.DataFrame,
        ctf_daily_ret_df: pd.DataFrame,
        tmp_path: Path,
    ) -> None:
        report = pipeline(
            script_path=minimal_model_script,
            submitter={"first_name": "A", "last_name": "B", "email": "a@b.com"},
            model_name="X",
            weights_df=ctf_weights_df,
            daily_ret_df=ctf_daily_ret_df,
            output_dir=tmp_path / "bundle",
        )
        assert isinstance(report, CTFReport)
        assert report.bundle.weights_path.exists()

    def test_missing_data_dir_and_weights_raises(
        self, minimal_model_script: Path, tmp_path: Path
    ) -> None:
        with pytest.raises(ValueError, match="data_dir.*weights_df|weights_df.*data_dir"):
            pipeline(
                script_path=minimal_model_script,
                submitter={"first_name": "A", "last_name": "B", "email": "a@b.com"},
                model_name="X",
                output_dir=tmp_path / "bundle",
            )

    def test_submit_true_without_submitter_raises(
        self,
        minimal_model_script: Path,
        minimal_ctf_data_dir: Path,
        tmp_path: Path,
    ) -> None:
        with pytest.raises(ValueError, match="submitter"):
            pipeline(
                script_path=minimal_model_script,
                data_dir=minimal_ctf_data_dir,
                submitter=None,
                model_name="X",
                output_dir=tmp_path / "bundle",
                submit=True,
            )

    def test_str_output(
        self,
        minimal_model_script: Path,
        minimal_ctf_data_dir: Path,
        tmp_path: Path,
    ) -> None:
        report = pipeline(
            script_path=minimal_model_script,
            data_dir=minimal_ctf_data_dir,
            submitter={"first_name": "A", "last_name": "B", "email": "a@b.com"},
            model_name="X",
            output_dir=tmp_path / "bundle",
        )
        text = str(report)
        assert "CTF PIPELINE REPORT" in text
        assert "Validation" in text
