#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
@File    :   body_page.py
@Time    :   2024/11/12 08:14:19
@Author  :   dulip3ng 
@Version :   1.0
@Desc    :   None
'''

from playwright.sync_api import Page, Error
from pages.locator.body_page_locator import BodyPageLocator
from pages.base_page import BasePage
from common.field_type import FieldType

class BodyPage(BasePage):

    def change_sheet(self, sheet_name:str, order:int=1):
        """
        切换单据体页签
        :param sheet_name: 页面名称
        :param order: 可选参数，存在同名页签时指明第几个，从1开始
        :return: None
        """
        self.page.locator(BodyPageLocator.SHEET_ARGS_LOC % (sheet_name, order)).click()

    def click_button(self, button_name:str, sub_button_name:str=None):
        """
        点击单据体按钮或子按钮
        如：新增行

        **用法：**
        BodyPage.click_button("新增行")

        BodyPage.click_button("新增行", "复制行")

        :param button_name: 按钮名称
        :param sub_button_name: 可选参数，子按钮名称
        :return: None
        """
        if not sub_button_name:
            self.page.locator(BodyPageLocator.BUTTON_ARGS_LOC % button_name).click()
        else:
            self.page.locator(BodyPageLocator.BUTTON_ARROW_ARGS_LOC % button_name).hover()
            self.page.locator(BodyPageLocator.SUB_BUTTON_ARGS_LOC % sub_button_name).click()
        self._click_blank()

    def click_line(self, row:int):
        """
        选中单据体行（通过点击行序号）
        :param row: 行号，从1开始
        :return: None
        """
        self.page.locator(BodyPageLocator.ACTIVATE_FIELD_ARGS_LOC % ("序号", row-1, 1)).click()

    def _activate_field(self, field_name:str, row:int, order:int=1):
        """
        激活字段，单据体字段未激活状态时统一为span元素，无法识别字段类型，无法针对不同字段类型操作
        :param field_name: 字段名
        :param row: 行号，从1开始
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: None
        """
        self.page.locator(BodyPageLocator.ACTIVATE_FIELD_ARGS_LOC % (field_name, row-1, order)).click(force=True)

    def _set_text(self, field_name:str, value:str, row:int, order:int=1):
        """
        单据体文本字段赋值
        :param field_name: 字段名
        :param value: 字段值
        :param row: 行号
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: None
        """
        self._activate_field(field_name, row, order)
        self.page.locator(BodyPageLocator.TEXT_FIELD_ARGS_LOC % (field_name, row-1, order)).fill(value)
        self._click_blank()

    def _set_select(self, field_name:str, value:str, row:int, order:int=1):
        """
        单据体下拉列表字段赋值
        :param field_name: 字段名
        :param value: 选项值
        :param row: 行号
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: None
        """
        self.page.locator(BodyPageLocator.ACTIVATE_FIELD_ARGS_LOC % (field_name, row-1, order)).click()
        self.page.locator(BodyPageLocator.SELECT_ITEM_ARGS_LOC % value).click()
        self._click_blank()

    def _set_base(self, field_name:str, value:str, row:int, order:int=1):
        """
        单据体基础资料类型字段赋值
        :param field_name: 字段名
        :param value: 字段值
        :param row: 行号
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: None
        """
        self._activate_field(field_name, row, order)
        self.page.locator(BodyPageLocator.BASE_FIELD_ARGS_LOC % (field_name, row-1, order)).click()
        self.page.locator(BodyPageLocator.BASE_FIELD_ARGS_LOC % (field_name, row-1, order)).fill(value)
        self.page.locator(BodyPageLocator.BASE_FIELD_ARGS_LOC % (field_name, row-1, order)).press_sequentially(" ")
        self.page.locator(BodyPageLocator.BASE_ITEM_ARGS_LOC % value).click()
        self._click_blank()

    def set_value(self, field_name:str, value:str, row:int, order:int=1, field_type:FieldType = None):
        """
        单据体字段赋值统一方法，根据给定或自动识别的字段类型调用不同方法完成赋值

        **用法：**

        BodyPage.set_value("衬衣订单号", "26024021", 1)

        :param field_name: 字段名
        :param value: 字段值
        :param row: 行号
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :param field_type: 可选参数，字段类型，不填时自动识别
        :return: None
        """
        if not field_type:
            field_type = self._parse_field(field_name, order)

        match field_type:
            case FieldType.TEXT:
                self._set_text(field_name, value, row, order)
            case FieldType.SELECT:
                self._set_select(field_name, value, row, order)
            case FieldType.BASE:
                self._set_base(field_name, value, row, order)

    def _parse_field(self, field_name:str, order:int=1):
        """
        识别单据体字段类型
        :param field_name: 字段名
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: 字段类型
        """
        self._activate_field(field_name, 1, order)
        data_role = self.page.locator(BodyPageLocator.PARSE_FILED_ARGS_LOC % (field_name, 0, order)).get_attribute("data-role")
        self._click_blank()
        match data_role:
            case "kdbosf7":
                return FieldType.BASE
            case "dropdownlist":
                return FieldType.SELECT
            case "kdtextfield" | "kdnumberfield" | "datepicker" | "kdmultilang" | "datetimepicker":
                return FieldType.TEXT

    def get_row_count(self):
        """
        获取单据体总行数
        :return: 行数
        """
        return self.page.locator(BodyPageLocator.ROW_COUNT_LOC).inner_text()

    def get_value(self, field_name:str, row:int, order:int=1):
        """
        获取单据体字段值，不区分字段类型
        :param field_name: 字段名
        :param row: 行号
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: 字段值
        """
        return self.page.locator(BodyPageLocator.FIELD_VALUE_ARGS_LOC % (field_name, row-1, order)).inner_text()

    def set_checked(self, field_name:str, row:int):
        """
        勾选单据体复选框
        :param field_name: 字段名
        :param row: 行号
        :return: None
        """
        self.page.locator(BodyPageLocator.CHECKBOX_FIELD_ARGS_LOC % (field_name, row-1)).click()
        self._click_blank()

    def set_text_in_body_head(self, field_name:str, value:str):
        """
        单据体中单据头形式文本字段赋值
        如：销售订单->物料数据->面料规格
        :param field_name: 字段名
        :param value: 字段值
        :return: None
        """
        self.page.locator(BodyPageLocator.TEXT_FIELD_IN_BODY_HEAD_ARGS_LOC % field_name).fill(value)
        self._click_blank()

    def set_select_in_body_head(self, field_name:str, value:str):
        """
        单据体中单据头形式下拉列表字段赋值
        如：销售订单->物料数据->货主类型
        :param field_name: 字段名
        :param value: 选项值
        :return: None
        """
        self.page.locator(BodyPageLocator.SELECT_FIELD_IN_BODY_HEAD_ARGS_LOC % field_name).click()
        self.page.locator(BodyPageLocator.SELECT_ITEM_ARGS_LOC % value).click()
        self._click_blank()

    def set_base_in_body_head(self, field_name:str, value:str):
        """
        单据体中单据头形式基础资料字段赋值
        如：销售订单->物料数据->面料来源
        :param field_name: 字段名
        :param value: 选项值
        :return: None
        """
        self.page.locator(BodyPageLocator.BASE_FIELD_IN_BODY_HEAD_SPAN_ARGS_LOC % field_name).click()
        self.page.locator(BodyPageLocator.BASE_FIELD_IN_BODY_HEAD_ARGS_LOC % field_name).fill(value)
        self.page.locator(BodyPageLocator.BASE_FIELD_IN_BODY_HEAD_ARGS_LOC % field_name).press_sequentially(" ")
        self.page.locator(BodyPageLocator.BASE_ITEM_ARGS_LOC % value).click()
        self._click_blank()

    def get_text_in_body_head(self, field_name:str, order:int=1):
        """
        单据体中单据头形式文本字段取值
        如：销售订单->物料数据->面料规格
        :param field_name: 字段名
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: 字段值
        """
        # 字段值可能存在1. input中，2.span或其他元素中，目标元素不是input时input_value()方法报错，捕获并换为inner_text()获取
        try:
            return self.page.locator(BodyPageLocator.TEXT_VALUE_IN_BODY_HEAD_ARGS_LOC % (field_name, field_name, order)).input_value()
        except Error:
            return self.page.locator(BodyPageLocator.TEXT_VALUE_IN_BODY_HEAD_ARGS_LOC % (field_name, field_name, order)).inner_text()

    def get_select_in_body_head(self, field_name:str, order:int=1):
        """
        单据体中单据头形式下拉列表字段取值
        如：销售订单->物料数据->货主类型
        :param field_name: 字段名
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: 字段值
        """
        return self.page.locator(BodyPageLocator.SELECT_VALUE_IN_BODY_HEAD_ARGS_LOC % (field_name, order)).inner_text()

    def get_base_in_body_head(self, field_name:str, order:int=1):
        """
        单据体中单据头形式基础资料字段取值
        如：销售订单->物料数据->面料来源
        :param field_name: 字段名
        :param order: 可选参数，存在同名字段时指明第几个，从1开始
        :return: 字段值
        """
        return self.page.locator(BodyPageLocator.BASE_VALUE_IN_BODY_HEAD_ARGS_LOC % (field_name, order)).inner_text()




