"""
Test script for PriceExport functionality.

This script tests the Phase 4 implementation of the PriceExport module
without requiring actual Oracle or API connections.
"""

import sys
import os
import requests
from unittest.mock import Mock, patch, MagicMock
from datetime import datetime, timedelta

# Add the project root to Python path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from features.price_export import PriceExport, main
from core.config import get_config


def test_price_export_initialization():
    """Test PriceExport class initialization."""
    print("Testing PriceExport initialization...")

    # Mock the dependencies
    with patch("features.price_export.create_oracle_wrapper") as mock_oracle:
        mock_oracle.return_value = Mock()

        price_export = PriceExport()

        # Check that configuration is loaded
        assert price_export.api_url is not None
        assert price_export.token is not None
        assert price_export.months > 0

        # Check statistics initialization
        assert price_export.stats["total_days"] == 0
        assert price_export.stats["successful_days"] == 0
        assert price_export.stats["failed_days"] == 0

        print("✓ PriceExport initialization test passed")


def test_oracle_query_format():
    """Test that Oracle query uses exact format specified in PRD."""
    print("Testing Oracle query format...")

    with patch("features.price_export.create_oracle_wrapper") as mock_oracle:
        mock_wrapper = Mock()
        mock_oracle.return_value = mock_wrapper
        mock_wrapper.execute_scalar.return_value = '{"test": "data"}'

        price_export = PriceExport()
        result = price_export.fetch_json_from_oracle("21.10.2025")

        # Verify the exact query format
        expected_query = "select m_hlpricejson('21.10.2025') from dual"
        mock_wrapper.execute_scalar.assert_called_once_with(expected_query)

        print("✓ Oracle query format test passed")


def test_date_iteration():
    """Test date range iteration with relativedelta."""
    print("Testing date range iteration...")

    with patch("features.price_export.create_oracle_wrapper") as mock_oracle:
        mock_wrapper = Mock()
        mock_oracle.return_value = mock_wrapper
        mock_wrapper.connect.return_value = True
        mock_wrapper.execute_scalar.return_value = '{"test": "data"}'

        # Mock requests.post to avoid actual HTTP calls
        with patch("features.price_export.requests.post") as mock_post:
            mock_post.return_value = Mock(status_code=200)

            price_export = PriceExport()
            price_export.months = 1  # Test with 1 month

            # Track the dates processed
            processed_dates = []

            def mock_fetch_json(date_str):
                processed_dates.append(date_str)
                return '{"test": "data"}'

            price_export.fetch_json_from_oracle = mock_fetch_json

            # Run export for a small range
            stats = price_export.export_price_range()

            # Verify that dates were processed in correct format
            assert len(processed_dates) > 0
            assert all(
                len(date) == 10 and date[2] == "." and date[5] == "."
                for date in processed_dates
            )

            print(
                f"✓ Date iteration test passed - processed {len(processed_dates)} dates"
            )


def test_http_headers():
    """Test that HTTP headers match PRD specification exactly."""
    print("Testing HTTP headers...")

    with patch("features.price_export.create_oracle_wrapper") as mock_oracle:
        mock_wrapper = Mock()
        mock_oracle.return_value = mock_wrapper

        price_export = PriceExport()
        price_export.token = "test_token_123"

        # Mock requests.post to capture headers
        with patch("features.price_export.requests.post") as mock_post:
            mock_response = Mock()
            mock_response.status_code = 200
            mock_post.return_value = mock_response

            # Test posting JSON data
            json_data = '{"test": "data"}'
            result = price_export.post_json_to_api(json_data, "21.10.2025")

            # Verify exact headers
            expected_headers = {
                "Content-Type": "application/json",
                "X-HL-Token": "test_token_123",
            }

            mock_post.assert_called_once()
            call_args = mock_post.call_args

            # Check headers
            assert call_args[1]["headers"] == expected_headers

            # Check JSON data is passed correctly
            assert call_args[1]["data"] == json_data

            print("✓ HTTP headers test passed")


def test_error_handling():
    """Test error handling for various failure scenarios."""
    print("Testing error handling...")

    # Test Oracle error
    with patch("features.price_export.create_oracle_wrapper") as mock_oracle:
        mock_wrapper = Mock()
        mock_oracle.return_value = mock_wrapper
        mock_wrapper.connect.return_value = True

        price_export = PriceExport()
        mock_wrapper.execute_scalar.side_effect = Exception("Oracle connection failed")
        result = price_export.fetch_json_from_oracle("21.10.2025")
        assert result is None
        assert price_export.stats["oracle_errors"] == 1

    # Test HTTP error
    with patch("features.price_export.create_oracle_wrapper") as mock_oracle:
        mock_wrapper = Mock()
        mock_oracle.return_value = mock_wrapper

        price_export = PriceExport()
        with patch("features.price_export.requests.post") as mock_post:
            mock_post.side_effect = requests.exceptions.RequestException("Network error")
            result = price_export.post_json_to_api('{"test": "data"}', "21.10.2025")
            assert result is False
            print(f"Network errors count: {price_export.stats['network_errors']}")
            assert price_export.stats["network_errors"] == 1

    # Test JSON validation error
    with patch("features.price_export.create_oracle_wrapper") as mock_oracle:
        mock_wrapper = Mock()
        mock_oracle.return_value = mock_wrapper

        price_export = PriceExport()
        result = price_export.validate_json("invalid json", "21.10.2025")
        assert result is False
        assert price_export.stats["json_errors"] == 1

        print("✓ Error handling test passed")


def test_main_function():
    """Test the main function orchestration."""
    print("Testing main function...")

    with patch("features.price_export.PriceExport") as mock_price_export:
        mock_instance = Mock()
        mock_price_export.return_value = mock_instance
        mock_instance.api_url = "https://test.api.com"
        mock_instance.token = "test_token"
        mock_instance.export_price_range.return_value = {
            "total_days": 30,
            "successful_days": 28,
            "failed_days": 2,
        }

        result = main()

        # Verify the export process was called
        mock_instance.export_price_range.assert_called_once()

        # Verify result structure
        assert result["total_days"] == 30
        assert result["successful_days"] == 28
        assert result["failed_days"] == 2

        print("✓ Main function test passed")


def run_all_tests():
    """Run all tests for PriceExport functionality."""
    print("=" * 60)
    print("Running PriceExport Phase 4 Tests")
    print("=" * 60)

    try:
        test_price_export_initialization()
        test_oracle_query_format()
        test_date_iteration()
        test_http_headers()
        test_error_handling()
        test_main_function()

        print("=" * 60)
        print("✓ All tests passed successfully!")
        print("Phase 4 PriceExport implementation is working correctly.")
        print("=" * 60)

    except Exception as e:
        print(f"✗ Test failed: {str(e)}")
        import traceback

        traceback.print_exc()
        return False

    return True


if __name__ == "__main__":
    success = run_all_tests()
    sys.exit(0 if success else 1)
