#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Tests for seaborn integration."""

import tempfile
from pathlib import Path

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pytest

# Skip all tests if seaborn/pandas not installed
pytest.importorskip("seaborn")
pytest.importorskip("pandas")


class TestSeabornRecording:
    """Test seaborn recording functionality."""

    def test_scatterplot_record_and_reproduce(self):
        """Test recording and reproducing a scatterplot."""
        import figrecipe as ps

        with tempfile.TemporaryDirectory() as tmpdir:
            # Create data
            np.random.seed(42)
            df = pd.DataFrame(
                {
                    "x": np.random.randn(50),
                    "y": np.random.randn(50),
                    "category": np.random.choice(["A", "B"], 50),
                }
            )

            # Record
            fig, ax = ps.subplots()
            ps.sns.scatterplot(
                data=df, x="x", y="y", hue="category", ax=ax, id="test_scatter"
            )

            recipe_path = Path(tmpdir) / "scatter.yaml"
            ps.save(fig, recipe_path, validate=False)
            plt.close(fig.fig)

            # Reproduce
            fig2, ax2 = ps.reproduce(recipe_path)

            # Check data was reproduced
            assert len(ax2.collections) > 0  # Has scatter points

            plt.close(fig2.fig)

    def test_lineplot_record_and_reproduce(self):
        """Test recording and reproducing a lineplot."""
        import figrecipe as ps

        with tempfile.TemporaryDirectory() as tmpdir:
            # Create data
            np.random.seed(42)
            df = pd.DataFrame(
                {
                    "x": np.arange(20),
                    "y": np.sin(np.linspace(0, 4 * np.pi, 20)),
                }
            )

            # Record
            fig, ax = ps.subplots()
            ps.sns.lineplot(data=df, x="x", y="y", ax=ax, id="test_line")

            recipe_path = Path(tmpdir) / "line.yaml"
            ps.save(fig, recipe_path, validate=False)
            plt.close(fig.fig)

            # Reproduce
            fig2, ax2 = ps.reproduce(recipe_path)

            # Check line was reproduced
            assert len(ax2.lines) > 0

            plt.close(fig2.fig)

    def test_seaborn_call_in_recipe_info(self):
        """Test that seaborn calls appear in recipe info."""
        import figrecipe as ps

        with tempfile.TemporaryDirectory() as tmpdir:
            df = pd.DataFrame(
                {
                    "x": [1, 2, 3],
                    "y": [4, 5, 6],
                }
            )

            fig, ax = ps.subplots()
            ps.sns.scatterplot(data=df, x="x", y="y", ax=ax, id="my_scatter")

            recipe_path = Path(tmpdir) / "test.yaml"
            ps.save(fig, recipe_path, validate=False)
            plt.close(fig.fig)

            # Check info
            info = ps.info(recipe_path)
            call_ids = [c["id"] for c in info["calls"]]
            call_funcs = [c["function"] for c in info["calls"]]

            assert "my_scatter" in call_ids
            assert "sns.scatterplot" in call_funcs

    def test_seaborn_with_hue(self):
        """Test seaborn plots with hue parameter."""
        import figrecipe as ps

        with tempfile.TemporaryDirectory() as tmpdir:
            np.random.seed(42)
            df = pd.DataFrame(
                {
                    "x": np.random.randn(30),
                    "y": np.random.randn(30),
                    "group": np.repeat(["A", "B", "C"], 10),
                }
            )

            fig, ax = ps.subplots()
            ps.sns.scatterplot(data=df, x="x", y="y", hue="group", ax=ax)

            recipe_path = Path(tmpdir) / "hue.yaml"
            ps.save(fig, recipe_path, validate=False)
            plt.close(fig.fig)

            # Reproduce and check
            fig2, ax2 = ps.reproduce(recipe_path)
            assert len(ax2.collections) > 0
            plt.close(fig2.fig)


class TestSeabornDataSerialization:
    """Test DataFrame column serialization for seaborn."""

    def test_csv_data_created(self):
        """Test that CSV files are created for large DataFrame columns."""
        import figrecipe as ps

        with tempfile.TemporaryDirectory() as tmpdir:
            # Create large data
            np.random.seed(42)
            n = 200  # > INLINE_THRESHOLD of 100
            df = pd.DataFrame(
                {
                    "x": np.random.randn(n),
                    "y": np.random.randn(n),
                }
            )

            fig, ax = ps.subplots()
            ps.sns.scatterplot(data=df, x="x", y="y", ax=ax)

            recipe_path = Path(tmpdir) / "large.yaml"
            ps.save(fig, recipe_path, validate=False)
            plt.close(fig.fig)

            # Check data files created
            data_dir = Path(tmpdir) / "large_data"
            assert data_dir.exists()
            csv_files = list(data_dir.glob("*.csv"))
            assert len(csv_files) > 0

    def test_small_data_creates_csv(self):
        """Test that small data is stored in CSV files (consistent CSV storage)."""
        import figrecipe as ps

        with tempfile.TemporaryDirectory() as tmpdir:
            # Small data - now always goes to CSV regardless of size
            df = pd.DataFrame(
                {
                    "x": [1, 2, 3, 4, 5],
                    "y": [2, 4, 6, 8, 10],
                }
            )

            fig, ax = ps.subplots()
            ps.sns.scatterplot(data=df, x="x", y="y", ax=ax)

            recipe_path = Path(tmpdir) / "small.yaml"
            ps.save(fig, recipe_path, validate=False)
            plt.close(fig.fig)

            # Data directory should be created (INLINE_THRESHOLD=0)
            data_dir = Path(tmpdir) / "small_data"
            assert data_dir.exists()
            csv_files = list(data_dir.glob("*.csv"))
            assert len(csv_files) > 0
