from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout
from qfluentwidgets import (
    BodyLabel, CheckBox, SubtitleLabel, PushButton, FluentIcon,
    InfoBar, InfoBarPosition, CardWidget, TitleLabel
)
from PyQt5.QtCore import Qt
from app.tools.code_generator import CodeGenerator
import os
import shutil
import csv


def get_module_page(module_type, subtype, project_path, parent=None):
    """获取模块配置页面"""
    return ModulePage(module_type, subtype, project_path, parent)


class ModulePage(QWidget):
    """单个模块配置页面"""
    
    def __init__(self, module_type, subtype, project_path, parent=None):
        super().__init__(parent)
        self.module_type = module_type
        self.subtype = subtype
        self.project_path = project_path
        
        # 获取模块路径
        module_dir = CodeGenerator.get_assets_dir("User_code/module")
        if subtype:
            self.module_path = os.path.join(module_dir, module_type, subtype)
            self.module_key = module_type  # 使用类型名作为目标文件夹
        else:
            self.module_path = os.path.join(module_dir, module_type)
            self.module_key = module_type
        
        # 加载描述
        self.descriptions = self._load_descriptions()
        
        self._init_ui()
        self._check_generated_status()
    
    def _load_descriptions(self):
        """从 describe.csv 加载模块描述"""
        descriptions = {}
        describe_path = os.path.join(
            CodeGenerator.get_assets_dir("User_code/module"),
            "describe.csv"
        )
        
        if os.path.exists(describe_path):
            try:
                with open(describe_path, 'r', encoding='utf-8') as f:
                    reader = csv.DictReader(f)
                    for row in reader:
                        module_name = row.get('module_name', '').strip()
                        description = row.get('description', '').strip()
                        if module_name and description:
                            descriptions[module_name] = description
            except Exception as e:
                print(f"读取模块描述失败: {e}")
        
        return descriptions
    
    def _init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout(self)
        layout.setSpacing(16)
        layout.setContentsMargins(48, 48, 48, 48)
        
        # 标题
        if self.subtype:
            title_text = f"{self.module_type} / {self.subtype}"
        else:
            title_text = self.module_type
        
        title = TitleLabel(title_text)
        title.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(title)
        
        # 描述
        desc_text = self.descriptions.get(self.module_key, "模块功能说明")
        desc = BodyLabel(desc_text)
        desc.setWordWrap(True)
        desc.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(desc)
        
        layout.addSpacing(24)
        
        # 文件列表卡片
        files_card = CardWidget()
        files_layout = QVBoxLayout(files_card)
        files_layout.setContentsMargins(16, 16, 16, 16)
        
        files_title = SubtitleLabel("包含文件")
        files_layout.addWidget(files_title)
        
        files = self._get_module_files()
        if files:
            for file in files:
                file_label = BodyLabel(f"• {file}")
                files_layout.addWidget(file_label)
        else:
            files_layout.addWidget(BodyLabel("未找到文件"))
        
        layout.addWidget(files_card)
        
        # 状态显示
        self.status_label = BodyLabel()
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(self.status_label)
        
        layout.addSpacing(24)
        
        # 按钮
        btn_layout = QHBoxLayout()
        btn_layout.addStretch()
        
        self.generate_btn = PushButton(FluentIcon.SAVE, "生成模块代码")
        self.generate_btn.clicked.connect(self._generate_code)
        btn_layout.addWidget(self.generate_btn)
        
        btn_layout.addStretch()
        layout.addLayout(btn_layout)
        
        layout.addStretch()
    
    def _get_module_files(self):
        """获取模块文件列表"""
        files = []
        try:
            if os.path.exists(self.module_path):
                for item in os.listdir(self.module_path):
                    if item.endswith(('.c', '.h')):
                        files.append(item)
        except Exception as e:
            print(f"读取模块文件失败: {e}")
        
        return sorted(files)
    
    def _check_generated_status(self):
        """检查模块是否已生成"""
        dst_dir = os.path.join(self.project_path, "User/module", self.module_key)
        
        if os.path.exists(dst_dir):
            has_code = any(
                f.endswith(('.c', '.h'))
                for f in os.listdir(dst_dir)
                if os.path.isfile(os.path.join(dst_dir, f))
            )
            if has_code:
                self.status_label.setText("✓ 模块已生成")
                self.status_label.setStyleSheet("color: green; font-weight: bold;")
                self.generate_btn.setEnabled(False)
                return
        
        self.status_label.setText("○ 模块未生成")
        self.status_label.setStyleSheet("color: orange;")
    
    def _generate_code(self):
        """生成模块代码"""
        try:
            # 首先生成 config（如果不存在）
            self._generate_config()
            
            # 目标目录：展平到 User/module/{module_key}
            dst_dir = os.path.join(self.project_path, "User/module", self.module_key)
            
            # 检查是否已存在
            if os.path.exists(dst_dir):
                has_code = any(
                    f.endswith(('.c', '.h'))
                    for f in os.listdir(dst_dir)
                    if os.path.isfile(os.path.join(dst_dir, f))
                )
                if has_code:
                    InfoBar.warning(
                        title="已存在",
                        content="模块代码已存在，不会覆盖",
                        orient=Qt.Horizontal,
                        isClosable=True,
                        position=InfoBarPosition.TOP,
                        duration=2000,
                        parent=self
                    )
                    return
            
            # 创建目录
            os.makedirs(dst_dir, exist_ok=True)
            
            # 复制所有文件
            file_count = 0
            for item in os.listdir(self.module_path):
                src_file = os.path.join(self.module_path, item)
                dst_file = os.path.join(dst_dir, item)
                
                if os.path.isfile(src_file):
                    if os.path.exists(dst_file):
                        continue
                    shutil.copy2(src_file, dst_file)
                    file_count += 1
                    print(f"生成文件: {dst_file}")
            
            if file_count > 0:
                InfoBar.success(
                    title="生成成功",
                    content=f"已生成 {file_count} 个文件",
                    orient=Qt.Horizontal,
                    isClosable=True,
                    position=InfoBarPosition.TOP,
                    duration=2000,
                    parent=self
                )
                self._check_generated_status()
            else:
                InfoBar.warning(
                    title="无需生成",
                    content="所有文件已存在",
                    orient=Qt.Horizontal,
                    isClosable=True,
                    position=InfoBarPosition.TOP,
                    duration=2000,
                    parent=self
                )
            
        except Exception as e:
            print(f"生成模块失败: {e}")
            InfoBar.error(
                title="生成失败",
                content=str(e),
                orient=Qt.Horizontal,
                isClosable=True,
                position=InfoBarPosition.TOP,
                duration=3000,
                parent=self
            )
    
    def _generate_config(self):
        """生成 config 文件（如果不存在）"""
        config_dir = os.path.join(self.project_path, "User/module")
        config_c = os.path.join(config_dir, "config.c")
        config_h = os.path.join(config_dir, "config.h")
        
        os.makedirs(config_dir, exist_ok=True)
        
        template_dir = CodeGenerator.get_assets_dir("User_code/module")
        template_c = os.path.join(template_dir, "config.c")
        template_h = os.path.join(template_dir, "config.h")
        
        if not os.path.exists(config_c) and os.path.exists(template_c):
            shutil.copy2(template_c, config_c)
            print(f"生成 config.c")
        
        if not os.path.exists(config_h) and os.path.exists(template_h):
            shutil.copy2(template_h, config_h)
            print(f"生成 config.h")
