"""Tests for data loading and basic data integrity."""
import pytest
import pandas as pd
import numpy as np


class TestLoadData:

    def test_returns_three_dataframes(self, raw_data):
        df_surf, df_rate, df_return = raw_data
        assert isinstance(df_surf, pd.DataFrame)
        assert isinstance(df_rate, pd.DataFrame)
        assert isinstance(df_return, pd.DataFrame)

    def test_surf_shape(self, raw_data):
        df_surf, _, _ = raw_data
        assert df_surf.shape == (67500, 9)

    def test_rate_shape(self, raw_data):
        _, df_rate, _ = raw_data
        assert df_rate.shape == (5511, 3)

    def test_return_shape(self, raw_data):
        _, _, df_return = raw_data
        assert df_return.shape == (501, 7)

    def test_surf_columns(self, raw_data):
        df_surf, _, _ = raw_data
        expected = {'id', 'date', 'k', 'impl_volatility', 'delta', 'f', 's', 'days', 'mnes'}
        assert set(df_surf.columns) == expected

    def test_rate_columns(self, raw_data):
        _, df_rate, _ = raw_data
        assert set(df_rate.columns) == {'date', 'days', 'rate'}

    def test_return_columns(self, raw_data):
        _, _, df_return = raw_data
        expected = {'12490', '14541', '14593', '18542', '93436', 'mktrf', 'rf'}
        assert set(df_return.columns) == expected

    def test_surf_dates_are_datetime(self, raw_data):
        df_surf, _, _ = raw_data
        assert pd.api.types.is_datetime64_any_dtype(df_surf['date'])

    def test_rate_dates_are_datetime(self, raw_data):
        _, df_rate, _ = raw_data
        assert pd.api.types.is_datetime64_any_dtype(df_rate['date'])

    def test_return_index_is_datetime(self, raw_data):
        _, _, df_return = raw_data
        assert isinstance(df_return.index, pd.DatetimeIndex)

    def test_rate_values_are_decimals(self, raw_data):
        """Rates should be in decimal form (divided by 100 on load)."""
        _, df_rate, _ = raw_data
        assert df_rate['rate'].max() < 0.1  # max ~5-6% in decimal

    def test_surf_delta_divided_by_100(self, raw_data):
        """Delta should be in [-1, 1] range after load_data divides by 100."""
        df_surf, _, _ = raw_data
        assert df_surf['delta'].min() >= -1.0
        assert df_surf['delta'].max() <= 1.0

    def test_surf_no_nans_in_key_columns(self, raw_data):
        df_surf, _, _ = raw_data
        for col in ['id', 'date', 'days', 'mnes', 'impl_volatility']:
            assert df_surf[col].notna().all(), f"NaN found in {col}"
