from __future__ import annotations

import os
import re

import pytest
from playwright.sync_api import Page

from e2e.pages.wanzhanggui_order_page import WanyoujiFulfillmentPage
from e2e.tests.订单流转.test_e2e_task_001_external_order_dispatch_to_player import login_player_sub_account_by_sms
from e2e.utils.account_store import E2EAccount, account_store


@pytest.mark.e2e_settle_wanyouji_pay_001
@pytest.mark.e2e_ledger
@pytest.mark.e2e_chain
def test_丸友集完成打手结算账单打款(page: Page, settings, bug_reporter) -> None:
    account, order = resolve_wanyouji_payout_account()
    player_account = resolve_player_account_for_payout(order)
    settlement_method = os.getenv("E2E_WANYOUJI_SETTLEMENT_METHOD", "线下支付").strip()
    assert settlement_method in {"线下支付", "线上打款"}, (
        "E2E_WANYOUJI_SETTLEMENT_METHOD 仅支持：线下支付、线上打款；"
        f"当前值：{settlement_method}"
    )

    owner_page = WanyoujiFulfillmentPage(page, settings.tenant_home_url, bug_reporter)
    owner_page.login_main_account(account.phone, account.password)
    config_result = {}
    if settlement_method == "线上打款":
        config_result = owner_page.ensure_wanyouji_online_payment_config_ready()
    completion_result = owner_page.complete_wanyouji_player_settlement_bill(
        source_order_no=order.get("source_order_no", ""),
        order_title=order.get("order_title", ""),
        settlement_method=settlement_method,
    )
    completed_order_text = ""
    if not completion_result.get("expected_rejected"):
        completed_order_text = owner_page.verify_workshop_order_completed_after_player_settlement(
            order.get("source_order_no", ""),
            order.get("order_title", ""),
        )
        login_player_sub_account_by_sms(page, settings, bug_reporter, player_account)
        player_page = WanyoujiFulfillmentPage(page, settings.tenant_home_url, bug_reporter)
        player_income_completed_text = player_page.verify_player_income_settlement_completed(
            order.get("source_order_no", ""),
            order.get("order_title", ""),
            expected_amount=order.get("expected_player_amount", "70"),
            expected_total_amount=os.getenv(
                "E2E_PLAYER_SETTLEMENT_EXPECTED_TOTAL_AMOUNT",
                str(
                    completion_result.get("settlement_total_amount")
                    or order.get("wanyouji_player_settlement_total_amount")
                    or order.get("expected_player_amount", "70")
                ),
            ),
        )
    else:
        player_income_completed_text = ""

    payload = account_store().load_payload()
    for item in payload.get("dispatched_orders", []):
        if item.get("source_order_no") == order.get("source_order_no"):
            if settlement_method == "线上打款":
                item["wanyouji_online_payment_config_status"] = "ready"
            item["wanyouji_online_payment_config_verified_by"] = account.phone
            item["wanyouji_online_payment_app"] = str(config_result.get("selected_app", ""))
            item["wanyouji_online_payment_channel"] = str(config_result.get("selected_channel", ""))
            item["wanyouji_player_settlement_method"] = settlement_method
            item["wanyouji_player_settlement_completed_by"] = account.phone
            item["wanyouji_player_settlement_result"] = (
                "online_rejected_expected"
                if completion_result.get("expected_rejected")
                else "completed"
            )
            if not completion_result.get("expected_rejected"):
                item["status"] = "player_settlement_completed"
                if completion_result.get("settlement_total_amount"):
                    item["wanyouji_player_settlement_total_amount"] = str(
                        completion_result.get("settlement_total_amount")
                    )
                item["wanyouji_order_list_completed_verified_by"] = account.phone
                item["wanyouji_order_list_completed_text"] = completed_order_text[:500]
                item["player_income_settlement_completed_verified_by"] = player_account.phone
                item["player_income_settlement_completed_text"] = player_income_completed_text[:500]
    account_store().save_payload(payload)

    bug_reporter.record_if_errors(
        account=account.phone,
        location=(
            "B-SETTLE-WANYOUJI-PAY-001 丸友集-工作室基础应用-财务结算列表-"
            f"结算账单列表-完成结算-{settlement_method}：{order.get('source_order_no', '')}"
        ),
    )


def has_player_settlement_bill(text: str) -> bool:
    if re.search(r"\bBD\d{8,}\b", text):
        return True
    return "待审核" in text and "预计结算金额" in text and "查看" in text


def resolve_wanyouji_payout_account() -> tuple[E2EAccount, dict]:
    explicit_phone = os.getenv("E2E_SETTLE_WANYOUJI_PHONE", "").strip()
    store = account_store()
    accounts = store.load()
    payload = store.load_payload()
    orders = sorted(
        payload.get("dispatched_orders", []),
        key=lambda item: item.get("updated_at", item.get("created_at", "")),
        reverse=True,
    )
    preferred_statuses = {
        "settlement_bill_submitted",
        "player_settlement_bill_submitted",
        "settlement_verified",
        "income_verified",
        "delivery_accepted",
        "delivery_submitted",
    }

    for order in orders:
        if order.get("status") not in preferred_statuses:
            continue
        phones = [order.get("task_wanyouji_phone"), order.get("wanyouji_phone"), *(order.get("wanyouji_phones") or [])]
        for phone in phones:
            if not phone or (explicit_phone and phone != explicit_phone):
                continue
            account = next((item for item in accounts if item.phone == phone), None)
            if account:
                return account, order

    candidates = [
        account
        for account in accounts
        if account.account_type == "main"
        and account.wanyouji_status == "opened"
        and account.certification_status == "approved"
        and (not explicit_phone or account.phone == explicit_phone)
    ]
    candidates = sorted(candidates, key=lambda item: item.updated_at, reverse=True)
    assert candidates, "台账中未找到可用于B-SETTLE-WANYOUJI-PAY-001的丸友集主账号。"
    return candidates[0], {}


def resolve_player_account_for_payout(order: dict) -> E2EAccount:
    player_phone = (
        os.getenv("E2E_TASK_PLAYER_PHONE", "").strip()
        or os.getenv("E2E_PLAYER_PHONE", "").strip()
        or order.get("task_player_phone", "")
        or order.get("player_phone", "")
    )
    accounts = account_store().load()
    player = next((item for item in accounts if item.phone == player_phone), None)
    assert player is not None, (
        f"台账中未找到用于B-SETTLE-WANYOUJI-PAY-001收入回写校验的打手账号；"
        f"player_phone={player_phone}; source_order_no={order.get('source_order_no', '')}"
    )
    return player
