import os
import pandas as pd
from docx import Document
from docx.shared import RGBColor
from docxcompose.composer import Composer
import streamlit as st
import tempfile

def populate_docx_template(excel_file, template_files, temp_dir, selected_publishable_indices, selected_confidential_indices):
    """
    Generate one full Word document per selected Excel row from the template,
    filling all relevant cells in the table while preserving formatting.

    Numbering of selected records is done separately for publishable and confidential,
    and numbers are prefixed to client names.
    """
    df = pd.read_excel(excel_file)
    df.columns = df.columns.str.strip()

    generated_files = []

    # Create numbering maps separately
    publishable_numbers = {idx: num + 1 for num, idx in enumerate(selected_publishable_indices)}
    confidential_numbers = {idx: num + 1 for num, idx in enumerate(selected_confidential_indices)}

    # Combine selections keeping order: publishable first then confidential (you can change if needed)
    all_selected = selected_publishable_indices + selected_confidential_indices

    for idx, row_idx in enumerate(all_selected):
        row = df.iloc[row_idx]

        conf_status = str(row.get('Confidential / Publishable', '')).lower()
        is_confidential = (conf_status == 'yes' or 'confidential' in conf_status)

        # Get numbering for current row
        if is_confidential:
            number = confidential_numbers.get(row_idx, 0)
        else:
            number = publishable_numbers.get(row_idx, 0)

        # Select template
        template_key = 'confidential' if is_confidential else 'publishable'
        doc = Document(template_files[template_key])

        if not doc.tables:
            st.error("Template file appears to have no tables.")
            return []

        table = doc.tables[0]

        # Prepare data fields (all strip spaces)
        serial_number = str(row.get('S No.', '') or '').strip()
        client_name = str(row.get('Client Name', '') or '').strip()

        matter_overview = str(row.get('Matter/Case Overview', '') or '').strip()

        # Description columns variations
        desc_col_names = ['Description  (in 500 words)', 'Description (in 500 words)', 'Description']
        description = ""
        for col_name in desc_col_names:
            if col_name in df.columns:
                val = row.get(col_name, '')
                if pd.notna(val):
                    description = str(val).strip()
                    break

        role_col_names = ['Role of S&A', 'Role of SA', 'Role']
        role_of_sa = ""
        for col_name in role_col_names:
            if col_name in df.columns:
                val = row.get(col_name, '')
                if pd.notna(val):
                    role_of_sa = str(val).strip()
                    break

        sig_col_names = ['The significance, impact and outcome of the case', 'Significance', 'Impact']
        significance = ""
        for col_name in sig_col_names:
            if col_name in df.columns:
                val = row.get(col_name, '')
                if pd.notna(val):
                    significance = str(val).strip()
                    break

        value = str(row.get('Value', '') or '').strip()
        cross_border = str(row.get('Is this a cross-border matter? If yes, please indicate the jurisdictions involved.', '') or '').strip()
        lead_partners = str(row.get('Lead partners', '') or '').strip()
        team_partners = str(row.get('Team Members', '') or '').strip()
        other_firms = str(row.get('Other Firms/counsels Involved', '') or '').strip()

        current_status = row.get('Current Status (ongoing / completed )', '')
        dates = str(current_status) if pd.notna(current_status) else ''

        try:
            # Fill client name cell (2,0)
            table.cell(2, 0).text = client_name
            if is_confidential:
                for paragraph in table.cell(2, 0).paragraphs:
                    for run in paragraph.runs:
                        run.font.color.rgb = RGBColor(255, 0, 0)

            # Matter overview cell (4,0)
            overview_cell = table.cell(4, 0)
            # Clear existing paragraphs
            overview_cell.text = ""

            # Overview header
            overview_header = overview_cell.add_paragraph()
            header_run = overview_header.add_run("Overview")
            header_run.bold = True
            if is_confidential:
                header_run.font.color.rgb = RGBColor(255, 0, 0)

            # Description paragraph
            desc_para = overview_cell.add_paragraph()
            desc_run = desc_para.add_run(description)
            if is_confidential:
                desc_run.font.color.rgb = RGBColor(255, 0, 0)

            # Role header
            role_header = overview_cell.add_paragraph()
            role_header.add_run("\n")  # linebreak
            role_run = role_header.add_run("Role of S&A")
            role_run.bold = True
            if is_confidential:
                role_run.font.color.rgb = RGBColor(255, 0, 0)

            # Role text
            role_para = overview_cell.add_paragraph()
            role_text_run = role_para.add_run(role_of_sa)
            if is_confidential:
                role_text_run.font.color.rgb = RGBColor(255, 0, 0)

            # Significance header
            sig_header = overview_cell.add_paragraph()
            sig_header.add_run("\n")
            sig_run = sig_header.add_run("Significance & Impact of the Matter")
            sig_run.bold = True
            if is_confidential:
                sig_run.font.color.rgb = RGBColor(255, 0, 0)

            # Significance text
            sig_para = overview_cell.add_paragraph()
            sig_text_run = sig_para.add_run(significance)
            if is_confidential:
                sig_text_run.font.color.rgb = RGBColor(255, 0, 0)

            # Remaining standard cells
            table.cell(5, 1).text = value

            # Fix typo here: .txt → .text
            table.cell(20, 1).text = other_firms

            table.cell(8, 1).text = cross_border
            table.cell(12, 0).text = lead_partners

            table.cell(12, 2).text = "S&A law offices"

            table.cell(16, 0).text = team_partners

            table.cell(16, 2).text = "S&A law offices"

            table.cell(22, 3).text = dates

          
            if is_confidential:
                for cell_pos in [(5, 1), (8, 1), (12, 0), (12, 2), (16, 0), (16, 2), (20, 1), (22, 3)]:
                    cell = table.cell(cell_pos[0], cell_pos[1])
                    for paragraph in cell.paragraphs:
                        for run in paragraph.runs:
                            run.font.color.rgb = RGBColor(255, 0, 0)

        except IndexError:
            st.error("Template table structure mismatch. Please check your template cell indices.")
            return []
        except Exception as e:
            st.error(f"Error processing document: {str(e)}")
            return []

        # Clean filename
        safe_client_name = "".join(c for c in client_name if c.isalnum() or c in (" ", "_")).rstrip()
        safe_client_name = safe_client_name.replace(" ", "_") or "client"

        prefix = "CONF" if is_confidential else "PUB"
        outpath = os.path.join(temp_dir, f"{idx:03d}_{prefix}_{safe_client_name}.docx")
        doc.save(outpath)
        generated_files.append(outpath)

    return generated_files


def combine_documents_with_watermark(file_paths, output_file):
    """
    Combine multiple .docx files preserving full formatting like tables, headers, footers, watermarks.
    """
    if not file_paths:
        return None

    combined_doc = Document(file_paths[0])
    composer = Composer(combined_doc)

    for fp in file_paths[1:]:
        doc = Document(fp)
        composer.append(doc)

    composer.save(output_file)
    return output_file


def app():
    st.title("Legal 500 Document Generator")

    # Upload Excel
    excel_file = st.file_uploader("Upload Excel file with data", type=["xlsx", "xls"])

    # Template file inputs
    st.subheader("Template Files")
    col1, col2 = st.columns(2)

    with col1:
        publishable_template_path = st.text_input(
            "Publishable Template Path",
            value="C:\\Users\\Administrator\\Desktop\\Legal 500.doc"
        )

    with col2:
        confidential_template_path = st.text_input(
            "Confidential Template Path",
            value="C:\\Users\\Administrator\\Desktop\\Legal 500..doc"
        )

    if excel_file is not None:
        df = pd.read_excel(excel_file)
        df.columns = df.columns.str.strip()

        st.subheader("Select Records to Include")

        tab1, tab2 = st.tabs(["Publishable", "Confidential"])
        selected_publishable_indices = []
        selected_confidential_indices = []

        with tab1:
            st.write("Select publishable records (marked as 'No' or 'Publishable'):")
            publishable_rows = []
            for i, row in df.iterrows():
                pval = str(row.get('Confidential / Publishable', '')).lower()
                if pd.notna(pval) and (pval == 'no' or 'publishable' in pval):
                    publishable_rows.append(i)

            for i in publishable_rows:
                row = df.iloc[i]
                serial_number = str(row.get('S No.', '') or '').strip()
                client_name = str(row.get('Client Name', '') or '').strip()
                value = str(row.get('Value', '') or '').strip()

                label = f"{serial_number} - {client_name} - ({value})"
                if st.checkbox(label, key=f"pub_{i}"):
                    if i not in selected_publishable_indices:
                        selected_publishable_indices.append(i)

        with tab2:
            st.write("Select confidential records (marked as 'Yes', 'Confidential', or 'Maintain Confidentiality'):")
            confidential_rows = []
            for i, row in df.iterrows():
                pval = str(row.get('Confidential / Publishable', '')).lower()
                if pd.notna(pval) and ('yes' == pval or 'confidential' in pval or 'maintain confidentiality' in pval):
                    confidential_rows.append(i)

            for i in confidential_rows:
                row = df.iloc[i]
                serial_number = str(row.get('S No.', '') or '').strip()
                client_name = str(row.get('Client Name', '') or '').strip()
                value = str(row.get('Value', '') or '').strip()
                label = f"{serial_number} - {client_name} - ({value})"
                if st.checkbox(label, key=f"conf_{i}"):
                    if i not in selected_confidential_indices:
                        selected_confidential_indices.append(i)

        if st.button("Generate Documents"):
            if selected_publishable_indices or selected_confidential_indices:
                with tempfile.TemporaryDirectory() as temp_dir:
                    # Validate templates
                    if not os.path.exists(publishable_template_path):
                        st.error(f"Publishable template file not found: {publishable_template_path}")
                        return

                    if not os.path.exists(confidential_template_path):
                        st.error(f"Confidential template file not found: {confidential_template_path}")
                        return

                    template_files = {
                        'publishable': publishable_template_path,
                        'confidential': confidential_template_path
                    }

                    progress_bar = st.progress(0)
                    status = st.empty()

                    status.text("Populating templates per selected record...")

                    with st.spinner("Processing..."):
                        generated_files = populate_docx_template(
                            excel_file,
                            template_files,
                            temp_dir,
                            selected_publishable_indices,
                            selected_confidential_indices
                        )

                    progress_bar.progress(50)

                    if not generated_files:
                        st.error("No documents generated. Check template and data.")
                        return

                    status.text("Combining generated documents (preserving watermark and formatting)...")
                    combined_path = os.path.join(temp_dir, "Legal_500_Combined.docx")
                    combine_documents_with_watermark(generated_files, combined_path)
                    progress_bar.progress(100)

                    if os.path.exists(combined_path):
                        status.text("Documents generated successfully!")
                        with open(combined_path, "rb") as f:
                            st.download_button(
                                label="Download Combined Document",
                                data=f,
                                file_name="Legal_500_Combined.docx",
                                mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                            )
                    else:
                        st.error("Failed to generate combined document.")
            else:
                st.warning("Select at least one record to generate documents.")


if __name__ == "__main__":
    app()  in this path of template file has to be hardcoed dont show this on frontend ....only in code....complte upadted code