import os
import re
from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml import OxmlElement, parse_xml
from docx.oxml.ns import nsdecls, qn

def set_cell_background(cell, color_hex):
    tcPr = cell._tc.get_or_add_tcPr()
    shd = parse_xml(f'<w:shd {nsdecls("w")} w:fill="{color_hex}"/>')
    tcPr.append(shd)

def set_cell_margins(cell, top=100, bottom=100, left=150, right=150):
    tcPr = cell._tc.get_or_add_tcPr()
    tcMar = OxmlElement('w:tcMar')
    for m, val in [('top', top), ('bottom', bottom), ('left', left), ('right', right)]:
        node = OxmlElement(f'w:{m}')
        node.set(qn('w:w'), str(val))
        node.set(qn('w:type'), 'dxa')
        tcMar.append(node)
    tcPr.append(tcMar)

def set_table_borders(table, color="CCCCCC", sz="4", val="single"):
    tblPr = table._tbl.tblPr
    borders = parse_xml(f'''
        <w:tblBorders {nsdecls("w")}>
            <w:top w:val="{val}" w:sz="{sz}" w:space="0" w:color="{color}"/>
            <w:bottom w:val="{val}" w:sz="{sz}" w:space="0" w:color="{color}"/>
            <w:left w:val="{val}" w:sz="{sz}" w:space="0" w:color="{color}"/>
            <w:right w:val="{val}" w:sz="{sz}" w:space="0" w:color="{color}"/>
            <w:insideH w:val="{val}" w:sz="{sz}" w:space="0" w:color="{color}"/>
            <w:insideV w:val="{val}" w:sz="{sz}" w:space="0" w:color="{color}"/>
        </w:tblBorders>
    ''')
    tblPr.append(borders)

def format_run(run, font_name='Times New Roman', size_pt=11, bold=False, italic=False, color_rgb=None):
    run.font.name = font_name
    run.font.size = Pt(size_pt)
    run.bold = bold
    run.italic = italic
    if color_rgb:
        run.font.color.rgb = color_rgb

def add_styled_paragraph(doc, text="", style='Normal', align=WD_ALIGN_PARAGRAPH.LEFT, space_before=0, space_after=6, line_spacing=1.15):
    p = doc.add_paragraph(style=style)
    p.alignment = align
    p.paragraph_format.space_before = Pt(space_before)
    p.paragraph_format.space_after = Pt(space_after)
    p.paragraph_format.line_spacing = line_spacing
    if text:
        run = p.add_run(text)
        format_run(run)
    return p

def process_inline_formatting(p, text):
    parts = re.split(r'(\*\*.*?\*\*)', text)
    for part in parts:
        if part.startswith('**') and part.endswith('**'):
            bold_text = part[2:-2]
            run = p.add_run(bold_text)
            format_run(run, bold=True)
        else:
            run = p.add_run(part)
            format_run(run)

def process_table(doc, table_rows):
    parsed_rows = []
    for r in table_rows:
        row_str = r.strip()
        if not row_str:
            continue
        cells = [c.strip() for c in row_str.split('|')[1:-1]]
        if all(re.match(r'^[-:]+$', c) for c in cells):
            continue
        parsed_rows.append(cells)
        
    if not parsed_rows:
        return
        
    num_cols = len(parsed_rows[0])
    table = doc.add_table(rows=len(parsed_rows), cols=num_cols)
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    set_table_borders(table)
    
    for row_idx, cells in enumerate(parsed_rows):
        row = table.rows[row_idx]
        for col_idx, text in enumerate(cells):
            if col_idx >= len(row.cells):
                continue
            cell = row.cells[col_idx]
            p = cell.paragraphs[0]
            p.paragraph_format.space_after = Pt(4)
            if row_idx == 0:
                set_cell_background(cell, "D9E1F2")
                run = p.add_run(text)
                format_run(run, bold=True, size_pt=10)
            else:
                run = p.add_run(text)
                format_run(run, size_pt=9.5)
            set_cell_margins(cell, top=60, bottom=60, left=100, right=100)

def parse_markdown_to_docx(doc, md_filepath):
    if not os.path.exists(md_filepath):
        print(f"File not found: {md_filepath}")
        return
        
    with open(md_filepath, 'r', encoding='utf-8') as f:
        lines = f.readlines()
    
    in_table = False
    table_data = []
    
    for line in lines:
        line_str = line.strip()
        
        if line_str.startswith('|'):
            in_table = True
            table_data.append(line_str)
            continue
        elif in_table:
            process_table(doc, table_data)
            in_table = False
            table_data = []
            
        if not line_str:
            continue
            
        if line_str.startswith('#### '):
            p = doc.add_paragraph()
            p.paragraph_format.space_before = Pt(6)
            p.paragraph_format.space_after = Pt(3)
            run = p.add_run(line_str[5:])
            format_run(run, size_pt=11.5, bold=True, color_rgb=RGBColor(128, 0, 0))
        elif line_str.startswith('### '):
            p = doc.add_paragraph()
            p.paragraph_format.space_before = Pt(8)
            p.paragraph_format.space_after = Pt(4)
            run = p.add_run(line_str[4:])
            format_run(run, size_pt=12.5, bold=True, color_rgb=RGBColor(0, 51, 102))
        elif line_str.startswith('## '):
            p = doc.add_paragraph()
            p.paragraph_format.space_before = Pt(12)
            p.paragraph_format.space_after = Pt(6)
            run = p.add_run(line_str[3:])
            format_run(run, size_pt=14, bold=True, color_rgb=RGBColor(0, 51, 102))
        elif line_str.startswith('- ') or line_str.startswith('* '):
            p = doc.add_paragraph(style='List Bullet')
            p.paragraph_format.space_after = Pt(3)
            process_inline_formatting(p, line_str[2:])
        elif re.match(r'^\d+\.\s', line_str):
            p = doc.add_paragraph(style='List Number')
            p.paragraph_format.space_after = Pt(3)
            idx = line_str.find('.')
            process_inline_formatting(p, line_str[idx+2:])
        else:
            p = doc.add_paragraph()
            p.paragraph_format.space_after = Pt(4)
            p.paragraph_format.line_spacing = 1.15
            process_inline_formatting(p, line_str)
            
    if in_table and table_data:
        process_table(doc, table_data)

def main():
    doc = Document()
    
    # Configure page setup
    section = doc.sections[0]
    section.top_margin = Inches(1)
    section.bottom_margin = Inches(1)
    section.left_margin = Inches(1)
    section.right_margin = Inches(1)

    # 1. Header block
    p = add_styled_paragraph(doc, "CÔNG TY TNHH SX-TM HOÁ KEO BÌNH THẠNH", align=WD_ALIGN_PARAGRAPH.CENTER)
    p.runs[0].bold = True
    p.runs[0].font.size = Pt(12)
    
    p = add_styled_paragraph(doc, "(BT CHEM)\n— — —\nPHÒNG QC", align=WD_ALIGN_PARAGRAPH.CENTER)
    p.runs[0].font.size = Pt(11)
    p.runs[0].bold = True
    
    p = doc.add_paragraph()
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER
    p.paragraph_format.space_before = Pt(12)
    p.paragraph_format.space_after = Pt(6)
    run = p.add_run("BÁO CÁO CHI TIẾT KẾT QUẢ QC TỪNG ĐỊA BÀN")
    format_run(run, size_pt=16, bold=True, color_rgb=RGBColor(0, 51, 102))
    
    p = add_styled_paragraph(doc, "Giai đoạn: 13/07/2026 – 20/07/2026", align=WD_ALIGN_PARAGRAPH.CENTER)
    p.runs[0].font.size = Pt(11)
    p.runs[0].italic = True

    # 2. Table of metadata
    table = doc.add_table(rows=5, cols=2)
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    set_table_borders(table)
    
    metadata = [
        ("Phạm vi tổng hợp", "Hố Nai, Tiến Triển, Thành Thắng, Phú Khang Phát, PMA, Kim Huy, Bình Thạnh, Kim Phong, Hạnh Phúc"),
        ("Nhân sự QC thực địa", "Bùi Thiện Lộc (QC1), Nguyễn Anh Trí (QC1), Bùi Đức Giang (QC), Đặng Đình Thao (QC)"),
        ("Ngày lập báo cáo", "20/07/2026"),
        ("Người tổng hợp", "Phòng QC BT-Chem"),
        ("Nguồn dữ liệu", "Báo cáo thực địa chi tiết gốc không lược bỏ (Locqc.md & Tri qc.md)")
    ]
    
    for idx, (label, val) in enumerate(metadata):
        row = table.rows[idx]
        cell_lbl, cell_val = row.cells[0], row.cells[1]
        
        # Left cell format
        p_lbl = cell_lbl.paragraphs[0]
        p_lbl.paragraph_format.space_after = Pt(4)
        run_lbl = p_lbl.add_run(label)
        format_run(run_lbl, bold=True, size_pt=10.5)
        set_cell_background(cell_lbl, "F2F2F2")
        set_cell_margins(cell_lbl, top=80, bottom=80, left=120, right=120)
        
        # Right cell format
        p_val = cell_val.paragraphs[0]
        p_val.paragraph_format.space_after = Pt(4)
        run_val = p_val.add_run(val)
        format_run(run_val, size_pt=10.5)
        set_cell_margins(cell_val, top=80, bottom=80, left=120, right=120)

    doc.add_paragraph()

    # Section I: CHI TIẾT BÁO CÁO QC BÙI THIỆN LỘC
    h1 = doc.add_paragraph()
    h1.paragraph_format.space_before = Pt(14)
    h1.paragraph_format.space_after = Pt(8)
    run_h1 = h1.add_run("I. CHI TIẾT CÁC BÁO CÁO - QC BÙI THIỆN LỘC")
    format_run(run_h1, size_pt=14, bold=True, color_rgb=RGBColor(0, 51, 102))
    
    parse_markdown_to_docx(doc, "../Locqc.md")
    
    doc.add_paragraph()

    # Section II: CHI TIẾT BÁO CÁO QC NGUYỄN ANH TRÍ
    h2 = doc.add_paragraph()
    h2.paragraph_format.space_before = Pt(14)
    h2.paragraph_format.space_after = Pt(8)
    run_h2 = h2.add_run("II. CHI TIẾT CÁC BÁO CÁO - QC NGUYỄN ANH TRÍ")
    format_run(run_h2, size_pt=14, bold=True, color_rgb=RGBColor(0, 51, 102))
    
    parse_markdown_to_docx(doc, "../Tri qc.md")

    # Space before sign-off
    doc.add_paragraph()
    doc.add_paragraph()

    # Signatures Table
    table_sig = doc.add_table(rows=1, cols=3)
    table_sig.alignment = WD_TABLE_ALIGNMENT.CENTER
    set_table_borders(table_sig, val="none") # No borders for signatures
    
    sig_cells = table_sig.rows[0].cells
    titles = [
        "NGƯỜI LẬP BÁO CÁO\n(Ký và ghi rõ họ tên)\n\n\n\nPhòng QC",
        "TRƯỞNG PHÒNG KỸ THUẬT\n(Ký và ghi rõ họ tên)\n\n\n\nPhòng Kỹ Thuật",
        "DUYỆT\n(Ban Giám Đốc)\n\n\n\nBan Giám Đốc"
    ]
    for i, t in enumerate(titles):
        p_s = sig_cells[i].paragraphs[0]
        p_s.alignment = WD_ALIGN_PARAGRAPH.CENTER
        run_s = p_s.add_run(t)
        format_run(run_s, size_pt=10, bold=True)
        set_cell_margins(sig_cells[i], top=100, bottom=100, left=150, right=150)

    # Save to file
    out_dir = "../Bao cao"
    os.makedirs(out_dir, exist_ok=True)
    out_path = os.path.join(out_dir, "bao-cao-QC-18-07-2026.docx")
    doc.save(out_path)
    print(f"Successfully generated weekly QC report at: {os.path.abspath(out_path)}")

if __name__ == '__main__':
    main()
