"""Tests for E2E digital/ATG helper functions."""
import pytest
from decimal import Decimal
from unittest.mock import AsyncMock, MagicMock
from datetime import date

from app.services.end_to_end_service import (
    _get_penerimaan_digital_e2e,
    _get_penjualan_digital_e2e,
    _get_harian_compare,
)


@pytest.mark.asyncio
async def test_get_penerimaan_digital_e2e_returns_sum():
    """Returns sum of ATG deltas when data exists."""
    db = AsyncMock()
    db.execute = AsyncMock(return_value=MagicMock(scalar_one_or_none=lambda: Decimal("1500.000")))

    result = await _get_penerimaan_digital_e2e(
        db, tangki_id=1,
        start_date=date(2026, 4, 1),
        end_date=date(2026, 4, 30),
    )
    assert result == Decimal("1500.000")


@pytest.mark.asyncio
async def test_get_penerimaan_digital_e2e_returns_none_when_no_data():
    """Returns None when no ATG data exists."""
    db = AsyncMock()
    db.execute = AsyncMock(return_value=MagicMock(scalar_one_or_none=lambda: None))

    result = await _get_penerimaan_digital_e2e(
        db, tangki_id=1,
        start_date=date(2026, 4, 1),
        end_date=date(2026, 4, 30),
    )
    assert result is None


@pytest.mark.asyncio
async def test_get_penjualan_digital_e2e_returns_sum():
    """Returns sum of digital teller deltas when data exists."""
    db = AsyncMock()
    db.execute = AsyncMock(return_value=MagicMock(scalar_one_or_none=lambda: Decimal("9800.000")))

    result = await _get_penjualan_digital_e2e(
        db, tangki_id=1,
        start_date=date(2026, 4, 1),
        end_date=date(2026, 4, 30),
    )
    assert result == Decimal("9800.000")


@pytest.mark.asyncio
async def test_get_penjualan_digital_e2e_returns_none_when_no_data():
    """Returns None when no digital teller data exists."""
    db = AsyncMock()
    db.execute = AsyncMock(return_value=MagicMock(scalar_one_or_none=lambda: None))

    result = await _get_penjualan_digital_e2e(
        db, tangki_id=1,
        start_date=date(2026, 4, 1),
        end_date=date(2026, 4, 30),
    )
    assert result is None


@pytest.mark.asyncio
async def test_get_harian_compare_returns_sum_and_count():
    """Returns losses sum and period count from approved rekonsiliasi harian."""
    mock_row = MagicMock()
    mock_row.losses_sum = Decimal("500.000")
    mock_row.periode_count = 10
    db = AsyncMock()
    db.execute = AsyncMock(return_value=MagicMock(one_or_none=lambda: mock_row))

    result = await _get_harian_compare(
        db, spbu_id=1, tangki_id=1,
        tanggal_mulai=date(2026, 4, 1),
        tanggal_selesai=date(2026, 4, 30),
    )
    assert result["harian_losses_sum"] == Decimal("500.000")
    assert result["harian_periode_count"] == 10


@pytest.mark.asyncio
async def test_get_harian_compare_returns_none_when_no_approved_data():
    """Returns None fields when no approved rekonsiliasi harian exists in range."""
    db = AsyncMock()
    db.execute = AsyncMock(return_value=MagicMock(one_or_none=lambda: None))

    result = await _get_harian_compare(
        db, spbu_id=1, tangki_id=1,
        tanggal_mulai=date(2026, 4, 1),
        tanggal_selesai=date(2026, 4, 30),
    )
    assert result["harian_losses_sum"] is None
    assert result["harian_periode_count"] is None
