import datetime as dt

from fastapi.testclient import TestClient
from sqlalchemy.orm import Session

from fxhnt.adapters.persistence.cockpit_models import (
    ForwardSummaryRow,
    StrategyAllocationRow,
    StrategyFundingRow,
)
from fxhnt.adapters.persistence.forward_nav import ForwardNavRepo
from fxhnt.adapters.web.app import create_app


def _client(tmp_path):
    repo = ForwardNavRepo(f"sqlite:///{tmp_path/'c.db'}")
    repo.migrate()
    return TestClient(create_app(repo))


def test_overview_renders_bottom_tab_nav(tmp_path):
    r = _client(tmp_path).get("/")
    assert r.status_code == 200
    assert 'class="tabs"' in r.text            # the mobile bottom-tab nav is present
    assert ">Overview<" in r.text


def test_overview_shows_allocation_and_funding(tmp_path):
    repo = ForwardNavRepo(f"sqlite:///{tmp_path/'c.db'}")
    repo.migrate()
    at = dt.datetime(2026, 7, 10)
    repo.replace_allocations([StrategyAllocationRow(strategy_id="bybit_4edge", target_weight=0.54,
        target_dollars=18900.0, policy_version=1, policy_hash="h", as_of="2026-07-10", computed_at=at)], at)
    repo.replace_funding([StrategyFundingRow(strategy_id="bybit_4edge", state="funded", label="funded",
        decay_run=0, recovery_run=0, first_pass_date=None, policy_version=2, policy_hash="h",
        as_of="2026-07-10", computed_at=at)], at)
    r = TestClient(create_app(repo)).get("/")
    assert r.status_code == 200
    assert "18,900" in r.text or "18900" in r.text     # allocation dollars surfaced
    assert "funded" in r.text                            # funding badge surfaced
    # The meter's denominator is the FUND'S capital (fund_config SSOT, falling back to settings.paper_capital
    # — NOT the separate allocation-engine gross-headroom ceiling), so with no fund_config row seeded it
    # resolves to the paper_capital default.
    assert "100,000" in r.text


def test_detail_shows_lifecycle_blocks(tmp_path):
    repo = ForwardNavRepo(f"sqlite:///{tmp_path/'c.db'}")
    repo.migrate()
    at = dt.datetime(2026, 7, 10)
    repo.replace_funding([StrategyFundingRow(strategy_id="bybit_4edge", state="funded", label="funded",
        decay_run=0, recovery_run=0, first_pass_date=None, policy_version=2, policy_hash="h",
        as_of="2026-07-10", computed_at=at)], at)
    repo.replace_allocations([StrategyAllocationRow(strategy_id="bybit_4edge", target_weight=0.54,
        target_dollars=18900.0, policy_version=1, policy_hash="h", as_of="2026-07-10", computed_at=at)], at)
    r = TestClient(create_app(repo)).get("/strategy/bybit_4edge")
    assert r.status_code == 200
    assert "Funding health" in r.text
    # Redesigned: the old standalone "Allocation" card is now the "In the fund" stat card (real capital
    # deployed here) among the top-of-page cards.
    assert "In the fund" in r.text
    assert "18,900" in r.text or "18900" in r.text


def test_detail_shows_executed_reality_block(tmp_path):
    repo = ForwardNavRepo(f"sqlite:///{tmp_path/'c.db'}")
    repo.migrate()
    at = dt.datetime(2026, 7, 10)
    with Session(repo._engine) as s:
        s.add_all([
            ForwardSummaryRow(strategy_id="bybit_4edge", as_of="2026-07-10", days=5, nav=1.0031,
                            total_return=0.0031, sharpe=1.0, maxdd=-0.05, gate_status="WAIT",
                            gate_reason="", src_updated_at=at),
            ForwardSummaryRow(strategy_id="bybit_4edge_exec", as_of="2026-07-10", days=5, nav=1.0019,
                            total_return=0.0019, sharpe=1.0, maxdd=-0.05, gate_status="WAIT",
                            gate_reason="", src_updated_at=at),
        ])
        s.commit()
    r = TestClient(create_app(repo)).get("/strategy/bybit_4edge")
    assert r.status_code == 200
    # The bybit_4edge book has an executed testnet twin (bybit_4edge_exec) with a forward summary, so the
    # guarded exec-twin "Real trades vs the plan" card renders (real trades vs the modeled plan) even though
    # this book is NOT an IBKR-account book (d.recon is None). The book's own forward +0.31% also shows in the
    # "Live paper so far" card.
    assert "Real trades vs the plan" in r.text
    assert "+0.31%" in r.text   # bybit_4edge's own forward return still renders
