import tempfile

import numpy as np
import pandas as pd
import pytest

from wise_pizza_mcp.store import clear_all


@pytest.fixture(autouse=True)
def clean_store():
    """Clear the dataset store before and after each test."""
    clear_all()
    yield
    clear_all()


def _make_sample_df(seed: int = 42, n_per_group: int = 5) -> pd.DataFrame:
    """Create a small DataFrame with 3 dims, totals, and sizes."""
    rng = np.random.RandomState(seed)
    regions = ["US", "EU", "APAC"]
    products = ["A", "B", "C"]
    channels = ["web", "app"]

    rows = []
    for region in regions:
        for product in products:
            for channel in channels:
                for _ in range(n_per_group):
                    base_total = rng.lognormal(3, 1)
                    base_size = rng.randint(10, 200)
                    rows.append(
                        {
                            "region": region,
                            "product": product,
                            "channel": channel,
                            "total": base_total,
                            "size": base_size,
                        }
                    )

    df = pd.DataFrame(rows)
    # Add a spike so there is something to find
    mask = (df["region"] == "US") & (df["product"] == "A")
    df.loc[mask, "total"] += 500
    return df


@pytest.fixture
def sample_df() -> pd.DataFrame:
    return _make_sample_df(seed=42)


@pytest.fixture
def sample_df_pair():
    """Two DataFrames for changes analysis with a meaningful difference."""
    df1 = _make_sample_df(seed=42)
    df2 = _make_sample_df(seed=123)
    # Make a clear change in one segment
    mask = (df2["region"] == "EU") & (df2["product"] == "B")
    df2.loc[mask, "total"] += 300
    return df1, df2


@pytest.fixture
def sample_ts_df() -> pd.DataFrame:
    """DataFrame with time column for timeseries analysis."""
    rng = np.random.RandomState(42)
    regions = ["US", "EU", "APAC"]
    products = ["A", "B"]
    months = pd.date_range("2024-01-01", periods=12, freq="MS")

    rows = []
    for month in months:
        for region in regions:
            for product in products:
                base_total = rng.lognormal(3, 1)
                base_size = rng.randint(10, 200)
                rows.append(
                    {
                        "region": region,
                        "product": product,
                        "month": str(month.date()),
                        "total": base_total,
                        "size": base_size,
                    }
                )

    df = pd.DataFrame(rows)
    # Add a trend to one segment
    for i, month in enumerate(months):
        mask = (df["month"] == str(month.date())) & (df["region"] == "US")
        df.loc[mask, "total"] += i * 50
    return df


@pytest.fixture
def tmp_csv(sample_df) -> str:
    """Write sample_df to a temp CSV and return the path."""
    with tempfile.NamedTemporaryFile(suffix=".csv", delete=False, mode="w") as f:
        sample_df.to_csv(f, index=False)
        return f.name


@pytest.fixture
def tmp_csv_pair(sample_df_pair):
    """Write both DataFrames to temp CSVs and return paths."""
    paths = []
    for df in sample_df_pair:
        with tempfile.NamedTemporaryFile(suffix=".csv", delete=False, mode="w") as f:
            df.to_csv(f, index=False)
            paths.append(f.name)
    return paths


@pytest.fixture
def tmp_ts_csv(sample_ts_df) -> str:
    """Write timeseries DataFrame to a temp CSV and return the path."""
    with tempfile.NamedTemporaryFile(suffix=".csv", delete=False, mode="w") as f:
        sample_ts_df.to_csv(f, index=False)
        return f.name
