#  @line_count 300
"""多格式输出模块"""
import json
from pathlib import Path
from typing import List, Dict, Any, Optional
from datetime import datetime
try:
    from openpyxl import Workbook
    from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
    OPENPYXL_AVAILABLE = True
except ImportError:
    OPENPYXL_AVAILABLE = False


class OutputFormatter:
    """多格式输出格式化器"""
    
    def __init__(self, test_items: List[Dict[str, Any]], test_cases: List[Dict[str, Any]],
                 document_info: Optional[Dict[str, Any]] = None):
        """
        初始化输出格式化器
        
        Args:
            test_items: 测试项列表
            test_cases: 测试用例列表
            document_info: 文档信息
        """
        self.test_items = test_items
        self.test_cases = test_cases
        self.document_info = document_info or {}
    
    def to_json(self, output_path: Optional[str] = None) -> str:
        """
        输出为JSON格式
        
        Args:
            output_path: 输出文件路径，如果为None则返回JSON字符串
        
        Returns:
            JSON字符串或文件路径
        """
        data = {
            'document_info': self.document_info,
            'generation_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'summary': {
                'test_item_count': len(self.test_items),
                'test_case_count': len(self.test_cases)
            },
            'test_items': self.test_items,
            'test_cases': self.test_cases
        }
        
        json_str = json.dumps(data, ensure_ascii=False, indent=2)
        
        if output_path:
            output_path = Path(output_path)
            output_path.parent.mkdir(parents=True, exist_ok=True)
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(json_str)
            return str(output_path)
        
        return json_str
    
    def to_markdown(self, output_path: Optional[str] = None) -> str:
        """
        输出为Markdown格式
        
        Args:
            output_path: 输出文件路径，如果为None则返回Markdown字符串
        
        Returns:
            Markdown字符串或文件路径
        """
        lines = []
        
        # 标题和文档信息
        lines.append("# 测试项和测试用例文档\n")
        if self.document_info.get('title'):
            lines.append(f"**文档标题**: {self.document_info['title']}\n")
        if self.document_info.get('version'):
            lines.append(f"**版本**: {self.document_info['version']}\n")
        lines.append(f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        lines.append(f"**测试项数量**: {len(self.test_items)}\n")
        lines.append(f"**测试用例数量**: {len(self.test_cases)}\n")
        lines.append("\n---\n")
        
        # 按模块分组
        modules = {}
        for item in self.test_items:
            module_name = item.get('module_name', '未分类')
            if module_name not in modules:
                modules[module_name] = []
            modules[module_name].append(item)
        
        # 输出每个模块的测试项和测试用例
        for module_name, items in modules.items():
            lines.append(f"\n## {module_name}\n")
            
            for item in items:
                # 测试项
                lines.append(f"\n### {item.get('id', '')} {item.get('name', '')}\n")
                lines.append(f"- **测试类型**: {item.get('test_type', 'N/A')}")
                lines.append(f"- **优先级**: {item.get('priority', 'N/A')}")
                lines.append(f"- **测试目标**: {item.get('test_objective', 'N/A')}\n")
                
                # 该测试项下的测试用例
                item_cases = [case for case in self.test_cases 
                             if case.get('test_item_id') == item.get('id')]
                
                if item_cases:
                    lines.append("#### 测试用例\n")
                    for case in item_cases:
                        lines.append(f"\n**{case.get('id', '')} {case.get('name', '')}**\n")
                        lines.append(f"- **前置条件**: {case.get('preconditions', 'N/A')}")
                        lines.append(f"- **优先级**: {case.get('priority', 'N/A')}")
                        lines.append(f"- **测试类型**: {case.get('test_type', 'N/A')}\n")
                        
                        lines.append("**测试步骤**:\n")
                        for idx, step in enumerate(case.get('test_steps', []), 1):
                            lines.append(f"{idx}. {step}\n")
                        
                        lines.append(f"\n**预期结果**: {case.get('expected_result', 'N/A')}\n")
                        lines.append("---\n")
        
        markdown_str = '\n'.join(lines)
        
        if output_path:
            output_path = Path(output_path)
            output_path.parent.mkdir(parents=True, exist_ok=True)
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(markdown_str)
            return str(output_path)
        
        return markdown_str
    
    def to_excel(self, output_path: str) -> str:
        """
        输出为Excel格式
        
        Args:
            output_path: 输出文件路径
        
        Returns:
            文件路径
        """
        if not OPENPYXL_AVAILABLE:
            raise ImportError("openpyxl未安装，无法生成Excel文件。请运行: pip install openpyxl")
        
        wb = Workbook()
        
        # 删除默认工作表
        if 'Sheet' in wb.sheetnames:
            wb.remove(wb['Sheet'])
        
        # 创建测试项工作表
        self._create_test_items_sheet(wb)
        
        # 创建测试用例工作表
        self._create_test_cases_sheet(wb)
        
        # 创建摘要工作表
        self._create_summary_sheet(wb)
        
        # 保存文件
        output_path = Path(output_path)
        output_path.parent.mkdir(parents=True, exist_ok=True)
        wb.save(output_path)
        
        return str(output_path)
    
    def _create_test_items_sheet(self, wb: Workbook):
        """创建测试项工作表"""
        ws = wb.create_sheet("测试项", 0)
        
        # 表头
        headers = ['测试项ID', '测试项名称', '所属模块', '功能名称', '测试类型', '优先级', '测试目标']
        ws.append(headers)
        
        # 设置表头样式
        header_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
        header_font = Font(bold=True, color="FFFFFF")
        border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        for col in range(1, len(headers) + 1):
            cell = ws.cell(1, col)
            cell.fill = header_fill
            cell.font = header_font
            cell.border = border
            cell.alignment = Alignment(horizontal='center', vertical='center')
        
        # 数据行
        for item in self.test_items:
            row = [
                item.get('id', ''),
                item.get('name', ''),
                item.get('module_name', ''),
                item.get('function_name', ''),
                item.get('test_type', ''),
                item.get('priority', ''),
                item.get('test_objective', '')
            ]
            ws.append(row)
            
            # 设置边框
            for col in range(1, len(headers) + 1):
                ws.cell(ws.max_row, col).border = border
        
        # 调整列宽
        column_widths = [12, 30, 15, 15, 12, 8, 40]
        for col, width in enumerate(column_widths, 1):
            ws.column_dimensions[ws.cell(1, col).column_letter].width = width
        
        # 冻结首行
        ws.freeze_panes = 'A2'
    
    def _create_test_cases_sheet(self, wb: Workbook):
        """创建测试用例工作表"""
        ws = wb.create_sheet("测试用例", 1)
        
        # 表头
        headers = ['测试用例ID', '测试项ID', '测试用例名称', '所属模块', '前置条件', 
                  '测试步骤', '预期结果', '优先级', '测试类型']
        ws.append(headers)
        
        # 设置表头样式
        header_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
        header_font = Font(bold=True, color="FFFFFF")
        border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        for col in range(1, len(headers) + 1):
            cell = ws.cell(1, col)
            cell.fill = header_fill
            cell.font = header_font
            cell.border = border
            cell.alignment = Alignment(horizontal='center', vertical='center')
        
        # 数据行
        for case in self.test_cases:
            test_steps_str = '\n'.join([f"{idx}. {step}" for idx, step 
                                       in enumerate(case.get('test_steps', []), 1)])
            
            row = [
                case.get('id', ''),
                case.get('test_item_id', ''),
                case.get('name', ''),
                case.get('module_name', ''),
                case.get('preconditions', ''),
                test_steps_str,
                case.get('expected_result', ''),
                case.get('priority', ''),
                case.get('test_type', '')
            ]
            ws.append(row)
            
            # 设置边框和换行
            for col in range(1, len(headers) + 1):
                cell = ws.cell(ws.max_row, col)
                cell.border = border
                if col == 6:  # 测试步骤列
                    cell.alignment = Alignment(wrap_text=True, vertical='top')
                else:
                    cell.alignment = Alignment(vertical='top')
        
        # 调整列宽
        column_widths = [12, 12, 30, 15, 25, 40, 30, 8, 12]
        for col, width in enumerate(column_widths, 1):
            ws.column_dimensions[ws.cell(1, col).column_letter].width = width
        
        # 设置行高（为测试步骤列预留空间）
        for row in range(2, ws.max_row + 1):
            ws.row_dimensions[row].height = 60
        
        # 冻结首行
        ws.freeze_panes = 'A2'
    
    def _create_summary_sheet(self, wb: Workbook):
        """创建摘要工作表"""
        ws = wb.create_sheet("摘要", 2)
        
        # 文档信息
        if self.document_info.get('title'):
            ws.append(['文档标题', self.document_info['title']])
        if self.document_info.get('version'):
            ws.append(['版本', self.document_info['version']])
        ws.append(['生成时间', datetime.now().strftime('%Y-%m-%d %H:%M:%S')])
        ws.append([])
        
        # 统计信息
        ws.append(['统计项', '数量'])
        ws.append(['测试项总数', len(self.test_items)])
        ws.append(['测试用例总数', len(self.test_cases)])
        ws.append([])
        
        # 按模块统计
        ws.append(['模块', '测试项数量', '测试用例数量'])
        modules = {}
        for item in self.test_items:
            module_name = item.get('module_name', '未分类')
            if module_name not in modules:
                modules[module_name] = {'items': 0, 'cases': 0}
            modules[module_name]['items'] += 1
        
        for case in self.test_cases:
            module_name = case.get('module_name', '未分类')
            if module_name not in modules:
                modules[module_name] = {'items': 0, 'cases': 0}
            modules[module_name]['cases'] += 1
        
        for module_name, stats in modules.items():
            ws.append([module_name, stats['items'], stats['cases']])
        
        # 设置样式
        header_font = Font(bold=True)
        for row in ws.iter_rows(min_row=1, max_row=1):
            for cell in row:
                cell.font = header_font
        
        # 调整列宽
        ws.column_dimensions['A'].width = 20
        ws.column_dimensions['B'].width = 15
        ws.column_dimensions['C'].width = 15

