// darkBidChecker.js
// 逻辑已迁移至项目内 Python：modules/dark_bid_format_check.py（本文件保留作参考）
// 依赖: jsdom (npm install jsdom)
const { JSDOM } = require('jsdom');

/**
 * 暗标格式检查器
 * @param {string} htmlContent - 技术暗标的HTML内容（由Word/PDF导出的完整HTML）
 * @param {Object} options - 可选配置
 * @returns {Object} 符合格式的JSON检查报告
 */
function checkTechnicalBid(htmlContent, options = {}) {
    const dom = new JSDOM(htmlContent);
    const document = dom.window.document;
    const styleSheets = Array.from(document.styleSheets);
    
    // 辅助函数：获取元素实际渲染样式（jsdom支持有限，但可获取内联和style标签定义）
    function getStyle(element, property) {
        return dom.window.getComputedStyle(element).getPropertyValue(property);
    }

    // 结果收集器
    const results = {
        overall: true,
        details: [],
        violations: []
    };

    // 通用添加结果方法
    function addResult(ruleName, passed, message, elements = []) {
        results.details.push({ rule: ruleName, passed, message });
        if (!passed) {
            results.overall = false;
            results.violations.push({ rule: ruleName, message, elements: elements.map(el => el.outerHTML.slice(0, 200)) });
        }
    }

    // ========== 1. 检查是否存在投标人身份信息 ==========
    function checkIdentityInfo() {
        const bodyText = document.body.innerText;
        // 公司名称模式（可扩展）
        const companyPattern = /(?:我公司|本公司|[（(]?[A-Za-z\u4e00-\u9fa5]+(?:集团|股份|有限|责任|公司)[）)]?)/g;
        // 地址模式（省市区路号等）
        const addrPattern = /(?:省|市|区|县|镇|路|街|大道|号|大厦|楼|层)[\u4e00-\u9fa50-9]+/g;
        // 总监/专监真实姓名模式（除甲、乙等代称外）
        const namePattern = /(?:总监理工程师|专业监理工程师|技术负责人|项目经理)[：:]\s*[^甲乙丙丁戊己庚辛壬癸\s]{2,4}(?=[，。；\s]|$)/g;
        
        let foundCompany = false;
        let foundAddr = false;
        let foundRealName = false;
        
        if (companyPattern.test(bodyText)) foundCompany = true;
        if (addrPattern.test(bodyText)) foundAddr = true;
        if (namePattern.test(bodyText)) foundRealName = true;
        
        // 检查图片alt或title是否包含公司标识
        const images = document.querySelectorAll('img');
        let hasLogo = false;
        images.forEach(img => {
            const alt = img.alt || '';
            const src = img.src || '';
            if (/logo|商标|微标|公司|品牌/i.test(alt) || /logo/i.test(src)) hasLogo = true;
        });
        
        const passed = !(foundCompany || foundAddr || foundRealName || hasLogo);
        addResult('身份信息隐藏', passed, 
            passed ? '未发现投标人身份信息' : '发现投标人身份信息（公司名/地址/真实姓名/商标）');
    }

    // ========== 2. 标题格式检查（三号黑体，非斜体，无下划线等） ==========
    function checkHeadings() {
        // 标题选择器：h1-h6 或任何 role="heading" 或具有大纲级别样式的元素
        const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6, [role="heading"], .heading, .title');
        let allValid = true;
        const invalidHeadings = [];
        
        headings.forEach(heading => {
            const fontSize = getStyle(heading, 'font-size');
            const fontFamily = getStyle(heading, 'font-family').toLowerCase();
            const fontStyle = getStyle(heading, 'font-style');
            const textDecoration = getStyle(heading, 'text-decoration');
            const color = getStyle(heading, 'color');
            const fontWeight = getStyle(heading, 'font-weight');
            
            // 三号 ≈ 16pt (21.33px) 允许误差 ±2px
            const sizeOk = Math.abs(parseFloat(fontSize) - 21.33) <= 3;
            const fontOk = fontFamily.includes('黑体') || fontFamily.includes('simhei') || fontFamily.includes('microsoft yahei');
            const styleOk = fontStyle !== 'italic';
            const decorOk = !textDecoration.includes('underline');
            const colorOk = color === 'rgb(0, 0, 0)' || color === '#000000';
            const weightOk = fontWeight !== '400' && fontWeight !== 'normal'; // 黑体通常加粗
            
            if (!(sizeOk && fontOk && styleOk && decorOk && colorOk && weightOk)) {
                allValid = false;
                invalidHeadings.push(heading);
            }
        });
        
        addResult('标题格式', allValid, 
            allValid ? '所有标题符合三号黑体要求' : '部分标题字号/字体/颜色/下划线不符合要求', invalidHeadings);
    }

    // ========== 3. 正文格式检查（四号宋体，首行缩进2字符，行距固定值26磅，无着色等） ==========
    function checkBodyText() {
        const bodyElements = document.querySelectorAll('p, div, span, li, td, th');
        let allValid = true;
        const invalidElements = [];
        // 排除标题、页眉页脚、目录等
        const excludeSelectors = 'h1, h2, h3, h4, h5, h6, .header, .footer, .toc, .目录';
        
        bodyElements.forEach(el => {
            if (el.matches(excludeSelectors)) return;
            const text = el.innerText.trim();
            if (text.length === 0) return;
            
            const fontSize = getStyle(el, 'font-size');
            const fontFamily = getStyle(el, 'font-family').toLowerCase();
            const color = getStyle(el, 'color');
            const textIndent = getStyle(el, 'text-indent');
            const lineHeight = getStyle(el, 'line-height');
            const textDecoration = getStyle(el, 'text-decoration');
            const fontWeight = getStyle(el, 'font-weight');
            const fontStyle = getStyle(el, 'font-style');
            
            // 四号 ≈ 14pt (18.67px)
            const sizeOk = Math.abs(parseFloat(fontSize) - 18.67) <= 2;
            const fontOk = fontFamily.includes('宋体') || fontFamily.includes('simsun') || fontFamily.includes('serif');
            const colorOk = color === 'rgb(0, 0, 0)' || color === '#000000';
            // 首行缩进2字符（以em为单位，2em代表2个汉字）
            const indentOk = parseFloat(textIndent) >= 1.8 && parseFloat(textIndent) <= 2.2;
            // 行距固定值26磅 (34.67px)
            const lineHeightOk = Math.abs(parseFloat(lineHeight) - 34.67) <= 2;
            const decorOk = !textDecoration.includes('underline');
            const weightOk = fontWeight === '400' || fontWeight === 'normal';
            const styleOk = fontStyle !== 'italic';
            
            if (!(sizeOk && fontOk && colorOk && indentOk && lineHeightOk && decorOk && weightOk && styleOk)) {
                allValid = false;
                invalidElements.push(el);
            }
        });
        
        addResult('正文格式', allValid,
            allValid ? '所有正文符合四号宋体/缩进/行距/颜色要求' : '部分正文段落格式不符合要求', invalidElements);
    }

    // ========== 4. 目录检查（无页码，无页眉页脚） ==========
    function checkTOC() {
        const tocElements = document.querySelectorAll('.toc, .table-of-contents, .目录, [role="directory"]');
        let noPageNumbers = true;
        let noHeaderFooter = true;
        
        tocElements.forEach(toc => {
            const text = toc.innerText;
            // 检查是否存在页码（数字独立在行尾或制表符后）
            if (/\d+$/.test(text.trim()) || /\.{2,}\s*\d+/.test(text)) {
                noPageNumbers = false;
            }
            // 检查内部是否有页眉页脚元素
            if (toc.querySelector('.header, .footer, .page-header, .page-footer')) {
                noHeaderFooter = false;
            }
        });
        
        // 若没有目录元素，按规则应存在目录但不得有页码，这里假设必须存在目录（招标要求通常有目录）
        if (tocElements.length === 0) {
            addResult('目录要求', false, '未检测到目录，请确保包含目录且目录无页码无页眉页脚');
        } else {
            const passed = noPageNumbers && noHeaderFooter;
            addResult('目录要求', passed,
                passed ? '目录符合无页码、无页眉页脚要求' : '目录中存在页码或页眉页脚');
        }
    }

    // ========== 5. 图表位置及图表内文字格式 ==========
    function checkChartsAndTables() {
        // 定位附件/附表章节
        const appendix = document.querySelector('#appendix, .appendix, .attachment, 附件, 附表');
        const isInAppendix = (el) => appendix && appendix.contains(el);
        
        const allTables = document.querySelectorAll('table');
        const allImages = document.querySelectorAll('img');
        const allFigures = document.querySelectorAll('figure, .chart');
        let illegalCharts = [];
        
        // 正文中不允许有图表，除非在附件内
        [...allTables, ...allImages, ...allFigures].forEach(chart => {
            if (!isInAppendix(chart)) {
                illegalCharts.push(chart);
            }
        });
        
        let chartTextValid = true;
        // 附件内图表文字需五号宋体
        if (appendix) {
            const chartTexts = appendix.querySelectorAll('table, td, th, figcaption, .chart-text');
            chartTexts.forEach(el => {
                const fontSize = getStyle(el, 'font-size');
                const fontFamily = getStyle(el, 'font-family').toLowerCase();
                const color = getStyle(el, 'color');
                const sizeOk = Math.abs(parseFloat(fontSize) - 10.5) <= 1.5; // 五号=10.5pt
                const fontOk = fontFamily.includes('宋体') || fontFamily.includes('simsun');
                const colorOk = color === 'rgb(0, 0, 0)' || color === '#000000';
                if (!(sizeOk && fontOk && colorOk)) chartTextValid = false;
            });
        }
        
        const chartsPassed = illegalCharts.length === 0 && chartTextValid;
        addResult('图表规范', chartsPassed,
            chartsPassed ? '图表仅出现在附件/附表内，且图表文字符合五号宋体' : 
            `正文中发现${illegalCharts.length}个图表或附件内图表文字格式错误`, illegalCharts);
    }

    // ========== 6. 全文字体颜色检查（无彩色，无着重号，无下划线） ==========
    function checkColorsAndDecorations() {
        const allElements = document.querySelectorAll('*');
        let colorViolations = [];
        let decorationViolations = [];
        
        allElements.forEach(el => {
            const color = getStyle(el, 'color');
            if (color !== 'rgb(0, 0, 0)' && color !== '#000000' && color !== 'black') {
                if (el.innerText.trim().length > 0) colorViolations.push(el);
            }
            const textDecor = getStyle(el, 'text-decoration');
            if (textDecor.includes('underline')) decorationViolations.push(el);
            // 着重号检测（一般使用伪元素或border-bottom，简单检测样式）
            const borderBottom = getStyle(el, 'border-bottom-style');
            if (borderBottom === 'solid' || borderBottom === 'dotted') {
                decorationViolations.push(el);
            }
        });
        
        const passed = colorViolations.length === 0 && decorationViolations.length === 0;
        addResult('颜色与装饰', passed,
            passed ? '无彩色文字、无下划线、无着重号' : 
            `发现${colorViolations.length}处彩色文字，${decorationViolations.length}处下划线/着重号`,
            [...colorViolations, ...decorationViolations]);
    }

    // ========== 7. 页面设置检查（A4纵向，页边距） ==========
    function checkPageSetup() {
        // 检查@page规则或根元素margin
        let pageValid = true;
        let marginTop, marginBottom, marginLeft, marginRight;
        // 尝试从styleSheets中获取@page
        let pageRule = null;
        for (let sheet of styleSheets) {
            try {
                const rules = sheet.cssRules || sheet.rules;
                for (let rule of rules) {
                    if (rule.type === CSSRule.PAGE_RULE) {
                        pageRule = rule.style;
                        break;
                    }
                }
            } catch(e) { /* 跨域限制忽略 */ }
        }
        
        if (pageRule) {
            marginTop = pageRule.marginTop;
            marginBottom = pageRule.marginBottom;
            marginLeft = pageRule.marginLeft;
            marginRight = pageRule.marginRight;
            const size = pageRule.size;
            if (size && size.toLowerCase() !== 'a4') pageValid = false;
        } else {
            // 检查body或根容器的margin
            const bodyStyle = getStyle(document.body, 'margin');
            if (bodyStyle) {
                const margins = bodyStyle.split(' ');
                // 简单近似
                marginTop = margins[0];
                marginBottom = margins[2] || margins[0];
                marginLeft = margins[3] || margins[1];
                marginRight = margins[1];
            } else {
                pageValid = false;
            }
        }
        
        const topOk = marginTop === '2.54cm' || parseFloat(marginTop) === 2.54;
        const bottomOk = marginBottom === '2.54cm' || parseFloat(marginBottom) === 2.54;
        const leftOk = marginLeft === '3.18cm' || parseFloat(marginLeft) === 3.18;
        const rightOk = marginRight === '3.18cm' || parseFloat(marginRight) === 3.18;
        const pageOrientation = document.documentElement.style.width === 'auto' ? '纵向' : '横向'; // 近似
        
        const passed = topOk && bottomOk && leftOk && rightOk && pageOrientation !== '横向';
        addResult('页面设置', passed,
            passed ? '页面设置符合A4纵向/边距要求' : '页面边距或纸张方向不符合要求');
    }

    // 执行所有检查
    checkIdentityInfo();
    checkHeadings();
    checkBodyText();
    checkTOC();
    checkChartsAndTables();
    checkColorsAndDecorations();
    checkPageSetup();
    
    return results;
}

// 导出函数供外部使用
module.exports = { checkTechnicalBid };

// ==================== 使用示例 ====================
// 假设已有htmlContent（技术暗标HTML字符串）
// const report = checkTechnicalBid(htmlContent);
// console.log(JSON.stringify(report, null, 2));