"""
Quality inspection rule definitions for PPT quality assurance.
Each rule defines a check function, severity level, and auto-fix strategy.
"""
from pptx.util import Emu, Pt
from dataclasses import dataclass, field
from typing import Callable, Optional


@dataclass
class QualityRule:
    rule_id: str
    category: str
    description: str
    severity: str
    auto_fixable: bool
    check_fn: str
    fix_fn: str


QUALITY_RULES = [
    QualityRule('L001', 'layout', '元素飞出页面左边界', 'critical', True, '_check_left_bounds', '_fix_left_bounds'),
    QualityRule('L002', 'layout', '元素飞出页面右边界', 'critical', True, '_check_right_bounds', '_fix_right_bounds'),
    QualityRule('L003', 'layout', '元素飞出页面顶部', 'critical', True, '_check_top_bounds', '_fix_top_bounds'),
    QualityRule('L004', 'layout', '元素飞出页面底部', 'critical', True, '_check_bottom_bounds', '_fix_bottom_bounds'),
    QualityRule('L005', 'layout', '图文重叠', 'critical', True, '_check_overlap', '_fix_overlap'),
    QualityRule('L006', 'layout', '占位符未替换', 'critical', True, '_check_placeholders', '_fix_placeholders'),
    QualityRule('L007', 'layout', '元素紧贴页面边缘', 'minor', True, '_check_edge_proximity', '_fix_edge_proximity'),

    QualityRule('V001', 'visual', '字体不一致', 'minor', True, '_check_font_consistency', '_fix_font_consistency'),
    QualityRule('V002', 'visual', '字号过小(<8pt)', 'major', True, '_check_font_too_small', '_fix_font_too_small'),
    QualityRule('V003', 'visual', '字号过大(>60pt)', 'major', True, '_check_font_too_large', '_fix_font_too_large'),
    QualityRule('V004', 'visual', '颜色对比度不足', 'major', True, '_check_contrast', '_fix_contrast'),
    QualityRule('V005', 'visual', '图片拉伸变形', 'major', True, '_check_image_aspect', '_fix_image_aspect'),

    QualityRule('C001', 'content', '页面留白过多(填充率<35%)', 'critical', True, '_check_sparse_page', '_fix_sparse_page'),
    QualityRule('C002', 'content', 'KPI卡片数值为空', 'critical', True, '_check_empty_kpi', '_fix_empty_kpi'),
    QualityRule('C003', 'content', '图表无数据', 'critical', True, '_check_empty_chart', '_fix_empty_chart'),
    QualityRule('C004', 'content', '文本截断溢出', 'major', True, '_check_text_overflow', '_fix_text_overflow'),
    QualityRule('C005', 'content', '分析文本过短(<100字)', 'critical', True, '_check_short_text', '_fix_short_text'),
    QualityRule('C006', 'content', '页面缺少标题', 'critical', True, '_check_missing_title', '_fix_missing_title'),
    QualityRule('C007', 'content', '分析段数不足', 'critical', True, '_check_insight_count', '_fix_insight_count'),
    QualityRule('C008', 'content', '页面内容为空(<50字)', 'critical', True, '_check_empty_page', '_fix_empty_page'),
    QualityRule('C009', 'content', '图表缺少分析文本', 'critical', True, '_check_chart_no_text', '_fix_chart_no_text'),

    QualityRule('D001', 'data', '图表数据与文本矛盾', 'critical', False, '_check_data_text_contradiction', None),
    QualityRule('D002', 'data', '页码错乱', 'major', True, '_check_page_numbers', '_fix_page_numbers'),
    QualityRule('D003', 'data', '数据来源缺失', 'major', True, '_check_missing_source', '_fix_missing_source'),
    QualityRule('D004', 'data', '表格列宽不合理', 'minor', True, '_check_table_column_width', '_fix_table_column_width'),
    QualityRule('D005', 'data', '图表刻度异常', 'minor', True, '_check_axis_scale', '_fix_axis_scale'),
]

QUALITY_RULES.extend([
    QualityRule('L008', 'layout', '空模板组件残留', 'major', True,
                '_check_empty_template_artifacts', '_fix_empty_template_artifacts'),
    QualityRule('C010', 'content', '动态页面与数据画像不匹配', 'critical', True,
                '_check_dynamic_page_fit', '_fix_rebuild_page'),
    QualityRule('C011', 'content', 'KPI布局容量不足', 'major', True,
                '_check_kpi_layout_capacity', '_fix_rebuild_page'),
    QualityRule('D006', 'data', '六项确认与输出不一致', 'critical', True,
                '_check_confirmation_alignment', '_fix_rebuild_page'),
])


SEVERITY_WEIGHTS = {
    'critical': 20,
    'major': 10,
    'minor': 3,
}

CATEGORY_WEIGHTS = {
    'layout': 0.30,
    'visual': 0.25,
    'content': 0.25,
    'data': 0.20,
}

FILL_RATIO_THRESHOLDS = {
    'sparse': 0.20,
    'low': 0.35,
    'acceptable': 0.55,
    'good': 0.70,
}

FONT_SIZE_MIN = Pt(8)
FONT_SIZE_MAX = Pt(60)
TEXT_MIN_LENGTH = 80
INSIGHT_MIN_COUNT = 2
PAGE_MIN_TEXT_LENGTH = 50
SAFE_MARGIN = Emu(762000)
CONTENT_LEFT = Emu(762000)
CONTENT_TOP_BASE = Emu(1524000)
FOOTER_TOP = Emu(8824000)
SLIDE_WIDTH = 16256000
SLIDE_HEIGHT = 9144000

DEFAULT_FONT = '微软雅黑'
DEFAULT_NUMBER_FONT = 'Arial'


def get_rules_by_category(category: str) -> list[QualityRule]:
    return [r for r in QUALITY_RULES if r.category == category]


def get_rules_by_severity(severity: str) -> list[QualityRule]:
    return [r for r in QUALITY_RULES if r.severity == severity]


def calculate_score(issues_by_severity: dict, issues_by_category: dict, total_pages: int) -> int:
    if total_pages <= 0:
        return 100

    penalty = 0
    for sev, count in issues_by_severity.items():
        weight = SEVERITY_WEIGHTS.get(sev, 5)
        penalty += count * weight

    per_page_penalty = min(penalty / total_pages, 80)
    score = max(0, 100 - per_page_penalty)
    return int(score)


def get_quality_label(score: int) -> str:
    if score >= 90:
        return '优质'
    elif score >= 75:
        return '良好'
    elif score >= 60:
        return '待改善'
    else:
        return '不合格'


if __name__ == '__main__':
    print(f"Loaded {len(QUALITY_RULES)} quality rules")
    for cat in ['layout', 'visual', 'content', 'data']:
        rules = get_rules_by_category(cat)
        print(f"  {cat}: {len(rules)} rules")
    for sev in ['critical', 'major', 'minor']:
        rules = get_rules_by_severity(sev)
        print(f"  {sev}: {len(rules)} rules")
