"""Element Plus Form 组件关键字"""

from playwright.sync_api import Page, Locator
from typing import Optional, Dict, List, Any

from ..base_keyword import BaseKeyword
from ...reference import INFO, set_element_value


class ElFormKeyword(BaseKeyword):
    """Element Plus Form 表单组件关键字

    处理表单验证、表单项操作、错误提示等。
    """

    def __init__(self, page: Page):
        super().__init__(page)

    def el_form_input(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        label: str = None
    ) -> None:
        """表单输入（可通过 label 定位）

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 输入内容
            label: 表单项 label（可选，用于定位）
        """
        INFO(f"表单输入: {content}")

        if label:
            # 通过 label 定位
            form_item = self.page.locator(f'.el-form-item:has(.el-form-item__label:text("{label}"))')
            input_el = form_item.locator('.el-input__inner, .el-textarea__inner')
        else:
            form_item = self.locator(targeting, element, index)
            input_el = form_item.locator('.el-input__inner, .el-textarea__inner')
            if input_el.count() == 0:
                input_el = form_item

        input_el.first.fill(str(content))

    def el_form_select(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        label: str = None
    ) -> None:
        """表单下拉选择

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 选项值
            label: 表单项 label
        """
        INFO(f"表单选择: {content}")

        if label:
            form_item = self.page.locator(f'.el-form-item:has(.el-form-item__label:text("{label}"))')
            select = form_item.locator('.el-select')
        else:
            form_item = self.locator(targeting, element, index)
            select = form_item.locator('.el-select')
            if select.count() == 0:
                select = form_item

        select.first.click()

        # 选择选项
        dropdown = self.page.locator('.el-select-dropdown:visible')
        dropdown.wait_for(state='visible', timeout=5000)
        option = dropdown.locator(f'.el-select-dropdown__item:has-text("{content}")')
        option.first.click()

    def el_form_date(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        label: str = None
    ) -> None:
        """表单日期选择

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 日期值
            label: 表单项 label
        """
        INFO(f"表单日期: {content}")

        if label:
            form_item = self.page.locator(f'.el-form-item:has(.el-form-item__label:text("{label}"))')
            date_picker = form_item.locator('.el-date-editor')
        else:
            form_item = self.locator(targeting, element, index)
            date_picker = form_item.locator('.el-date-editor')
            if date_picker.count() == 0:
                date_picker = form_item

        input_el = date_picker.first.locator('.el-input__inner')
        input_el.click()
        input_el.fill(str(content))
        input_el.press('Enter')

    def el_form_checkbox(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str = 'true',
        label: str = None
    ) -> None:
        """表单复选框

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 是否选中
            label: 表单项 label 或复选框文本
        """
        checked = str(content).lower() in ('true', '1', 'yes')
        INFO(f"表单复选框: {checked}")

        if label:
            # 先尝试作为复选框文本匹配
            checkbox = self.page.locator(f'.el-checkbox:has(.el-checkbox__label:text("{label}"))')
            if checkbox.count() == 0:
                # 再尝试作为表单项 label
                form_item = self.page.locator(f'.el-form-item:has(.el-form-item__label:text("{label}"))')
                checkbox = form_item.locator('.el-checkbox')
        else:
            form_item = self.locator(targeting, element, index)
            checkbox = form_item.locator('.el-checkbox')
            if checkbox.count() == 0:
                checkbox = form_item

        is_checked = checkbox.first.locator('.is-checked').count() > 0

        if checked != is_checked:
            checkbox.first.click()

    def el_form_radio(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        label: str = None
    ) -> None:
        """表单单选框

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 单选框文本或值
            label: 表单项 label
        """
        INFO(f"表单单选: {content}")

        if label:
            form_item = self.page.locator(f'.el-form-item:has(.el-form-item__label:text("{label}"))')
        else:
            form_item = self.locator(targeting, element, index)

        radio = form_item.locator(f'.el-radio:has(.el-radio__label:text("{content}"))')
        radio.first.click()

    def el_form_switch(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str = 'true',
        label: str = None
    ) -> None:
        """表单开关

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 开关状态
            label: 表单项 label
        """
        on = str(content).lower() in ('true', '1', 'yes', 'on')
        INFO(f"表单开关: {on}")

        if label:
            form_item = self.page.locator(f'.el-form-item:has(.el-form-item__label:text("{label}"))')
            switch = form_item.locator('.el-switch')
        else:
            form_item = self.locator(targeting, element, index)
            switch = form_item.locator('.el-switch')
            if switch.count() == 0:
                switch = form_item

        is_on = switch.first.locator('.is-checked').count() > 0

        if on != is_on:
            switch.first.click()

    def el_form_submit(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str = '提交'
    ) -> None:
        """提交表单

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 提交按钮文本
        """
        INFO(f"提交表单: {content}")

        form = self.locator(targeting, element, index)
        submit_btn = form.locator(f'.el-button:has-text("{content}")')

        if submit_btn.count() > 0:
            submit_btn.first.click()
        else:
            # 尝试提交按钮
            form.locator('.el-button--primary').first.click()

    def el_form_reset(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str = '重置'
    ) -> None:
        """重置表单

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 重置按钮文本
        """
        INFO(f"重置表单: {content}")

        form = self.locator(targeting, element, index)
        reset_btn = form.locator(f'.el-button:has-text("{content}")')

        if reset_btn.count() > 0:
            reset_btn.first.click()

    def el_form_get_error(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        label: str = None
    ) -> str:
        """获取表单项错误信息

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            label: 表单项 label

        Returns:
            str: 错误信息
        """
        if label:
            form_item = self.page.locator(f'.el-form-item:has(.el-form-item__label:text("{label}"))')
        else:
            form_item = self.locator(targeting, element, index)

        error = form_item.locator('.el-form-item__error')
        if error.is_visible():
            return error.text_content().strip()

        return ''

    def el_form_get_all_errors(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> List[str]:
        """获取所有表单错误信息

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引

        Returns:
            List[str]: 错误信息列表
        """
        form = self.locator(targeting, element, index)
        errors = form.locator('.el-form-item__error')

        result = []
        for i in range(errors.count()):
            text = errors.nth(i).text_content()
            if text:
                result.append(text.strip())

        INFO(f"表单错误: {result}")
        return result

    def el_form_assert_error(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        label: str = None,
        mode: str = 'equals'
    ) -> bool:
        """断言表单错误

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 期望的错误信息
            label: 表单项 label
            mode: 断言模式

        Returns:
            bool: 断言结果
        """
        actual = self.el_form_get_error(targeting, element, index, label=label)

        if mode == 'equals':
            result = actual == content
        elif mode == 'contains':
            result = content in actual
        elif mode == 'exists':
            result = len(actual) > 0
        else:
            result = actual == content

        INFO(f"表单错误断言: '{actual}' {mode} '{content}' -> {result}")
        return result

    def el_form_assert_no_error(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        label: str = None
    ) -> bool:
        """断言表单项无错误

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            label: 表单项 label

        Returns:
            bool: 断言结果
        """
        error = self.el_form_get_error(targeting, element, index, label=label)
        result = len(error) == 0

        INFO(f"无错误断言: {result}")
        return result

    def el_form_fill(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """批量填写表单

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: JSON 格式的表单数据 {"label1": "value1", "label2": "value2"}
        """
        import json
        data = json.loads(str(content))

        INFO(f"批量填写表单: {list(data.keys())}")

        for label, value in data.items():
            form_item = self.page.locator(f'.el-form-item:has(.el-form-item__label:text("{label}"))')

            if form_item.count() == 0:
                INFO(f"未找到表单项: {label}", "WARNING")
                continue

            # 判断表单项类型
            if form_item.locator('.el-select').count() > 0:
                # 下拉选择
                self.el_form_select('css', '.el-form-item', label=label, content=str(value))
            elif form_item.locator('.el-date-editor').count() > 0:
                # 日期选择
                self.el_form_date('css', '.el-form-item', label=label, content=str(value))
            elif form_item.locator('.el-switch').count() > 0:
                # 开关
                self.el_form_switch('css', '.el-form-item', label=label, content=str(value))
            elif form_item.locator('.el-checkbox').count() > 0:
                # 复选框
                self.el_form_checkbox('css', '.el-form-item', label=label, content=str(value))
            elif form_item.locator('.el-radio').count() > 0:
                # 单选框
                self.el_form_radio('css', '.el-form-item', label=label, content=str(value))
            else:
                # 默认输入框
                self.el_form_input('css', '.el-form-item', label=label, content=str(value))

            self.page.wait_for_timeout(100)
