"""期权平仓/到期状态同步单测."""
import sqlite3

from lib.exchange.okx_options_lib import (
    format_option_history_row,
    format_usdc_amount,
    is_option_full_close_history,
    resolve_option_close_from_history,
)
from lib.options.options_db import init_options_tables
from lib.options.options_monitor_lib import sync_open_options_trades


def test_format_usdc_amount():
    assert format_usdc_amount(4.896) == "4.90"
    assert format_usdc_amount(4.9) == "4.90"
    assert format_usdc_amount(4.0) == "4.00"


def test_is_option_full_close_history():
    assert is_option_full_close_history({"type": "2"})
    assert is_option_full_close_history({"type": "3"})
    assert not is_option_full_close_history({"type": "1"})
    assert not is_option_full_close_history({"type": "5"})


def test_format_option_history_row():
    raw = {
        "instId": "BTC-USD_UM-260710-62000-P",
        "openAvgPx": "380",
        "closeAvgPx": "0",
        "closeTotalPos": "1",
        "openMaxPos": "1",
        "realizedPnl": "-3.99",
        "pnlRatio": "-1.049",
        "type": "2",
        "cTime": "1784000000000",
        "uTime": "1784088035000",
        "posId": "pos-btc",
    }
    row = format_option_history_row(raw, tick_sz="0.1", ct_mult=0.01)
    assert row["inst_id"] == "BTC-USD_UM-260710-62000-P"
    assert row["sheets"] == 1
    assert row["realized_pnl"] == -3.99
    assert row["status_label"] == "已平"
    assert row["open_avg_px_fmt"] == "380"
    assert row["premium_paid_fmt"] == "3.80"
    assert row["history_key"] == "ex:pos-btc"


def test_resolve_option_close_from_history_picks_latest():
    rows = [
        {"instId": "ETH-USD_UM-260709-1700-P", "uTime": "1000", "realizedPnl": "-1.0", "closeAvgPx": "0"},
        {"instId": "ETH-USD_UM-260709-1700-P", "uTime": "2000", "realizedPnl": "-1.24", "closeAvgPx": "0", "posId": "9"},
    ]
    got = resolve_option_close_from_history(rows, open_ms=500)
    assert got is not None
    assert got["realized_pnl"] == -1.24
    assert got["pos_id"] == "9"


def test_sync_open_options_trades_marks_expired_closed():
    conn = sqlite3.connect(":memory:")
    conn.row_factory = sqlite3.Row
    init_options_tables(conn)
    conn.execute(
        """
        INSERT INTO options_trades
        (inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
         open_quote, premium_paid, status)
        VALUES (?, 'ETH', 'P', 1700, '', 20, 0.2, 6.2, 1.24, 'open')
        """,
        ("ETH-USD_UM-260709-1700-P",),
    )
    conn.commit()

    n = sync_open_options_trades(
        conn,
        live_inst_ids=set(),
        fetch_history_fn=lambda _inst: [],
    )
    assert n == 1
    row = conn.execute("SELECT status, premium_received, realized_pnl, signal_note FROM options_trades").fetchone()
    assert row["status"] == "closed"
    assert row["premium_received"] == 0.0
    assert row["realized_pnl"] == -1.24
    assert "到期结算" in (row["signal_note"] or "")


def test_sync_open_options_trades_skips_without_close_evidence():
    conn = sqlite3.connect(":memory:")
    conn.row_factory = sqlite3.Row
    init_options_tables(conn)
    conn.execute(
        """
        INSERT INTO options_trades
        (inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
         open_quote, premium_paid, status, created_at)
        VALUES (?, 'BTC', 'P', 62000, '', 1, 0.01, 380.0, 3.8, 'open', '2026-07-09 08:00:00')
        """,
        ("BTC-USD_UM-260710-62000-P",),
    )
    conn.commit()

    n = sync_open_options_trades(
        conn,
        live_inst_ids=set(),
        fetch_history_fn=lambda _inst: [],
    )
    assert n == 0
    row = conn.execute("SELECT status FROM options_trades").fetchone()
    assert row["status"] == "open"


def test_reconcile_live_open_trades_reopens_sync_artifact():
    conn = sqlite3.connect(":memory:")
    conn.row_factory = sqlite3.Row
    init_options_tables(conn)
    conn.execute(
        """
        INSERT INTO options_trades
        (inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
         open_quote, premium_paid, status, closed_at)
        VALUES (?, 'BTC', 'P', 62000, '', 1, 0.01, 380.0, 3.8, 'closed', '2026-07-09 09:10:34')
        """,
        ("BTC-USD_UM-260710-62000-P",),
    )
    conn.commit()

    from lib.options.options_monitor_lib import reconcile_live_open_trades

    n = reconcile_live_open_trades(conn, live_inst_ids={"BTC-USD_UM-260710-62000-P"})
    assert n == 1
    row = conn.execute("SELECT status, closed_at FROM options_trades").fetchone()
    assert row["status"] == "open"
    assert row["closed_at"] is None

    conn = sqlite3.connect(":memory:")
    conn.row_factory = sqlite3.Row
    init_options_tables(conn)
    conn.execute(
        """
        INSERT INTO options_trades
        (inst_id, underlying, opt_type, strike, exp_time, sheets, eth_amount,
         open_quote, premium_paid, status, created_at)
        VALUES (?, 'ETH', 'P', 1700, '', 20, 0.2, 6.2, 1.24, 'open', '2026-07-08 02:32:44')
        """,
        ("ETH-USD_UM-260709-1700-P",),
    )
    conn.commit()

    def _hist(_inst):
        return [
            {
                "instId": "ETH-USD_UM-260709-1700-P",
                "uTime": "1784000000000",
                "realizedPnl": "-0.5",
                "closeAvgPx": "0.1",
                "posId": "pos-1",
            }
        ]

    n = sync_open_options_trades(
        conn,
        live_inst_ids=set(),
        fetch_history_fn=_hist,
    )
    assert n == 1
    row = conn.execute(
        "SELECT status, premium_received, realized_pnl, close_ord_id FROM options_trades"
    ).fetchone()
    assert row["status"] == "closed"
    assert row["realized_pnl"] == -0.5
    assert row["premium_received"] == 0.74
    assert row["close_ord_id"] == "pos-1"
