"""
每日自动划转:北京时间指定整点小时内,将交易账户(AUTO_TRANSFER_TO)余额调整至目标额.

- 交易账户 < 目标:从资金账户划入差额
- 交易账户 > 目标:将多余划回资金账户
- 有 active 持仓:不划转,写账簿并企业微信说明
"""
from __future__ import annotations

from typing import Any, Callable


def run_auto_transfer_once_per_day(
    *,
    enabled: bool,
    bj_hour: int,
    target_amount: float,
    from_account: str,
    to_account: str,
    funds_decimals: int,
    get_db: Callable[[], Any],
    get_active_position_count: Callable[[Any], int],
    get_account_usdt_total: Callable[[str], float | None],
    execute_transfer_usdt: Callable[[float, str, str], tuple[bool, str, Any]],
    send_wechat_msg: Callable[[str], None],
    utc_now_dt: Callable[[], Any],
    app_tz: Any,
    utc_calendar_date_str: Callable[[], str],
    app_now_str: Callable[[], str],
    min_transfer: float = 0.01,
) -> None:
    if not enabled:
        return
    utc_dt = utc_now_dt()
    bj = utc_dt.astimezone(app_tz)
    if bj.hour != bj_hour:
        return

    transfer_day = utc_calendar_date_str()
    conn = get_db()
    exists = conn.execute(
        "SELECT id FROM transfer_logs WHERE transfer_type=? AND transfer_day=?",
        ("auto_daily", transfer_day),
    ).fetchone()
    if exists:
        conn.close()
        return

    def _log(
        amount: float,
        fr: str,
        to: str,
        status: str,
        message: str,
        *,
        commit_close: bool = True,
    ) -> None:
        conn.execute(
            "INSERT INTO transfer_logs (transfer_type, transfer_day, amount, from_account, to_account, status, message) VALUES (?,?,?,?,?,?,?)",
            ("auto_daily", transfer_day, amount, fr, to, status, message[:500]),
        )
        conn.commit()
        if commit_close:
            conn.close()

    active = get_active_position_count(conn)
    if active > 0:
        msg = f"持仓中({active}笔),本次资金无划转"
        _log(0, from_account, to_account, "skipped", msg)
        send_wechat_msg(
            f"自动划转:{msg}\n"
            f"目标:{to_account} 调整至 {round(float(target_amount), funds_decimals)}U\n"
            f"账簿日(UTC):{transfer_day}｜触发时刻(北京):{app_now_str()}"
        )
        return

    target = round(float(target_amount), funds_decimals)
    trade_bal = get_account_usdt_total(to_account)
    if trade_bal is None:
        _log(
            0,
            from_account,
            to_account,
            "failed",
            f"读取{to_account}账户USDT失败",
        )
        return

    trade = round(float(trade_bal), funds_decimals)
    diff = round(target - trade, funds_decimals)

    if abs(diff) < min_transfer:
        _log(
            0,
            from_account,
            to_account,
            "skipped",
            f"{to_account}账户已为{trade}U(目标{target}U)",
        )
        return

    if diff > 0:
        fr, to, amount = from_account, to_account, diff
        action = "划入"
    else:
        fr, to, amount = to_account, from_account, round(abs(diff), funds_decimals)
        action = "划出"

    from_bal = get_account_usdt_total(fr)
    if from_bal is not None and round(float(from_bal), funds_decimals) < amount:
        cur = round(float(from_bal), funds_decimals)
        _log(amount, fr, to, "failed", f"{fr}账户USDT不足,需{amount}U,当前{cur}U")
        send_wechat_msg(
            f"自动划转失败:{fr}余额不足,需{amount}U,当前{cur}U({action}至{to_account}目标{target}U)\n"
            f"账簿日(UTC):{transfer_day}｜触发时刻(北京):{app_now_str()}"
        )
        return

    ok, msg, _ = execute_transfer_usdt(amount, fr, to)
    _log(amount, fr, to, "success" if ok else "failed", msg)
    if ok:
        send_wechat_msg(
            f"自动划转成功:{to_account} {trade}U→目标{target}U,{action}{amount}U {fr}->{to}\n"
            f"账簿日(UTC):{transfer_day}｜触发时刻(北京):{app_now_str()}"
        )
    else:
        send_wechat_msg(
            f"自动划转失败:计划{action}{amount}U {fr}->{to}(目标{target}U)\n原因:{msg}\n"
            f"账簿日(UTC):{transfer_day}｜触发时刻(北京):{app_now_str()}"
        )
