from __future__ import annotations

from decimal import Decimal

from jarvis_finance.services.cash_service import _calculated_balance
from jarvis_finance.services.household_import import source_reference_hash
from jarvis_finance.services.modelled_wealth import (
    build_modelled_wealth_development,
    effective_cash_evidence,
)
from jarvis_finance.services.performance_scope import set_performance_scope_classification
from jarvis_finance.services.wealth_cockpit import _household_import_meta
from jarvis_finance.storage.database import connect_memory
from jarvis_finance.storage.migrations import apply_migrations

NOW = "2026-08-26T12:00:00Z"


def database():
    conn = connect_memory()
    apply_migrations(conn)
    for platform_id, name, kind in (
        ("pf", "PostFinance", "broker"),
        ("tw", "True Wealth", "broker"),
        ("crypto", "Crypto", "crypto"),
        ("bank", "Bank", "bank"),
    ):
        conn.execute(
            "INSERT INTO platforms(platform_id,name,platform_type,created_at) VALUES(?,?,?,?)",
            (platform_id, name, kind, NOW),
        )
    for account_id, platform_id, name, kind, included, bucket in (
        ("pf-depot", "pf", "PostFinance Depot", "brokerage", 0, "equity"),
        ("pf-cash", "pf", "PostFinance Settlement Cash", "cash", 0, "cash"),
        ("tw-total", "tw", "True Wealth", "managed_portfolio", 0, "other"),
        ("crypto-wallet", "crypto", "Crypto", "crypto", 0, "crypto"),
        ("bank-known", "bank", "Known bank", "cash", 0, "cash"),
        ("bank-unknown", "bank", "Unknown bank", "cash", 0, "cash"),
    ):
        conn.execute(
            """INSERT INTO accounts(account_id,platform_id,account_name,account_type,currency,
                      performance_included,is_active,created_at,balance_mode,portfolio_bucket)
                 VALUES(?,?,?,?, 'CHF',?,1,?,'csv_calculated',?)""",
            (account_id, platform_id, name, kind, included, NOW, bucket),
        )
    for account_id, role, included in (
        ("pf-depot", "postfinance_etrading_depot", True),
        ("pf-cash", "postfinance_etrading_cash", True),
        ("tw-total", "canonical_truewealth_total_value", True),
        ("crypto-wallet", "crypto_portfolio", True),
        ("bank-known", "not_in_investment_performance_scope", False),
        ("bank-unknown", "not_in_investment_performance_scope", False),
    ):
        set_performance_scope_classification(
            conn,
            account_id=account_id,
            included=included,
            classification_role=role,
            source="test",
            note="modelled wealth fixture",
            classified_at=NOW,
        )
    return conn


def expect_only(conn, *roles: str):
    wanted = set(roles)
    rows = conn.execute(
        """SELECT account_id,classification_role,included
             FROM performance_scope_classifications"""
    ).fetchall()
    for row in rows:
        included = str(row["classification_role"]) in wanted
        if bool(row["included"]) == included:
            continue
        set_performance_scope_classification(
            conn,
            account_id=str(row["account_id"]),
            included=False,
            classification_role="not_in_investment_performance_scope",
            source="test",
            note="narrow modelled wealth test scope",
            classified_at=NOW,
        )


def add_official(
    conn, snapshot_id: str, account_id: str, day: str, value: str, source: str,
    *, captured_at: str = NOW, quality: str = "ok",
):
    conn.execute(
        """INSERT INTO account_value_snapshots(snapshot_id,account_id,valuation_date,total_value_chf,
                  currency,source_type,quality_status,created_at,valuation_at,is_active)
             VALUES(?,?,?,?,'CHF',?,?,?,?,1)""",
        (snapshot_id, account_id, day, value, source, quality, captured_at, captured_at),
    )


def add_model(
    conn, snapshot_id: str, account_id: str, day: str, value: str, source: str,
    *, version: int = 1, captured_at: str = NOW,
):
    conn.execute(
        """INSERT INTO portfolio_valuation_snapshots(snapshot_id,scope_kind,scope_id,account_id,
                  value_original,currency,base_currency,fx_rate_to_base,fx_direction,valuation_at,
                  source,captured_at,snapshot_version,source_reference,quality_status,reason_codes_json)
             VALUES(?,'account',?,?,?,'CHF','CHF','1','original_to_base',?,?,?,?,'test','complete','[]')""",
        (snapshot_id, account_id, account_id, value, day, source, captured_at, version),
    )


def add_cash_snapshot(conn, snapshot_id: str, account_id: str, day: str, value: str, kind: str):
    conn.execute(
        """INSERT INTO cash_account_snapshots(snapshot_id,account_id,snapshot_type,balance_date,
                  amount_original,currency,amount_chf,source,created_at,created_by)
             VALUES(?,?,?,?,?,'CHF',?,'test',?,'user')""",
        (snapshot_id, account_id, kind, day, value, value, NOW),
    )


def add_canonical_movement(
    conn,
    transaction_id: str,
    account_id: str,
    day: str,
    value: str,
    source_type: str = "household_csv",
):
    conn.execute(
        """INSERT INTO transactions(
             transaction_id,transaction_type,account_id,trade_date,net_amount_original,
             currency_original,fx_rate_to_chf,net_amount_chf,source_type,is_confirmed,
             quality_status,created_at,is_voided)
           VALUES(?,'cash_movement',?,?,?,'CHF','1',?,?,1,'ok',?,0)""",
        (transaction_id, account_id, day, value, value, source_type, NOW),
    )


def component(point: dict, key: str) -> dict:
    return next(item for item in point["components"] if item["key"] == key)


def test_postfinance_model_combines_depot_and_settlement_cash_once_and_ignores_performance_gate():
    conn = database()
    expect_only(conn, "postfinance_etrading_depot", "postfinance_etrading_cash")
    add_official(conn, "pf-anchor", "pf-depot", "2026-08-26", "1000", "postfinance_official_import")
    add_model(conn, "pf-depot-model", "pf-depot", "2026-08-27", "920", "daily_market_fx_v4")
    add_model(
        conn, "pf-depot-unrelated", "pf-depot", "2026-08-27", "9999",
        "postfinance_official_import_component_v1", version=2,
    )
    add_model(conn, "pf-cash-model", "pf-cash", "2026-08-27", "110", "daily_market_fx_v4")
    conn.commit()

    before_changes = conn.total_changes
    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-27")
    replay = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-27")

    assert replay == result
    assert conn.total_changes == before_changes
    assert result["status"] == "available"
    assert result["chart_visible"] is True
    assert result["anchor"] == {
        "date": "2026-08-26",
        "value_chf": "1000.00",
        "quality": "confirmed",
    }
    assert component(result["points"][0], "postfinance")["quality"] == "confirmed"
    assert component(result["points"][-1], "postfinance")["value_chf"] == "1030.00"
    assert result["current"]["value_chf"] == "1030.00"
    assert result["change_chf"] == "30.00"
    assert result["change_pct"] == "3.0000"


def test_historical_days_never_receive_a_later_current_price_and_carry_is_forward_only():
    conn = database()
    expect_only(conn, "crypto_portfolio")
    add_model(conn, "crypto-25", "crypto-wallet", "2026-08-25", "200", "daily_crypto_valuation_v1")
    add_model(
        conn, "crypto-25-legacy", "crypto-wallet", "2026-08-25", "190",
        "daily_crypto_current_valuation_v1", version=2,
        captured_at="2026-08-26T11:00:00Z",
    )
    add_model(conn, "crypto-27", "crypto-wallet", "2026-08-27", "260", "daily_crypto_valuation_v1")
    conn.commit()
    before = conn.total_changes

    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-27")

    assert result["chart_visible"] is True
    day_26 = next(point for point in result["points"] if point["date"] == "2026-08-26")
    assert component(day_26, "crypto") == {
        "key": "crypto",
        "label": "Krypto",
        "value_chf": "200.00",
        "quality": "carried",
        "source_date": "2026-08-25",
    }
    assert conn.total_changes == before


def test_current_virtual_crypto_total_wins_without_double_counting_classified_account_scope():
    conn = database()
    expect_only(conn, "crypto_portfolio")
    add_model(
        conn,
        "crypto-account-total",
        "crypto-wallet",
        "2026-08-28",
        "48105.19",
        "daily_crypto_valuation_v1",
        captured_at="2026-08-28T10:00:00Z",
    )
    conn.execute(
        """INSERT INTO portfolio_valuation_snapshots(
               snapshot_id,scope_kind,scope_id,account_id,value_original,currency,
               base_currency,fx_rate_to_base,fx_direction,valuation_at,source,captured_at,
               snapshot_version,source_reference,quality_status,reason_codes_json
           ) VALUES(
               'crypto-current-total','account','crypto-recorded-holdings',NULL,'47989.61','CHF',
               'CHF','1','original_to_base','2026-08-28','daily_crypto_current_valuation_v1',
               '2026-08-28T11:00:00Z',1,'test','complete','[]'
           )"""
    )
    conn.commit()

    result = build_modelled_wealth_development(
        conn, period="1m", as_of="2026-08-28"
    )

    crypto = component(result["points"][-1], "crypto")
    assert crypto["value_chf"] == "47989.61"
    assert crypto["source_date"] == "2026-08-28"
    assert result["current"]["value_chf"] == "47989.61"


def test_mixed_anchor_dates_and_one_unknown_account_do_not_suppress_known_total_or_chart():
    conn = database()
    expect_only(conn, "postfinance_etrading_depot", "postfinance_etrading_cash", "canonical_truewealth_total_value")
    add_official(conn, "pf-anchor", "pf-depot", "2026-08-25", "1000", "postfinance_official_import")
    add_official(conn, "tw-anchor", "tw-total", "2026-08-26", "500", "truewealth_official_import")
    add_cash_snapshot(conn, "bank-anchor", "bank-known", "2026-08-24", "100", "csv_anchor_balance")
    conn.execute(
        """INSERT INTO accounts(
             account_id,platform_id,account_name,account_type,currency,
             performance_included,is_active,balance_mode,created_at)
           VALUES('empty-placeholder','bank','Legacy empty placeholder','cash','CHF',0,1,'manual',?)""",
        (NOW,),
    )
    conn.execute(
        """INSERT INTO budget_accounts(
             budget_account_id,linked_account_id,name,account_type,currency,is_active,created_at)
           VALUES('budget-unknown','bank-unknown','Unknown bank','savings','CHF',1,?)""",
        (NOW,),
    )
    conn.commit()

    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-26")

    assert result["chart_visible"] is True
    assert result["current"]["value_chf"] == "1600.00"
    assert result["baseline"]["date"] == "2026-08-26"
    assert result["change_chf"] == "0.00"
    assert result["current"]["quality"] == "incomplete"
    assert [item["label"] for item in result["unknown_accounts"]] == ["Bankkonto"]
    assert len(result["points"]) >= 2


def test_new_official_anchor_adds_correction_marker_without_mutating_predecessor_model():
    conn = database()
    expect_only(conn, "canonical_truewealth_total_value")
    add_official(conn, "tw-anchor-1", "tw-total", "2026-08-25", "500", "truewealth_official_import")
    add_model(conn, "tw-model", "tw-total", "2026-08-26", "520", "truewealth_modelled_daily")
    add_official(conn, "tw-anchor-2", "tw-total", "2026-08-27", "525", "truewealth_official_import")
    conn.commit()

    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-27")

    assert result["correction_markers"] == [
        {
            "date": "2026-08-27",
            "source_key": "truewealth",
            "confirmed_value_chf": "525.00",
            "predecessor_model_value_chf": "520.00",
            "difference_chf": "5.00",
        }
    ]
    assert conn.execute("SELECT value_original FROM portfolio_valuation_snapshots WHERE snapshot_id='tw-model'").fetchone()[0] == "520"


def test_effective_cash_evidence_uses_latest_day_then_documented_same_day_precedence_and_movements():
    conn = database()
    add_cash_snapshot(conn, "csv", "bank-known", "2026-08-25", "100", "csv_anchor_balance")
    add_cash_snapshot(conn, "manual", "bank-known", "2026-08-25", "110", "manual_balance")
    add_cash_snapshot(conn, "recon", "bank-known", "2026-08-25", "120", "reconciliation")
    conn.execute(
        "INSERT INTO budget_accounts(budget_account_id,linked_account_id,name,account_type,currency,is_active,created_at) VALUES('budget-bank','bank-known','Known bank','checking','CHF',1,?)",
        (NOW,),
    )
    conn.execute(
        """INSERT INTO budget_transactions(budget_transaction_id,account_id,transaction_type,transaction_date,
                  description,amount_original,currency_original,fx_rate_to_chf,amount_chf,fx_status,status,source_type,created_at)
             VALUES('movement','budget-bank','income','2026-08-26','Confirmed movement','10','CHF','1','10','ok','confirmed','import_candidate',?)""",
        (NOW,),
    )
    conn.commit()

    evidence = effective_cash_evidence(conn, account_id="bank-known", as_of="2026-08-26")

    assert evidence["anchor_type"] == "reconciliation"
    assert evidence["anchor_value_chf"] == "120.00"
    assert evidence["value_chf"] == "130.00"
    assert evidence["quality"] == "carried"


def test_effective_cash_evidence_recognizes_each_supported_snapshot_type_and_no_evidence_is_unknown():
    conn = database()
    for account_id, kind, value in (
        ("bank-known", "csv_anchor_balance", "100"),
        ("pf-cash", "manual_balance", "200"),
        ("bank-unknown", "reconciliation", "300"),
    ):
        add_cash_snapshot(conn, f"s-{account_id}", account_id, "2026-08-25", value, kind)
    conn.execute(
        """INSERT INTO accounts(
             account_id,platform_id,account_name,account_type,currency,
             performance_included,is_active,created_at,balance_mode,portfolio_bucket)
           VALUES('bank-calculated','bank','Calculated bank','cash','CHF',0,1,?,
                  'csv_calculated','cash')""",
        (NOW,),
    )
    add_canonical_movement(conn, "calculated-move", "bank-calculated", "2026-08-25", "50")
    conn.commit()

    assert effective_cash_evidence(conn, account_id="bank-known", as_of="2026-08-25")["value_chf"] == "100.00"
    assert effective_cash_evidence(conn, account_id="pf-cash", as_of="2026-08-25")["value_chf"] == "200.00"
    assert effective_cash_evidence(conn, account_id="bank-unknown", as_of="2026-08-25")["value_chf"] == "300.00"
    calculated = effective_cash_evidence(conn, account_id="bank-calculated", as_of="2026-08-25")
    assert calculated["anchor_type"] == "calculated_balance"
    assert calculated["value_chf"] == "50.00"
    assert effective_cash_evidence(conn, account_id="missing", as_of="2026-08-25")["quality"] == "unavailable"


def test_cash_uses_one_authoritative_ledger_and_exposes_real_movement_day():
    conn = database()
    add_cash_snapshot(conn, "anchor", "bank-known", "2026-08-24", "100", "csv_anchor_balance")
    conn.execute(
        """INSERT INTO budget_accounts(
             budget_account_id,linked_account_id,name,account_type,currency,is_active,created_at)
           VALUES('budget-bank','bank-known','Known bank','checking','CHF',1,?)""",
        (NOW,),
    )
    conn.execute(
        """INSERT INTO budget_transactions(
             budget_transaction_id,account_id,transaction_type,transaction_date,description,
             amount_original,currency_original,fx_rate_to_chf,amount_chf,fx_status,status,
             source_type,created_at)
           VALUES('budget-move','budget-bank','income','2026-08-25','Movement',
                  '10','CHF','1','10','ok','confirmed','import_candidate',?)""",
        (NOW,),
    )
    add_canonical_movement(conn, "duplicate-move", "bank-known", "2026-08-25", "10")
    add_canonical_movement(
        conn,
        "manual-adjustment",
        "bank-known",
        "2026-08-25",
        "7",
        source_type="vue_manual_cash",
    )
    conn.commit()

    evidence = effective_cash_evidence(conn, account_id="bank-known", as_of="2026-08-26")

    assert evidence["value_chf"] == "117.00"
    assert evidence["movement_chf"] == "17.00"
    assert evidence["movement_source"] == "budget+canonical"
    assert evidence["source_date"] == "2026-08-25"
    assert _calculated_balance(conn, "bank-known") == Decimal("117")


def test_cash_position_and_model_use_the_same_confirmed_canonical_ledger():
    conn = database()
    add_cash_snapshot(conn, "anchor", "bank-known", "2026-08-24", "100", "csv_anchor_balance")
    add_canonical_movement(
        conn,
        "manual-1",
        "bank-known",
        "2026-08-25",
        "10",
        source_type="vue_manual_cash",
    )
    conn.commit()

    evidence = effective_cash_evidence(conn, account_id="bank-known", as_of="2026-08-26")
    assert evidence["value_chf"] == "110.00"
    assert _calculated_balance(conn, "bank-known") == Decimal("110")


def test_cash_movement_dates_make_a_real_value_change_chart_visible():
    conn = database()
    expect_only(conn)
    add_cash_snapshot(conn, "anchor", "bank-known", "2026-08-24", "100", "csv_anchor_balance")
    add_canonical_movement(conn, "move", "bank-known", "2026-08-25", "10")
    conn.commit()

    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-26")

    assert result["chart_visible"] is True
    assert result["current"]["value_chf"] == "110.00"


def test_mixed_age_bank_total_uses_the_oldest_component_source_date():
    conn = database()
    expect_only(conn)
    add_cash_snapshot(conn, "older", "bank-known", "2026-08-20", "100", "manual_balance")
    add_cash_snapshot(conn, "newer", "bank-unknown", "2026-08-26", "200", "reconciliation")
    conn.commit()

    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-26")
    bank = component(result["points"][-1], "bank_cash")

    assert bank["value_chf"] == "300.00"
    assert bank["quality"] == "carried"
    assert bank["source_date"] == "2026-08-20"


def test_missing_expected_investment_component_marks_partial_total_incomplete():
    conn = database()
    expect_only(conn, "postfinance_etrading_depot", "crypto_portfolio")
    add_official(conn, "pf-anchor", "pf-depot", "2026-08-26", "100", "postfinance_official_import")
    conn.commit()

    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-26")

    assert result["current"] == {
        "date": "2026-08-26", "value_chf": "100.00", "quality": "incomplete"
    }
    assert result["unknown_accounts"] == [
        {
            "key": "unknown-component-crypto",
            "label": "Krypto",
            "reason_code": "stored_valuation_evidence_missing",
        }
    ]


def test_official_source_and_quality_allowlists_fail_closed():
    conn = database()
    expect_only(conn, "canonical_truewealth_total_value")
    add_official(conn, "official", "tw-total", "2026-08-26", "500", "truewealth_official_import")
    add_official(conn, "unrelated", "tw-total", "2026-08-26", "999", "legacy_projection", captured_at="2026-08-26T13:00:00Z")
    add_official(conn, "bad-quality", "tw-total", "2026-08-27", "777", "truewealth_official_import", quality="invalid")
    add_official(conn, "malformed", "tw-total", "2026-08-28", "not-a-number", "truewealth_official_import")
    add_official(conn, "bad-date", "tw-total", "2026-00-99", "999", "truewealth_official_import")
    add_model(
        conn,
        "bad-model-date",
        "tw-total",
        "2026-00-98",
        "999",
        "truewealth_modelled_daily",
    )
    conn.commit()

    result = build_modelled_wealth_development(conn, period="all", as_of="2026-08-28")

    assert result["period"]["preset"] == "all"
    assert result["current"]["value_chf"] == "500.00"
    assert result["current"]["quality"] == "carried"


def test_same_day_model_before_official_import_creates_correction_marker():
    conn = database()
    expect_only(conn, "canonical_truewealth_total_value")
    add_model(
        conn, "model", "tw-total", "2026-08-26", "520",
        "truewealth_modelled_daily", captured_at="2026-08-26T10:00:00Z",
    )
    add_official(
        conn, "official", "tw-total", "2026-08-26", "525",
        "truewealth_official_import", captured_at="2026-08-26T11:00:00Z",
    )
    conn.commit()

    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-26")

    assert result["correction_markers"][0]["predecessor_model_value_chf"] == "520.00"
    assert result["correction_markers"][0]["difference_chf"] == "5.00"


def test_unknown_cash_account_never_leaks_raw_private_name_or_identifier():
    conn = database()
    expect_only(conn)
    conn.execute(
        "UPDATE accounts SET account_name='Alice CH93 0000 0000 0000 0000 0' WHERE account_id='bank-unknown'"
    )
    conn.execute(
        """INSERT INTO budget_accounts(
             budget_account_id,linked_account_id,name,account_type,currency,is_active,created_at)
           VALUES('budget-private','bank-unknown','Private','savings','CHF',1,?)""",
        (NOW,),
    )
    add_cash_snapshot(conn, "known", "bank-known", "2026-08-26", "100", "reconciliation")
    conn.commit()

    result = build_modelled_wealth_development(conn, period="1m", as_of="2026-08-26")

    payload = str(result["unknown_accounts"])
    assert result["unknown_accounts"][0]["label"] == "Bankkonto"
    assert "Alice" not in payload
    assert "CH93" not in payload
    assert "bank-unknown" not in payload


def test_household_import_metadata_is_canonical_account_specific(monkeypatch):
    monkeypatch.setenv("JARVIS_FINANCE_FINGERPRINT_KEY", "test-fingerprint-key")
    conn = database()
    for budget_id, account_id, label in (
        ("budget-5632", "bank-known", "Privatkonto 5632"),
        ("budget-5031", "bank-unknown", "Sparkonto 5031"),
    ):
        conn.execute(
            """INSERT INTO budget_accounts(
                 budget_account_id,linked_account_id,name,account_type,currency,is_active,created_at)
               VALUES(?,?,?,'checking','CHF',1,?)""",
            (budget_id, account_id, label, NOW),
        )
    for mapping_id, budget_id, account_id, reference in (
        ("map-5632", "budget-5632", "bank-known", "private-account-5632"),
        ("map-5031", "budget-5031", "bank-unknown", "savings-account-5031"),
    ):
        conn.execute(
            """INSERT INTO household_account_source_mappings(
                 mapping_id,contract_version,source_type,source_reference_hash,budget_account_id,
                 canonical_account_id,reference_hint,is_active,created_at,updated_at)
               VALUES(?,'household_import_v1','raiffeisen_bank',?,?,?,'configured',1,?,?)""",
            (
                mapping_id,
                source_reference_hash(reference),
                budget_id,
                account_id,
                NOW,
                NOW,
            ),
        )
    conn.execute(
        """INSERT INTO audit_log(
             audit_id,timestamp,source,action,entity_type,entity_id,old_values_json,
             new_values_json,created_by,created_at)
           VALUES('audit-batch',?,'test','confirm','batch','batch','{}','{}','user',?)""",
        (NOW, NOW),
    )
    conn.execute(
        """INSERT INTO household_import_batches(
             batch_id,contract_version,preview_fingerprint,baseline_fingerprint,input_fingerprint,
             file_count,row_count,candidate_count,transfer_pair_count,duplicate_count,review_count,
             receipt_link_count,status,audit_id,confirmed_at,confirmed_by)
           VALUES('batch','household_import_v1',
                  'pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp',
                  'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
                  'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii',
                  1,2,1,0,1,1,0,
                  'confirmed','audit-batch',?,'user')""",
        (NOW,),
    )
    conn.execute(
        """INSERT INTO budget_transaction_candidates(
             transaction_candidate_id,source_file_label,source_type,transaction_date,description,
             amount_original,currency_original,confidence,requires_review,status,created_at,
             account_source,household_batch_id,source_row_fingerprint,logical_fingerprint)
           VALUES('candidate-5632','private.csv','raiffeisen_bank','2026-08-25','Private row',
                  '10','CHF','1',1,'needs_review',?,'private-account-5632','batch','row','logical')""",
        (NOW,),
    )
    conn.commit()

    private = _household_import_meta(
        conn, "raiffeisen", canonical_account_id="bank-known"
    )
    savings = _household_import_meta(
        conn, "raiffeisen", canonical_account_id="bank-unknown"
    )

    assert private["new_rows"] == 1
    assert private["review_rows"] == 1
    assert private["coverage_to"] == "2026-08-25"
    assert savings == {
        "imported_at": None,
        "coverage_from": None,
        "coverage_to": None,
        "coverage_status": "unavailable",
        "new_rows": 0,
        "duplicate_rows": 0,
        "review_rows": 0,
    }
