import inspect
import os.path
import tkinter as tk
from tkinter import ttk
from .base_page import BasePage
from protocol import DeviceInfo, int_to_ip, ip_to_int, bytes_to_mac
from config import Cmd


class DeviceInfoPage(BasePage):
    def __init__(self, parent, tcp_client):
        super().__init__(parent, tcp_client, "设备信息")

        # 配置样式
        self.configure_styles()
        
        tcp_client.register_callback(Cmd.DEVICE_INFO_GET, self.on_data_received)
        tcp_client.register_callback(Cmd.DEVICE_INFO_SET, self.on_set_response)

        # self.create_widgets()

    def configure_styles(self):
        """配置界面样式"""
        style = ttk.Style()
        style.configure('Readonly.TEntry', 
                       fieldbackground='#f0f0f0',
                       foreground='#666666')
    
    def hex_to_int(self, hex_str):
        """将16进制字符串转换为整数"""
        try:
            hex_str = hex_str.strip().replace('0x', '').replace('0X', '')
            return int(hex_str, 16) if hex_str else 0
        except ValueError:
            return 0
    
    def int_to_hex(self, value):
        """将整数转换为16进制字符串"""
        return f"{value:X}"
    
    def format_date(self, date_int):
        """格式化日期"""
        if date_int == 0:
            return "未知"
        year = (date_int >> 16) & 0xFFFF
        month = (date_int >> 8) & 0xFF
        day = date_int & 0xFF
        return f"{year:04d}-{month:02d}-{day:02d}"
    
    def format_runtime(self, seconds):
        """格式化运行时间"""
        if seconds == 0:
            return "0秒"
        days = seconds // (24 * 3600)
        hours = (seconds % (24 * 3600)) // 3600
        minutes = (seconds % 3600) // 60
        secs = seconds % 60
        parts = []
        if days > 0:
            parts.append(f"{days}天")
        if hours > 0:
            parts.append(f"{hours}时")
        if minutes > 0:
            parts.append(f"{minutes}分")
        if secs > 0 or not parts:
            parts.append(f"{secs}秒")
        return "".join(parts)
    
    def bytes_to_string(self, byte_data):
        """字节数据转字符串"""
        try:
            return byte_data.decode('utf-8', errors='ignore').split('\x00')[0]
        except:
            return str(byte_data)
    
    def validate_hex_input(self, new_value):
        """验证16进制输入"""
        if not new_value:
            return True
        pattern = r'^(0[xX])?[0-9A-Fa-f]*$'
        return re.match(pattern, new_value) is not None
    
    def create_widgets(self):
        """创建界面控件"""
        print(f"file:{os.path.basename(__file__)} func:{inspect.currentframe().f_code.co_name}")
        super().create_widgets()
        
        # 创建两列框架
        main_frame = ttk.Frame(self)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
        
        left_frame = ttk.Frame(main_frame)
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 5))
        
        right_frame = ttk.Frame(main_frame)
        right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=(5, 0))
        
        # 定义所有字段
        self.fields = [
            # 左列 - 可编辑字段
            {"label": "主设备号", "attr": "type_m", "type": "spin", "args": (0, 255), "readonly": False},
            {"label": "次设备号", "attr": "type_s", "type": "spin", "args": (0, 255), "readonly": False},
            {"label": "设备ID", "attr": "dev_id", "type": "hex_entry", "readonly": False},
            {"label": "设备名", "attr": "hostname", "type": "entry", "readonly": False},
            {"label": "IP地址", "attr": "ip", "type": "entry", "readonly": False},
            {"label": "子网掩码", "attr": "mask", "type": "entry", "readonly": False},
            {"label": "网关", "attr": "gw", "type": "entry", "readonly": False},
            {"label": "后台端口", "attr": "csg_port", "type": "spin", "args": (1, 65535), "readonly": False},
            {"label": "后台IP", "attr": "csg_ipv4", "type": "entry", "readonly": False},
            
            # 右列 - 只读字段
            {"label": "MAC地址", "attr": "mac", "type": "entry", "readonly": True},
            {"label": "软件版本", "attr": "app_version", "type": "entry", "readonly": True},
            {"label": "编译时间", "attr": "app_compile_time", "type": "entry", "readonly": True},
            {"label": "硬件版本", "attr": "hardware_version", "type": "entry", "readonly": True},
            {"label": "FPGA版本", "attr": "fpga_version", "type": "entry", "readonly": True},
            {"label": "出厂日期", "attr": "factory_date", "type": "entry", "readonly": True},
            {"label": "部署日期", "attr": "deployment_date", "type": "entry", "readonly": True},
            {"label": "运行时间", "attr": "running_time", "type": "entry", "readonly": True}
        ]
        
        # 创建字段控件
        self.create_field_controls(left_frame, [f for f in self.fields if not f['readonly']])
        self.create_field_controls(right_frame, [f for f in self.fields if f['readonly']])
        
        # 创建按钮
        self.create_buttons()
    
    def create_field_controls(self, parent, fields):
        """创建字段控件"""
        for i, field in enumerate(fields):
            ttk.Label(parent, text=field["label"] + ":").grid(
                row=i, column=0, sticky='e', padx=2, pady=2)
            
            if field["type"] == "spin":
                var = tk.IntVar()
                spinbox = ttk.Spinbox(parent, from_=field["args"][0], to=field["args"][1], 
                                    textvariable=var, width=15)
                spinbox.grid(row=i, column=1, sticky='w', padx=2, pady=2)
                if field["readonly"]:
                    spinbox.configure(state='readonly', style='Readonly.TEntry')
                
            elif field["type"] == "hex_entry":
                var = tk.StringVar()
                entry = ttk.Entry(parent, textvariable=var, width=15)
                entry.grid(row=i, column=1, sticky='w', padx=2, pady=2)
                if not field["readonly"]:
                    entry.configure(validate="key", 
                                  validatecommand=(entry.register(self.validate_hex_input), '%P'))
                else:
                    entry.configure(state='readonly', style='Readonly.TEntry')
                
            else:
                var = tk.StringVar()
                entry = ttk.Entry(parent, textvariable=var, width=20)
                entry.grid(row=i, column=1, sticky='w', padx=2, pady=2)
                if field["readonly"]:
                    entry.configure(state='readonly', style='Readonly.TEntry')
            
            setattr(self, f"{field['attr']}_var", var)
    
    def create_buttons(self):
        """创建按钮"""
        btn_frame = ttk.Frame(self)
        btn_frame.pack(pady=10)
        
        ttk.Button(btn_frame, text="读取", command=self.read_data, width=10).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="设置", command=self.set_data, width=10).pack(side=tk.LEFT, padx=5)
    
    def read_data(self):
        """读取设备数据"""
        print(f"发送命令: {Cmd.DEVICE_INFO_GET}")
        if not self.tcp_client.connected:
            self.show_error("未连接设备")
            return
        self.tcp_client.send_packet(Cmd.DEVICE_INFO_GET)
    
    def set_data(self):
        """设置设备数据"""
        if not self.tcp_client.connected:
            self.show_error("未连接设备")
            return
        
        info = DeviceInfo()
        info.type_m = self.type_m_var.get()
        info.type_s = self.type_s_var.get()
        info.dev_id = self.hex_to_int(self.dev_id_var.get())
        info.hostname = self.hostname_var.get().encode().ljust(128, b'\x00')
        info.ip = ip_to_int(self.ip_var.get())
        info.mask = ip_to_int(self.mask_var.get())
        info.gw = ip_to_int(self.gw_var.get())
        info.csg_port = self.csg_port_var.get()
        info.csg_ipv4 = ip_to_int(self.csg_ipv4_var.get())
        
        self.tcp_client.send_packet(Cmd.DEVICE_INFO_SET, info.to_bytes())

    def on_data_received(self, header, body):
        """处理接收到的数据"""
        print(f"file:{os.path.basename(__file__)} func:{inspect.currentframe().f_code.co_name}")
        print(f"收到数据: 命令={header.cmd}, 数据长度={len(body)}")

        try:
            info = DeviceInfo.from_bytes(body)
            print(f"解析成功: dev_id={info.dev_id}, hostname={info.hostname}")

            self.type_m_var.set(info.type_m)
            self.type_s_var.set(info.type_s)
            self.dev_id_var.set(self.int_to_hex(info.dev_id))
            self.hostname_var.set(self.bytes_to_string(info.hostname))
            self.ip_var.set(int_to_ip(info.ip))
            self.mask_var.set(int_to_ip(info.mask))
            self.gw_var.set(int_to_ip(info.gw))
            self.csg_port_var.set(info.csg_port)
            self.csg_ipv4_var.set(int_to_ip(info.csg_ipv4))
            
            self.mac_var.set(bytes_to_mac(info.mac))
            self.app_version_var.set(self.bytes_to_string(info.app_version))
            self.app_compile_time_var.set(self.bytes_to_string(info.app_compile_time))
            self.hardware_version_var.set(self.bytes_to_string(info.hardware_version))
            self.fpga_version_var.set(self.bytes_to_string(info.fpga_version))
            self.factory_date_var.set(self.format_date(info.factory_date))
            self.deployment_date_var.set(self.format_date(info.deployment_date))
            self.running_time_var.set(self.format_runtime(info.running_time))
            
        except Exception as e:
            print(f"解析设备信息失败: {e}")
            self.show_error("解析设备信息失败")
    
    def on_set_response(self, header, body):
        """处理设置响应"""
        self.show_info("设备信息设置成功")