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 (value.strip() == "0" or not value.strip()):
            remove_paragraph(paragraph)
            return
        full_text = ''.join(run.text for run in paragraph.runs)
        full_text = full_text.replace(placeholder, value.strip())
        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')
    rFonts.set(ns.qn('w:ascii'), 'Calibri')
    rFonts.set(ns.qn('w:hAnsi'), 'Calibri')
    rFonts.set(ns.qn('w:eastAsia'), 'Calibri')
    rFonts.set(ns.qn('w:cs'), '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', '')
        location1 = request.form.get('location1', '')
        location2 = request.form.get('location2', '')
        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', '')
        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_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'

        doc = Document('customerPPI.docx')

        # Handle image replacement
        image_mappings = {
            "Image 1:": ("image1", "static/Solution-Overview.png"),
            "Image 2:": ("image2", "static/Client-to-Conf.png"),
            "Image 3:": ("image3", "static/Admin-to-MGT.png"),
            "Image 4:": ("image4", "static/Option-Auth-MGT.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)

                    if i + 1 < len(paragraphs):
                        next_para = paragraphs[i + 1]
                    else:
                        next_para = insert_paragraph_after(para)

                    for run in next_para.runs[:]:
                        if run._element.xpath(".//w:drawing"):
                            next_para._element.remove(run._element)

                    next_para.add_run().add_picture(image_path, width=Inches(5.5))
                    paragraphs = doc.paragraphs
            i += 1

        # Replace text placeholders
        replacements = {
            "<customer>": customer,
            "<partner>": partner,
            "<customExecSection>": customExecSection,
            "<location1>": location1,
            "<location2>": location2,
            "<mgt>": mgt,
            "<cnsm1>": cnsm1,
            "<cnmed1>": cnmed1,
            "<cnlg1>": cnlg1,
            "<cnsm2>": cnsm2,
            "<cnmed2>": cnmed2,
            "<cnlg2>": cnlg2,
            "<cap>": cap,
            "<date>": selected_date,
            "<sa>": sa,
            "<title>": title,
            "<endpoints>": endpoints,
            "<otj>": otj_qty
        }

        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)

        # Replace CVI naming
        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)

        # Replace SIP naming
        for paragraph in doc.paragraphs:
            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)

        # Replace Server naming
        for paragraph in doc.paragraphs:
            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."

        # IP block
        ip_list = [request.form.get(f'ipaddress{i}', '').strip() for i in range(1, 21)]
        ip_block = '\n'.join(ip for ip in ip_list if ip)
        replace_placeholder_in_doc(doc, "<ipblock>", ip_block)

        # Integration links
        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

        # Participants (webrtc, sip, cc)
        participant_map = {
            'webrtc': 'WebRTC',
            'sip': 'Standards-Based Endpoints',
            'cc': 'Contact Center agents'
        }

        selected_participants = [
            label for key, label in participant_map.items() if request.form.get(key) == 'yes'
        ]

        if not selected_participants:
            participant_text = ""
        elif len(selected_participants) == 1:
            participant_text = selected_participants[0]
        elif len(selected_participants) == 2:
            participant_text = f"{selected_participants[0]} and {selected_participants[1]}"
        else:
            participant_text = ", ".join(selected_participants[:-1]) + f", and {selected_participants[-1]}"

        for paragraph in doc.paragraphs:
            if any(ph in paragraph.text for ph in ["<webrtc>", "<sip>", "<cc>"]):
                if not participant_text:
                    remove_paragraph(paragraph)
                else:
                    full_text = ''.join(run.text for run in paragraph.runs)
                    for ph in ["<webrtc>", "<sip>", "<cc>"]:
                        full_text = full_text.replace(ph, '')
                    full_text = full_text.replace(" ,", ",").replace("  ", " ").strip()
                    full_text = full_text.replace("via", f"via {participant_text}")
                    for run in paragraph.runs:
                        run.text = ''
                    if paragraph.runs:
                        paragraph.runs[0].text = full_text
                    else:
                        paragraph.add_run(full_text)
                break

        # Output
        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('formPPI.html')

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