from wxautoz.utils import (
    FindWindow,
    SetClipboardText,
    ReadClipboardData,
    GetAllWindows,
)
from wxautoz.param import (
    WxParam, 
    WxResponse,
)
from wxautoz.languages import *
from .base import (
    BaseUISubWnd
)
from wxautoz.logger import wxlog
from wxautoz.uiautomation import (
    ControlFromHandle,
)
from wxautoz.utils.tools import (
    get_file_dir,
    roll_into_view,
)
from wxautoz import uiautomation as uia
import traceback
import shutil
import time

class EditBox:
    ...

class SelectContactWnd(BaseUISubWnd):
    """选择联系人窗口"""
    _ui_cls_name = 'SelectContactWnd'

    def __init__(self, parent):
        self.parent = parent
        self.root = parent.root
        hwnd = FindWindow(self._ui_cls_name, timeout=1)
        if hwnd:
            self.control = ControlFromHandle(hwnd)
        else:
            self.control = parent.root.control.PaneControl(ClassName=self._ui_cls_name, searchDepth=1)
        
        self.editbox = self.control.EditControl()

    def send(self, target):
        if isinstance(target, str):
            SetClipboardText(target)
            while not self.editbox.HasKeyboardFocus:
                self.editbox.Click()
                time.sleep(0.1)
            self.editbox.SendKeys('{Ctrl}a')
            self.editbox.SendKeys('{Ctrl}v')
            checkbox = self.control.ListControl().CheckBoxControl()
            if checkbox.Exists(1):
                checkbox.Click()
                self.control.ButtonControl(Name='发送').Click()
                return WxResponse.success()
            else:
                self.control.SendKeys('{Esc}')
                wxlog.debug(f'未找到好友：{target}')
                return WxResponse.failure(f'未找到好友：{target}')
            
        elif isinstance(target, list):
            n = 0
            fail = []
            multiselect = self.control.ButtonControl(Name='多选')
            if multiselect.Exists(0):
                multiselect.Click()
            for i in target:
                SetClipboardText(i)
                while not self.editbox.HasKeyboardFocus:
                    self.editbox.Click()
                    time.sleep(0.1)
                self.editbox.SendKeys('{Ctrl}a')
                self.editbox.SendKeys('{Ctrl}v')
                checkbox = self.control.ListControl().CheckBoxControl()
                if checkbox.Exists(1):
                    checkbox.Click()
                    n += 1
                else:
                    fail.append(i)
                    wxlog.debug(f"未找到转发对象：{i}")
            if n > 0:
                self.control.ButtonControl(RegexName='分别发送（\d+）').Click()
                if n == len(target):
                    return WxResponse.success()
                else:
                    return WxResponse.success('存在未转发成功名单', data=fail)
            else:
                self.control.SendKeys('{Esc}')
                wxlog.debug(f'所有好友均未未找到：{target}')
                return WxResponse.failure(f'所有好友均未未找到：{target}')
            

class CMenuWnd(BaseUISubWnd):
    _ui_cls_name = 'CMenuWnd'

    def __init__(self, parent):
        self.parent = parent
        self.root = parent.root
        if menulist := [i for i in GetAllWindows() if 'CMenuWnd' in i]:
            self.control = uia.ControlFromHandle(menulist[0][0])
        else:
            self.control = self.root.control.MenuControl(ClassName=self._ui_cls_name)
    
    def _lang(self, text: str) -> str:
        return MENU_OPTIONS.get(text, {WxParam.LANGUAGE: text}).get(WxParam.LANGUAGE)
    
    @property
    def option_controls(self):
        return self.control.ListControl().GetChildren()
    
    @property
    def option_names(self):
        return [c.Name for c in self.option_controls]
    
    def select(self, item):
        from wxautoz.ui.base import WXAUTO_BACKGROUND_MODE

        if not self.exists(0):
            return WxResponse.failure('菜单窗口不存在')
        if isinstance(item, int):
            if WXAUTO_BACKGROUND_MODE:
                self.option_controls[item].Click(move=False)
            else:
                self.option_controls[item].Click()
            return WxResponse.success()

        item = self._lang(item)
        for c in self.option_controls:
            if c.Name == item:
                if WXAUTO_BACKGROUND_MODE:
                    c.Click(move=False)
                else:
                    c.Click()
                return WxResponse.success()
        if self.exists(0):
            self.close()
        return WxResponse.failure(f'未找到选项：{item}')
    
    def close(self):
        try:
            self.control.SendKeys('{ESC}')
        except Exception as e:
            pass

class NetErrInfoTipsBarWnd(BaseUISubWnd):
    _ui_cls_name = 'NetErrInfoTipsBarWnd'

    def __init__(self, parent):
        self.control = parent.root.control.PaneControl(ClassName=self._ui_cls_name)

    def __bool__(self):
        return self.exists(0)
    

class WeChatImage(BaseUISubWnd):
    _ui_cls_name = 'ImagePreviewWnd'

    def __init__(self) -> None:
        self.hwnd = FindWindow(classname=self._ui_cls_name)
        if self.hwnd:
            self.control = ControlFromHandle(self.hwnd)
            self.type = 'image'
            if self.control.PaneControl(ClassName='ImagePreviewLayerWnd').Exists(0):
                self.type = 'video'
            MainControl1 = [i for i in self.control.GetChildren() if not i.ClassName][0]
            self.ToolsBox, self.PhotoBox = MainControl1.GetChildren()
            
            # tools按钮
            self.t_previous = self.ToolsBox.ButtonControl(Name=self._lang('上一张'))
            self.t_next = self.ToolsBox.ButtonControl(Name=self._lang('下一张'))
            self.t_zoom = self.ToolsBox.ButtonControl(Name=self._lang('放大'))
            self.t_translate = self.ToolsBox.ButtonControl(Name=self._lang('翻译'))
            self.t_ocr = self.ToolsBox.ButtonControl(Name=self._lang('提取文字'))
            self.t_save = self.control.ButtonControl(Name=self._lang('另存为...'))
            self.t_qrcode = self.ToolsBox.ButtonControl(Name=self._lang('识别图中二维码'))
    
    def _lang(self, text: str) -> str:
        return IMAGE_WINDOW.get(text, {WxParam.LANGUAGE: text}).get(WxParam.LANGUAGE)
    
    def ocr(self, wait=10):
        result = ''
        ctrls = self.PhotoBox.GetChildren()
        if len(ctrls) == 2:
            self.t_ocr.Click()
        t0 = time.time()
        while time.time() - t0 < wait:
            ctrls = self.PhotoBox.GetChildren()
            if len(ctrls) == 3:
                TranslateControl = ctrls[-1]
                result = TranslateControl.TextControl().Name
                if result:
                    return result
            else:
                self.t_ocr.Click()
            time.sleep(0.1)
        return result
    
    def save(self, dir_path=None, timeout=10):
        """保存图片/视频

        Args:
            dir_path (str): 绝对路径，包括文件名和后缀，例如："D:/Images/微信图片_xxxxxx.png"
            timeout (int, optional): 保存超时时间，默认10秒
        
        Returns:
            str: 文件保存路径，即savepath
        """
        if dir_path is None:
            dir_path = WxParam.DEFAULT_SAVE_PATH
        suffix = 'png' if self.type == 'image' else 'mp4'
        filename = f"wxautoz_{self.type}_{time.strftime('%Y%m%d%H%M%S')}.{suffix}"
        filepath = get_file_dir(dir_path) / filename
        t0 = time.time()

        SetClipboardText('')
        while True:
            if time.time() - t0 > timeout:
                if self.control.Exists(0):
                    self.control.SendKeys('{Esc}')
                raise TimeoutError('下载超时')
            try:
                self.control.ButtonControl(Name=self._lang('更多')).Click()
                menu = self.control.MenuControl(ClassName='CMenuWnd')
                menu.MenuItemControl(Name=self._lang('复制')).Click()
                clipboard_data = ReadClipboardData()
                path = clipboard_data['15'][0]
                wxlog.debug(f"读取到图片/视频路径：{path}")
                break
            except:
                wxlog.debug(traceback.format_exc())
                time.sleep(0.1)
        shutil.copyfile(path, filepath)
        SetClipboardText('')
        if self.control.Exists(0):
            wxlog.debug("关闭图片窗口")
            self.control.SendKeys('{Esc}')
        return filepath

class NewFriendElement:
    def __init__(self, control, parent):
        self.parent = parent
        self.root = parent.root
        self.control = control
        self.name = self.control.Name
        self.msg = self.control.GetFirstChildControl().PaneControl(SearchDepth=1).GetChildren()[-1].TextControl().Name
        self.NewFriendsBox = self.root.chatbox.control.ListControl(Name='新的朋友').GetParentControl()
        self.status = self.control.GetFirstChildControl().GetChildren()[-1]
        self.acceptable = isinstance(self.status, uia.ButtonControl)
            
    def __repr__(self) -> str:
        return f"<wxautoz New Friends Element at {hex(id(self))} ({self.name}: {self.msg})>"
    
    def delete(self):
        wxlog.info(f'删除好友请求: {self.name}')
        roll_into_view(self.NewFriendsBox, self.control)
        self.control.RightClick()
        menu = CMenuWnd(self.root)
        menu.select('删除')

    def reply(self, text):
        wxlog.debug(f'回复好友请求: {self.name}')
        roll_into_view(self.NewFriendsBox, self.control)
        self.control.Click()
        self.root.ChatBox.ButtonControl(Name='回复').Click()
        edit = self.root.ChatBox.EditControl()
        edit.Click()
        edit.SendKeys('{Ctrl}a')
        SetClipboardText(text)
        edit.SendKeys('{Ctrl}v')
        time.sleep(0.1)
        self.root.ChatBox.ButtonControl(Name='发送').Click()
        dialog = self.root.UiaAPI.PaneControl(ClassName='WeUIDialog')
        while edit.Exists(0):
            if dialog.Exists(0):
                systext = dialog.TextControl().Name
                wxlog.debug(f'系统提示: {systext}')
                dialog.SendKeys('{Esc}')
                self.root.ChatBox.ButtonControl(Name='').Click()
                return WxResponse.failure(msg=systext)
            time.sleep(0.1)
        self.root.ChatBox.ButtonControl(Name='').Click()
        return WxResponse.success()
    
    def accept(self, remark=None, tags=None, permission='朋友圈'):
        """接受好友请求
        
        Args:
            remark (str, optional): 备注名
            tags (list, optional): 标签列表
            permission (str, optional): 朋友圈权限, 可选值：'朋友圈', '仅聊天'
        """
        if not self.acceptable:
            wxlog.debug(f"当前好友状态无法接受好友请求：{self.name}")
            return 
        wxlog.debug(f"接受好友请求：{self.name}  备注：{remark} 标签：{tags}")
        self.root._show()
        roll_into_view(self.NewFriendsBox, self.status)
        self.status.Click()
        NewFriendsWnd = self.root.control.WindowControl(ClassName='WeUIDialog')
        tipscontrol = NewFriendsWnd.TextControl(Name="你的联系人较多，添加新的朋友时需选择权限")

        permission_sns = NewFriendsWnd.CheckBoxControl(Name='聊天、朋友圈、微信运动等')
        permission_chat = NewFriendsWnd.CheckBoxControl(Name='仅聊天')
        if tipscontrol.Exists(0.5):
            permission_sns = tipscontrol.GetParentControl().GetParentControl().TextControl(Name='朋友圈')
            permission_chat = tipscontrol.GetParentControl().GetParentControl().TextControl(Name='仅聊天')

        if remark:
            remarkedit = NewFriendsWnd.TextControl(Name='备注名').GetParentControl().EditControl()
            remarkedit.Click()
            remarkedit.SendKeys('{Ctrl}a')
            remarkedit.SendKeys(remark)
        
        if tags:
            tagedit = NewFriendsWnd.TextControl(Name='标签').GetParentControl().EditControl()
            for tag in tags:
                tagedit.Click()
                tagedit.SendKeys(tag)
                NewFriendsWnd.PaneControl(ClassName='DropdownWindow').TextControl().Click()

        if permission == '朋友圈':
            permission_sns.Click()
        elif permission == '仅聊天':
            permission_chat.Click()

        NewFriendsWnd.ButtonControl(Name='确定').Click()
