"""司机 APP 货运流程 Page Object — 货源→接单→装货→卸货→获取单号。

基于 resources/selectors/正常流程-司机.md 中的元素定位。
使用 Appium UiAutomator2 定位策略。
"""

from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from tests.app._base_page import AppBasePage


class DriverFreightFlowPage(AppBasePage):
    """司机端 APP - 货运完整流程（货源→接单→装货→卸货→获取单号）。"""

    def __init__(self, driver, platform: str = "android"):
        super().__init__(driver, platform)

        # ── 底部导航 ──
        # 0=首页, 1=货源, 2=消息, 3=我的
        self.freight_source_tab = (
            AppiumBy.ANDROID_UIAUTOMATOR,
            'new UiSelector().resourceId("com.arpa.ynchenggangdriver:id/fixed_bottom_navigation_icon").instance(1)',
        )

        # ── 货源单列表 ──
        self.freight_order_item = (
            AppiumBy.ANDROID_UIAUTOMATOR,
            'new UiSelector().className("android.widget.RelativeLayout").instance(3)',
        )

        # ── 数量 ──
        self.quantity_input = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/et_num")

        # ── 协议勾选 ──
        self.agreement_checkbox = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/check_xieyi")

        # ── 接单 ──
        self.accept_order_btn = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/tv_bian")

        # ── 系统弹窗取消 ──
        self.cancel_btn = (AppiumBy.ID, "android:id/button2")

        # ── 吨位 ──
        self.weight_input = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/et_dun")

        # ── 上传图片 ──
        self.select_image_btn = (
            AppiumBy.ANDROID_UIAUTOMATOR,
            'new UiSelector().className("android.widget.ImageView").instance(2)',
        )
        self.album_btn = (AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("相册")')
        self.image_checkbox = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/cb_check")
        self.done_btn = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/btn_ok")

        # ── 装货/卸货确认 ──
        self.load_unload_confirm = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/tv_nick")

        # ── 合同 ──
        self.contract_webview = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/textHtml")
        self.acknowledge_btn = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/tv_affirm")
        self.confirm_btn = (AppiumBy.ID, "com.arpa.ynchenggangdriver:id/ok_tv3")

    # ════════════════════════════════════════════════════════════
    # 基础操作封装
    # ════════════════════════════════════════════════════════════

    def _wait_and_click(self, locator, timeout_s: float = 10.0):
        wait = WebDriverWait(self.driver, timeout=timeout_s)
        wait.until(EC.visibility_of_element_located(locator))
        self.driver.find_element(*locator).click()

    def _wait_and_fill(self, locator, value: str, timeout_s: float = 10.0):
        wait = WebDriverWait(self.driver, timeout=timeout_s)
        wait.until(EC.visibility_of_element_located(locator))
        el = self.driver.find_element(*locator)
        el.clear()
        el.send_keys(value)

    def _tap_by_text(self, text: str, timeout_s: float = 10.0):
        locator = (AppiumBy.ANDROID_UIAUTOMATOR, f'new UiSelector().text("{text}")')
        self._wait_and_click(locator, timeout_s)

    def _safe_tap_by_text(self, text: str, timeout_s: float = 5.0):
        """容错点击：元素不存在时静默跳过。"""
        try:
            self._tap_by_text(text, timeout_s)
        except Exception:
            pass

    def _swipe_up(self, locator=None, duration_ms: int = 800):
        """向上滑动。指定 locator 时在元素内滑动，否则全屏滑动。"""
        if locator:
            try:
                wait = WebDriverWait(self.driver, timeout=5.0)
                el = wait.until(EC.presence_of_element_located(locator))
                size = el.size
                loc = el.location
                start_x = loc["x"] + size["width"] // 2
                start_y = loc["y"] + int(size["height"] * 0.8)
                end_y = loc["y"] + int(size["height"] * 0.2)
                self.driver.swipe(start_x, start_y, start_x, end_y, duration_ms)
                return
            except Exception:
                pass
        # 全屏滑动
        size = self.driver.get_window_size()
        self.driver.swipe(
            start_x=size["width"] // 2,
            start_y=int(size["height"] * 0.7),
            end_x=size["width"] // 2,
            end_y=int(size["height"] * 0.3),
            duration=duration_ms,
        )

    # ════════════════════════════════════════════════════════════
    # 接单流程 (步骤 1-5)
    # ════════════════════════════════════════════════════════════

    def accept_order_flow(self, quantity: str = "1"):
        """接单完整流程：货源 tab → 货源单 → 数量 → 协议 → 接单。"""
        self._wait_and_click(self.freight_source_tab)     # ① 点击货源
        self.driver.implicitly_wait(1)
        self._wait_and_click(self.freight_order_item)      # ② 点击货源单
        self.driver.implicitly_wait(2)
        self._wait_and_fill(self.quantity_input, quantity) # ③ 填写数量
        self._wait_and_click(self.agreement_checkbox)      # ④ 勾选协议
        self._wait_and_click(self.accept_order_btn)        # ⑤ 接单
        self.driver.implicitly_wait(2)

    # ════════════════════════════════════════════════════════════
    # 装货流程 (步骤 6-17)
    # ════════════════════════════════════════════════════════════

    def load_goods_flow(self, weight: str = "10"):
        """装货完整流程。"""
        self._tap_by_text("装货")                           # ⑥ 点击装货
        self.driver.implicitly_wait(1)
        self._wait_and_click(self.cancel_btn)               # ⑦ 点击取消（系统弹窗）
        self.driver.implicitly_wait(1)
        self._wait_and_fill(self.weight_input, weight)      # ⑧ 输入吨位
        self._wait_and_click(self.select_image_btn)         # ⑨ 选择图片
        self.driver.implicitly_wait(1)
        self._wait_and_click(self.album_btn)                # ⑩ 相册
        self.driver.implicitly_wait(1)
        self._wait_and_click(self.image_checkbox)           # ⑪ 勾选图片
        self._wait_and_click(self.done_btn)                 # ⑫ 完成
        self.driver.implicitly_wait(2)
        self._wait_and_click(self.agreement_checkbox)       # ⑬ 勾选协议
        self._wait_and_click(self.load_unload_confirm)      # ⑭ 装货确认
        self.driver.implicitly_wait(1)
        self._swipe_up(self.contract_webview)               # ⑮ 滑动合同
        self.driver.implicitly_wait(1)
        self._safe_tap_by_text("已知晓", timeout_s=5.0)     # ⑯ 已知晓（容错）
        self._safe_tap_by_text("确定", timeout_s=5.0)       # ⑰ 确定（容错）
        self.driver.implicitly_wait(2)

    # ════════════════════════════════════════════════════════════
    # 卸货流程 (步骤 19-27)
    # ════════════════════════════════════════════════════════════

    def unload_goods_flow(self, weight: str = "10"):
        """卸货完整流程。"""
        self._tap_by_text("卸货")                           # ⑲ 点击卸货
        self.driver.implicitly_wait(1)
        self._wait_and_click(self.cancel_btn)               # ⑳ 点击取消（系统弹窗）
        self.driver.implicitly_wait(1)
        self._wait_and_fill(self.weight_input, weight)      # ㉑ 输入吨位
        self._wait_and_click(self.select_image_btn)         # ㉒ 选择图片
        self.driver.implicitly_wait(1)
        self._wait_and_click(self.album_btn)                # ㉓ 相册
        self.driver.implicitly_wait(1)
        self._wait_and_click(self.image_checkbox)           # ㉔ 勾选图片
        self._wait_and_click(self.done_btn)                 # ㉕ 完成
        self.driver.implicitly_wait(2)
        self._wait_and_click(self.load_unload_confirm)      # ㉖ 卸货确认
        self.driver.implicitly_wait(1)
        self._safe_tap_by_text("确定", timeout_s=5.0)       # ㉗ 确定（容错）
        self.driver.implicitly_wait(2)

    # ════════════════════════════════════════════════════════════
    # 获取单号 (步骤 28)
    # ════════════════════════════════════════════════════════════

    def get_transport_order_no(self, timeout_s: float = 10.0) -> str:
        """获取运输单号。从"运输单号：RHJC..."中正则提取纯单号。"""
        import re

        locator = (
            AppiumBy.ANDROID_UIAUTOMATOR,
            'new UiSelector().textContains("运输单号")',
        )
        wait = WebDriverWait(self.driver, timeout=timeout_s)
        el = wait.until(EC.visibility_of_element_located(locator))
        full_text = el.text
        match = re.search(r"RHJC\S+", full_text)
        if match:
            return match.group()
        return full_text.replace("运输单号：", "").replace("运输单号:", "").strip()

    # ════════════════════════════════════════════════════════════
    # 全流程
    # ════════════════════════════════════════════════════════════

    def full_driver_flow(self, quantity: str = "1", load_weight: str = "10",
                         unload_weight: str = "10") -> str:
        """执行完整司机端流程：接单→装货→卸货→返回运输单号。"""
        self.accept_order_flow(quantity)
        self.load_goods_flow(load_weight)
        self.unload_goods_flow(unload_weight)
        return self.get_transport_order_no()
