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

from playwright.sync_api import Page, Locator, FileChooser
from typing import Optional, List
from pathlib import Path

from ..base_keyword import BaseKeyword
from ...reference import INFO


class ElUploadKeyword(BaseKeyword):
    """Element Plus Upload 上传组件关键字

    处理文件上传、拖拽上传、图片预览等操作。
    """

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

    def el_upload(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """文件上传

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 文件路径（多个文件用逗号分隔）
        """
        files = [f.strip() for f in str(content).split(',')]
        INFO(f"上传文件: {files}")

        upload = self.locator(targeting, element, index)

        # 找到隐藏的 input[type=file]
        file_input = upload.locator('input[type="file"]')

        if file_input.count() > 0:
            # 直接设置文件
            if len(files) == 1:
                file_input.set_input_files(files[0])
            else:
                file_input.set_input_files(files)
        else:
            # 通过 file chooser 处理
            with self.page.expect_file_chooser() as fc_info:
                upload.click()
            file_chooser = fc_info.value
            if len(files) == 1:
                file_chooser.set_files(files[0])
            else:
                file_chooser.set_files(files)

    def el_upload_drag(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str
    ) -> None:
        """拖拽上传

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 文件路径
        """
        INFO(f"拖拽上传: {content}")

        upload = self.locator(targeting, element, index)
        drag_area = upload.locator('.el-upload-dragger, .el-upload--drag')

        # 使用 Playwright 的文件拖拽 API
        file_input = upload.locator('input[type="file"]')
        if file_input.count() > 0:
            file_input.set_input_files(str(content))
        else:
            with self.page.expect_file_chooser() as fc_info:
                drag_area.click()
            fc_info.value.set_files(str(content))

    def el_upload_remove(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str = '0'
    ) -> None:
        """删除已上传文件

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 文件索引或文件名
        """
        INFO(f"删除上传文件: {content}")

        upload = self.locator(targeting, element, index)

        if content.isdigit():
            # 按索引删除
            file_index = int(content)
            file_items = upload.locator('.el-upload-list__item')
            if file_items.count() > file_index:
                item = file_items.nth(file_index)
                item.hover()
                delete_btn = item.locator('.el-upload-list__item-delete, .el-icon-delete')
                if delete_btn.is_visible():
                    delete_btn.click()
                else:
                    # 尝试点击关闭按钮
                    close_btn = item.locator('.el-icon-close')
                    if close_btn.is_visible():
                        close_btn.click()
        else:
            # 按文件名删除
            file_item = upload.locator(f'.el-upload-list__item:has-text("{content}")')
            if file_item.count() > 0:
                file_item.first.hover()
                delete_btn = file_item.first.locator('.el-upload-list__item-delete, .el-icon-delete, .el-icon-close')
                delete_btn.click()

    def el_upload_clear(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> None:
        """清除所有上传文件

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
        """
        INFO("清除所有上传文件")

        upload = self.locator(targeting, element, index)
        file_items = upload.locator('.el-upload-list__item')

        # 从后往前删除
        while file_items.count() > 0:
            item = file_items.last
            item.hover()
            self.page.wait_for_timeout(100)
            delete_btn = item.locator('.el-upload-list__item-delete, .el-icon-delete, .el-icon-close')
            if delete_btn.is_visible():
                delete_btn.click()
                self.page.wait_for_timeout(200)
            file_items = upload.locator('.el-upload-list__item')

    def el_upload_preview(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str = '0'
    ) -> None:
        """预览上传文件

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 文件索引
        """
        file_index = int(content)
        INFO(f"预览文件: {file_index}")

        upload = self.locator(targeting, element, index)
        file_items = upload.locator('.el-upload-list__item')

        if file_items.count() > file_index:
            item = file_items.nth(file_index)
            item.hover()
            preview_btn = item.locator('.el-upload-list__item-preview, .el-icon-zoom-in')
            if preview_btn.is_visible():
                preview_btn.click()
            else:
                # 直接点击图片
                item.locator('img').click()

    def el_upload_get_file_count(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> int:
        """获取已上传文件数量

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

        Returns:
            int: 文件数量
        """
        upload = self.locator(targeting, element, index)
        count = upload.locator('.el-upload-list__item').count()
        INFO(f"已上传文件数: {count}")
        return count

    def el_upload_get_file_names(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None
    ) -> List[str]:
        """获取已上传文件名列表

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

        Returns:
            List[str]: 文件名列表
        """
        upload = self.locator(targeting, element, index)
        file_items = upload.locator('.el-upload-list__item')

        names = []
        for i in range(file_items.count()):
            item = file_items.nth(i)
            name = item.locator('.el-upload-list__item-name').text_content()
            if name:
                names.append(name.strip())

        INFO(f"已上传文件: {names}")
        return names

    def el_upload_assert_count(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str,
        mode: str = 'equals'
    ) -> bool:
        """断言上传文件数量

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 期望数量
            mode: 断言模式

        Returns:
            bool: 断言结果
        """
        actual = self.el_upload_get_file_count(targeting, element, index)
        expected = int(content)

        mode_map = {
            'equals': actual == expected,
            'gt': actual > expected,
            'lt': actual < expected,
            'gte': actual >= expected,
            'lte': actual <= expected,
        }
        result = mode_map.get(mode, actual == expected)

        INFO(f"上传数量断言: {actual} {mode} {expected} -> {result}")
        return result

    def el_upload_wait_success(
        self,
        targeting: str,
        element: str,
        index: Optional[int] = None,
        *,
        content: str = '30000'
    ) -> None:
        """等待上传成功

        Args:
            targeting: 定位类型
            element: 定位表达式
            index: 索引
            content: 超时时间 (毫秒)
        """
        timeout = int(content)
        INFO("等待上传完成")

        upload = self.locator(targeting, element, index)

        # 等待进度消失
        progress = upload.locator('.el-upload-list__item-status-label .el-icon-loading, .el-progress')
        try:
            progress.wait_for(state='hidden', timeout=timeout)
        except Exception:
            pass

        # 等待成功状态
        success = upload.locator('.el-upload-list__item.is-success, .el-icon-check')
        try:
            success.wait_for(state='visible', timeout=5000)
        except Exception:
            pass
