"""Unit tests for fundamental_service — the surviving read path.

Writes to ``fundamental_data`` are covered by test_fundamental_data_refresh.py;
this file only guards the lookup used by the router and scoring.
"""

from __future__ import annotations

import json
from datetime import datetime, timezone

import pytest
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine

from app.database import Base
from app.exceptions import NotFoundError
from app.models.fundamental import FundamentalData
from app.models.ticker import Ticker
from app.services import fundamental_service

# Use a dedicated engine so commit/refresh work without conflicting
# with the conftest transactional session.
_engine = create_async_engine("sqlite+aiosqlite://", echo=False)
_session_factory = async_sessionmaker(_engine, class_=AsyncSession, expire_on_commit=False)


@pytest.fixture(autouse=True)
async def _setup_tables():
    async with _engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    yield
    async with _engine.begin() as conn:
        await conn.run_sync(Base.metadata.drop_all)


@pytest.fixture
async def session() -> AsyncSession:
    async with _session_factory() as s:
        yield s


@pytest.fixture
async def ticker(session: AsyncSession) -> Ticker:
    """Create a test ticker."""
    t = Ticker(symbol="AAPL")
    session.add(t)
    await session.commit()
    await session.refresh(t)
    return t


@pytest.mark.asyncio
async def test_get_fundamental_returns_the_cached_row(
    session: AsyncSession, ticker: Ticker
):
    fields = {"pe_ratio": "split guard applied"}
    session.add(
        FundamentalData(
            ticker_id=ticker.id,
            pe_ratio=None,
            market_cap=1_000_000.0,
            fetched_at=datetime.now(timezone.utc),
            unavailable_fields_json=json.dumps(fields),
        )
    )
    await session.commit()

    record = await fundamental_service.get_fundamental(session, symbol="aapl")

    assert record is not None
    assert record.market_cap == 1_000_000.0
    assert json.loads(record.unavailable_fields_json) == fields


@pytest.mark.asyncio
async def test_get_fundamental_returns_none_without_a_cached_row(
    session: AsyncSession, ticker: Ticker
):
    assert await fundamental_service.get_fundamental(session, symbol="AAPL") is None


@pytest.mark.asyncio
async def test_get_fundamental_rejects_an_unknown_symbol(session: AsyncSession):
    with pytest.raises(NotFoundError):
        await fundamental_service.get_fundamental(session, symbol="NOPE")
