from __future__ import annotations

import os
import random
from datetime import datetime

import pytest
from playwright.sync_api import Page

from e2e.pages.wanzhanggui_order_page import ManualOrderData, WanyoujiFulfillmentPage, WanzhangguiOrderPage
from e2e.utils.account_store import E2EAccount, account_store


@pytest.mark.e2e_order_001
@pytest.mark.e2e_ledger
@pytest.mark.e2e_chain
def test_丸掌柜手工录单发单并在丸友集抢单大厅验证闭环(page: Page, settings, bug_reporter) -> None:
    wanzhanggui_phone = os.getenv("E2E_ORDER_WANZHANGGUI_PHONE", "19147509308")
    wanzhanggui_password = os.getenv("E2E_ORDER_WANZHANGGUI_PASSWORD", "test123456")
    order_mode = os.getenv("E2E_ORDER_MODE", "手工录单")
    strategy_type = os.getenv("E2E_ORDER_STRATEGY_TYPE", "单平台指定")
    assert order_mode in {"手工录单", "批量录单"}, f"E2E_ORDER_MODE 暂仅支持手工录单/批量录单，当前值：{order_mode}"
    assert order_mode == "手工录单", "批量录单后续实现，当前脚本先覆盖手工录单闭环"
    assert strategy_type in {"单平台指定", "多工作室同时分发", "多平台分发"}, (
        "E2E_ORDER_STRATEGY_TYPE 仅支持：单平台指定、多工作室同时分发、多平台分发，"
        f"当前值：{strategy_type}"
    )

    store = account_store()
    wanzhanggui_account = store.find(phone=wanzhanggui_phone)
    assert wanzhanggui_account is not None, f"台账中未找到丸掌柜账号 {wanzhanggui_phone}"
    assert wanzhanggui_account.wanzhanggui_status == "opened", (
        f"账号 {wanzhanggui_phone} 未处于已开通丸掌柜状态，当前状态：{wanzhanggui_account.wanzhanggui_status}"
    )

    required_count = 1 if strategy_type == "单平台指定" else 2
    strategy_name = latest_strategy_name_for_type(wanzhanggui_phone, strategy_type)
    wanyouji_accounts = find_accounts_with_dispatch_strategy_name(
        wanzhanggui_phone,
        strategy_type,
        strategy_name,
        required_count,
    )
    if len(wanyouji_accounts) < required_count:
        pytest.skip(
            f"{strategy_type} 录单发单闭环至少需要 {required_count} 个已配置该策略的丸友集账号，"
            f"当前仅找到 {len(wanyouji_accounts)} 个。请先执行 E2E-PUSH-003 生成对应策略。"
        )

    timestamp = datetime.now().strftime("%m%d%H%M%S")
    source_order_no = f"E2EORDER{timestamp}"
    order_title = f"E2E手工录单{timestamp}"
    receive_price = manual_order_receive_price()
    dispatch_price = str(max(1, int(receive_price) - 10))
    order = ManualOrderData(
        source_order_no=source_order_no,
        order_title=order_title,
        strategy_name=strategy_name,
        strategy_type=strategy_type,
        receive_price=receive_price,
        dispatch_price=dispatch_price,
        role_name=f"E2E角色{timestamp[-4:]}",
    )

    order_page = WanzhangguiOrderPage(page, settings.tenant_home_url, bug_reporter)
    order_page.login_main_account(wanzhanggui_phone, wanzhanggui_password)
    bug_reporter.record_if_errors(account=wanzhanggui_phone, location="丸掌柜账号-主账号登录")
    order_page.create_manual_order(order)
    bug_reporter.record_if_errors(
        account=wanzhanggui_phone,
        location=f"丸掌柜-商家管理-订单管理-手工录单-提交订单：{source_order_no}/{strategy_name}",
    )

    expected_scope = "私单" if strategy_type == "单平台指定" else "公池单/私单"
    accounts_to_verify = wanyouji_accounts[:required_count]
    for wanyouji_account in accounts_to_verify:
        fulfillment_page = WanyoujiFulfillmentPage(page, settings.tenant_home_url, bug_reporter)
        fulfillment_page.login_main_account(wanyouji_account.phone, wanyouji_account.password)
        bug_reporter.record_if_errors(account=wanyouji_account.phone, location="丸友集账号-主账号登录")
        fulfillment_page.verify_order_reached_hall(source_order_no, order_title, expected_scope)
        bug_reporter.record_if_errors(
            account=wanyouji_account.phone,
            location=(
                "丸友集-工作室履约应用-抢单大厅-"
                f"验证{expected_scope}收到订单：{source_order_no}/{order_title}"
            ),
        )

    store.mark_order_dispatched(
        wanzhanggui_phone=wanzhanggui_phone,
        source_order_no=source_order_no,
        order_title=order_title,
        strategy_name=strategy_name,
        strategy_type=strategy_type,
        wanyouji_phones=[account.phone for account in accounts_to_verify],
    )


def find_accounts_with_dispatch_strategy_name(
    wanzhanggui_phone: str,
    strategy_type: str,
    strategy_name: str,
    count: int,
) -> list[E2EAccount]:
    matched: list[E2EAccount] = []
    accounts = sorted(account_store().load(), key=lambda account: account.updated_at, reverse=True)
    for account in accounts:
        if account.certification_status != "approved" or account.wanyouji_status != "opened":
            continue
        has_strategy = any(
            item.get("wanzhanggui_phone") == wanzhanggui_phone
            and item.get("strategy_type") == strategy_type
            and item.get("strategy_name") == strategy_name
            and item.get("status") == "created"
            for item in account.dispatch_strategies
        )
        if not has_strategy:
            continue
        matched.append(account)
        if len(matched) >= count:
            return matched
    return matched


def latest_strategy_name_for_type(wanzhanggui_phone: str, strategy_type: str) -> str:
    candidates: list[tuple[str, str]] = []
    for account in account_store().load():
        for item in account.dispatch_strategies:
            if (
                item.get("wanzhanggui_phone") == wanzhanggui_phone
                and item.get("strategy_type") == strategy_type
                and item.get("status") == "created"
            ):
                candidates.append((item.get("created_at", account.updated_at), item["strategy_name"]))
    if not candidates:
        raise AssertionError(f"台账中未找到 {strategy_type} 的策略名称")
    return sorted(candidates, key=lambda item: item[0], reverse=True)[0][1]


def manual_order_receive_price() -> str:
    explicit = os.getenv("E2E_MANUAL_ORDER_RECEIVE_PRICE", "").strip()
    if explicit:
        value = int(explicit)
        assert 50 <= value <= 300, f"E2E_MANUAL_ORDER_RECEIVE_PRICE must be between 50 and 300, got {value}"
        return str(value)
    return str(random.randint(50, 300))
