"""DataContract 冒烟：issue 形态与 mapping 一致（不连 DB）。"""
from __future__ import annotations

import sys
from unittest.mock import patch

import pytest

# 无 pandas 时注入占位模块；已安装则使用真实 pandas。
try:
    import pandas as _pandas  # noqa: F401
except ImportError:
    import types

    _pd = types.ModuleType("pandas")
    _pd.DataFrame = object  # type: ignore[attr-defined]
    sys.modules["pandas"] = _pd

from core.modules.data_contract import DataContractManager, DataKey, IssueResult
from core.modules.data_contract.cache import ContractCacheManager
from core.modules.data_contract.contract_const import ContractScope
from core.modules.data_contract.contracts import NonTimeSeriesContract, TimeSeriesContract
from core.modules.data_contract.loaders import StockKlineLoader, StockListLoader, TagLoader


@pytest.fixture
def mgr() -> DataContractManager:
    return DataContractManager(contract_cache=ContractCacheManager())


def test_stock_list_issue_shape(mgr: DataContractManager):
    with patch.object(mgr, "_issue_global") as issue_global:
        fake_contract = mgr.issuer.issue(DataKey.STOCK_LIST)
        fake_contract.data = [{"id": "600000.SH"}]
        issue_global.return_value = fake_contract

        result = mgr.issue(DataKey.STOCK_LIST)

    assert isinstance(result, IssueResult)
    c = result.require_contract()
    assert c.meta.data_id == DataKey.STOCK_LIST
    assert c.meta.scope == ContractScope.GLOBAL
    assert isinstance(c, NonTimeSeriesContract)
    assert isinstance(c.loader, StockListLoader)
    assert c.data == [{"id": "600000.SH"}]


def test_kline_qfq_issue_shape(mgr: DataContractManager):
    result = mgr.issue(DataKey.STOCK_KLINE_DAILY, entity_id="600000.SH", adjust="qfq")
    assert isinstance(result, IssueResult)
    assert result.entity_count == 1
    c = result.require_one()
    assert c.meta.data_id == DataKey.STOCK_KLINE_DAILY
    assert c.meta.scope == ContractScope.PER_ENTITY
    assert isinstance(c, TimeSeriesContract)
    assert isinstance(c.loader, StockKlineLoader)
    assert c.loader_params.get("adjust") == "qfq"
    assert c.loader_params.get("term") == "daily"
    assert c.data is None


def test_tag_issue_shape(mgr: DataContractManager):
    result = mgr.issue(DataKey.TAG, entity_id="000001.SZ")
    c = result.require_one()
    assert c.meta.data_id == DataKey.TAG
    assert isinstance(c, TimeSeriesContract)
    assert isinstance(c.loader, TagLoader)
    assert getattr(c, "time_axis_field", None) == "as_of_date"
    assert c.data is None


def test_tag_load_requires_scenario(mgr: DataContractManager):
    with pytest.raises(ValueError, match="scenario"):
        mgr.issue(DataKey.TAG, entity_id="000001.SZ").require_one().load(
            start="20200101", end="20201231"
        )
