from flask import Flask, render_template, request, send_file
import io
import os
from docx import Document
from docx.oxml import OxmlElement, ns
from docx.oxml.ns import qn
from docx.shared import Pt, Inches

app = Flask(__name__)

def remove_paragraph(paragraph):
    p = paragraph._element
    p.getparent().remove(p)
    p._p = p._element = None

def insert_paragraph_after(paragraph):
    new_p = OxmlElement('w:p')
    paragraph._p.addnext(new_p)
    return paragraph._parent.add_paragraph()

def replace_placeholder_in_paragraph(paragraph, placeholder, value):
    CONDITIONAL_REMOVE = {
        "<cnsm1>", "<cnmed1>", "<cnlg1>",
        "<cnsm2>", "<cnmed2>", "<cnlg2>"
    }
    if placeholder in paragraph.text:
        if placeholder in CONDITIONAL_REMOVE and (not value.strip() or value.strip() == "0"):
            remove_paragraph(paragraph)
            return

        size_map = {
            "<cnsm1>": "Small Conference Node (8vCPU)",
            "<cnmed1>": "Medium Conference Node (16vCPU)",
            "<cnlg1>": "Large Conference Node (32vCPU)",
            "<cnsm2>": "Small Conference Node (8vCPU)",
            "<cnmed2>": "Medium Conference Node (16vCPU)",
            "<cnlg2>": "Large Conference Node (32vCPU)"
        }

        description = size_map.get(placeholder, "")
        replacement = f"{value.strip()} x {description}" if description else value.strip()

        full_text = ''.join(run.text for run in paragraph.runs).replace(placeholder, replacement)
        for run in paragraph.runs:
            run.text = ''
        if paragraph.runs:
            paragraph.runs[0].text = full_text
        else:
            paragraph.add_run(full_text)

def replace_placeholder_in_doc(doc, placeholder, value):
    for paragraph in doc.paragraphs:
        replace_placeholder_in_paragraph(paragraph, placeholder, value)
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for paragraph in cell.paragraphs:
                    replace_placeholder_in_paragraph(paragraph, placeholder, value)
    for section in doc.sections:
        for paragraph in section.header.paragraphs:
            replace_placeholder_in_paragraph(paragraph, placeholder, value)
        for paragraph in section.footer.paragraphs:
            replace_placeholder_in_paragraph(paragraph, placeholder, value)

def add_hyperlink(paragraph, url, text):
    part = paragraph.part
    r_id = part.relate_to(
        url,
        'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
        is_external=True
    )
    hyperlink = OxmlElement('w:hyperlink')
    hyperlink.set(ns.qn('r:id'), r_id)
    new_run = OxmlElement('w:r')
    rPr = OxmlElement('w:rPr')
    sz = OxmlElement('w:sz')
    sz.set(ns.qn('w:val'), '18')
    rPr.append(sz)
    rFonts = OxmlElement('w:rFonts')
    for attr in ['ascii', 'hAnsi', 'eastAsia', 'cs']:
        rFonts.set(ns.qn(f'w:{attr}'), 'Calibri')
    rPr.append(rFonts)
    color = OxmlElement('w:color')
    color.set(ns.qn('w:val'), '0000FF')
    rPr.append(color)
    underline = OxmlElement('w:u')
    underline.set(ns.qn('w:val'), 'single')
    rPr.append(underline)
    new_run.append(rPr)
    text_elem = OxmlElement('w:t')
    text_elem.text = text
    new_run.append(text_elem)
    hyperlink.append(new_run)
    paragraph._p.append(hyperlink)

@app.route('/', methods=['GET', 'POST'])
def form():
    if request.method == 'POST':
        customer = request.form.get('customer', '')
        partner = request.form.get('partner', '')
        customExecSection = request.form.get('customExecSection', '')
        customSO = request.form.get('customSO', '')
        cpu_model = request.form.get('cpu_model', '')
        platform = request.form.get('platform', '')
        hypervisor = request.form.get('hypervisor', '')
        location1 = request.form.get('location1', '')
        location2 = request.form.get('location2', '')
        locationDMZ1 = request.form.get('locationDMZ1', '')
        locationDMZ2 = request.form.get('locationDMZ2', '')
        mgt = "1"
        cnsm1 = request.form.get('cnsm1', '')
        cnmed1 = request.form.get('cnmed1', '')
        cnlg1 = request.form.get('cnlg1', '')
        cnsm2 = request.form.get('cnsm2', '')
        cnmed2 = request.form.get('cnmed2', '')
        cnlg2 = request.form.get('cnlg2', '')
        edgesm1 = request.form.get('edgesm1', '')
        edgemed1 = request.form.get('edgemed1', '')
        edgesm2 = request.form.get('edgesm2', '')
        edgemed2 = request.form.get('edgemed2', '')
        cap = request.form.get('cap', '')
        endpoints_enabled = request.form.get('endpointReg', '') == 'yes'
        endpoints = request.form.get('endpoints', '') if endpoints_enabled else ''
        otj_enabled = request.form.get('otj', '') == 'yes'
        otj_qty = request.form.get('otjQty', '') if otj_enabled else ''
        selected_date = request.form.get('date', '')
        sa = request.form.get('sa', '')
        title = request.form.get('title', '')
        naming_template_cvi = request.form.get('namingTemplateCVI', '').strip()
        cvi_type = request.form.get('cviType', '').strip()
        cvi_selected = request.form.get('namingConventionCVI', '') == 'yes'
        naming_template_sip = request.form.get('namingTemplateSIP', '').strip()
        sip_selected = request.form.get('namingConventionSIP', '') == 'yes'
        naming_template_server = request.form.get('namingTemplateServer', '').strip()
        server_selected = request.form.get('namingConventionServer', '') == 'yes'
        pexipNoted_value = request.form.get('pexipNoted', '')
        pexipNotedText = request.form.get('pexipNotedText', '').strip()

        if pexipNotedText:
            pexipNoted = pexipNotedText
        else:
            pexipNoted = f"{customer} meets the recommended best practices for Pexip Infinity."

        doc = Document('customer.docx')

        image_mappings = {
            "Image 1:": ("image1", "Sample-Compute.png"),
            "Image 2:": ("image2", "VMware-Infinity.png"),
            "Image 3:": ("image3", "Client-to-Conf.png"),
            "Image 4:": ("image4", "Admin-to-MGT.png"),
            "Image 5:": ("image5", "Option-Auth-MGT.png"),
            "Image 6:": ("image6", "OTJ-O365.png"),
            "Image 7:": ("image7", "OTJ-O365.png")
        }

        paragraphs = doc.paragraphs
        i = 0
        while i < len(paragraphs):
            para = paragraphs[i]
            for label, (field_name, default_filename) in image_mappings.items():
                if para.text.strip().startswith(label):
                    uploaded_file = request.files.get(field_name)
                    if uploaded_file and uploaded_file.filename != "":
                        image_path = f"/tmp/{uploaded_file.filename}"
                        uploaded_file.save(image_path)
                    else:
                        image_path = os.path.join(os.path.dirname(__file__), default_filename)
                    next_para = paragraphs[i + 1] if i + 1 < len(paragraphs) else insert_paragraph_after(para)
                    for run in next_para.runs[:]:
                        if run._element.xpath(".//w:drawing"):
                            next_para._element.remove(run._element)
                    try:
                        next_para.add_run().add_picture(image_path, width=Inches(5.5))
                    except Exception as e:
                        print(f"Could not insert image for {field_name}: {e}")
                    paragraphs = doc.paragraphs
            i += 1

        replacements = {
            "<customer>": customer,
            "<partner>": partner,
            "<customExecSection>": customExecSection,
            "<customSO>": customSO,
            "<cpu_model>": cpu_model,
            "<platform>": platform,
            "<hypervisor>": hypervisor,
            "<location1>": location1,
            "<location2>": location2,
            "<locationDMZ1>": locationDMZ1,
            "<locationDMZ2>": locationDMZ2,
            "<mgt>": mgt,
            "<cnsm1>": cnsm1,
            "<cnmed1>": cnmed1,
            "<cnlg1>": cnlg1,
            "<cnsm2>": cnsm2,
            "<cnmed2>": cnmed2,
            "<cnlg2>": cnlg2,
            "<edgesm1>": edgesm1,
            "<edgemed1>": edgemed1,
            "<edgesm2>": edgesm2,
            "<edgemed2>": edgemed2,
            "<cap>": cap,
            "<date>": selected_date,
            "<sa>": sa,
            "<title>": title,
            "<endpoints>": endpoints,
            "<otj>": otj_qty,
            "<cviType>": cvi_type,
            "<pexipNoted>": pexipNoted
        }

        for paragraph in doc.paragraphs:
            if "<endpoints>" in paragraph.text and not endpoints_enabled:
                remove_paragraph(paragraph)
            elif "<otj>" in paragraph.text and not otj_enabled:
                remove_paragraph(paragraph)

        for placeholder, value in replacements.items():
            replace_placeholder_in_doc(doc, placeholder, value)

        for paragraph in doc.paragraphs:
            if "<namingTemplateCVI>" in paragraph.text:
                if cvi_selected and naming_template_cvi:
                    replace_placeholder_in_paragraph(paragraph, "<namingTemplateCVI>", naming_template_cvi)
                else:
                    remove_paragraph(paragraph)

            if "<namingTemplateSIP>" in paragraph.text:
                if sip_selected and naming_template_sip:
                    replace_placeholder_in_paragraph(paragraph, "<namingTemplateSIP>", naming_template_sip)
                else:
                    remove_paragraph(paragraph)

            if "<namingTemplateServer>" in paragraph.text:
                if server_selected and naming_template_server:
                    replace_placeholder_in_paragraph(paragraph, "<namingTemplateServer>", naming_template_server)
                else:
                    paragraph.text = f"{customer} has chosen NOT to use a standard naming convention and Pexip will provide the naming convention for the Pexip nodes."

        INTEGRATION_LINKS = {
            'ucm': 'https://docs.pexip.com/admin/integrate_ucm.htm',
            'vcs': 'https://docs.pexip.com/admin/integrate_vcs.htm',
            'poly': 'https://docs.pexip.com/admin/integrate_polycom.htm',
            'genesys': 'https://docs.pexip.com/admin/integrate_genesys.htm',
            'pstn': 'https://docs.pexip.com/admin/integrate_pstn_gateway.htm'
        }

        for key, url in INTEGRATION_LINKS.items():
            version = request.form.get(key, '').strip()
            placeholder = f"<{key}>"
            for paragraph in doc.paragraphs:
                if placeholder in paragraph.text:
                    if not version:
                        remove_paragraph(paragraph)
                    else:
                        for run in paragraph.runs:
                            run.text = ''
                        paragraph.runs[0].text = f"{key.upper()} v{version}: "
                        add_hyperlink(paragraph, url, url)
                    break

        output = io.BytesIO()
        doc.save(output)
        output.seek(0)

        filename = f"{customer.replace(' ', '_')}_output.docx"
        return send_file(output, as_attachment=True, download_name=filename)

    return render_template('form.html')

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5002)