"""Generate Guide and README PDFs using fpdf2."""
from fpdf import FPDF
import re

class DocPDF(FPDF):
    def __init__(self, title):
        super().__init__()
        self._doc_title = title
        self.set_auto_page_break(auto=True, margin=20)

    def header(self):
        self.set_font("Helvetica", "B", 8)
        self.set_text_color(120, 120, 120)
        self.cell(0, 6, self._doc_title, align="L")
        self.ln(4)
        self.set_draw_color(60, 60, 60)
        self.line(10, self.get_y(), 200, self.get_y())
        self.ln(4)

    def footer(self):
        self.set_y(-15)
        self.set_font("Helvetica", "I", 7)
        self.set_text_color(150, 150, 150)
        self.cell(0, 10, f"Page {self.page_no()}/{{nb}}", align="C")

    def section_title(self, txt):
        self.set_font("Helvetica", "B", 13)
        self.set_text_color(30, 30, 30)
        self.ln(3)
        self.cell(0, 8, txt)
        self.ln(8)

    def sub_title(self, txt):
        self.set_font("Helvetica", "B", 10)
        self.set_text_color(50, 50, 50)
        self.ln(2)
        self.cell(0, 6, txt)
        self.ln(6)

    def body(self, txt):
        self.set_font("Helvetica", "", 9)
        self.set_text_color(40, 40, 40)
        self.multi_cell(0, 5, txt)
        self.ln(1)

    def step(self, n, txt):
        self.set_font("Helvetica", "B", 9)
        self.set_text_color(59, 130, 246)
        self.cell(8, 5, str(n))
        self.set_font("Helvetica", "", 9)
        self.set_text_color(40, 40, 40)
        self.multi_cell(0, 5, txt)
        self.ln(1)

    def tip(self, txt):
        self.set_fill_color(240, 248, 255)
        self.set_font("Helvetica", "I", 8)
        self.set_text_color(6, 182, 212)
        x = self.get_x()
        self.cell(0, 5, "TIP:", fill=True)
        self.ln(5)
        self.set_text_color(60, 60, 60)
        self.multi_cell(0, 4.5, txt, fill=True)
        self.ln(2)

    def table_row(self, cells, bold=False):
        style = "B" if bold else ""
        self.set_font("Helvetica", style, 7)
        n = len(cells)
        if n <= 2:
            widths = [60, 130]
        elif n == 3:
            widths = [35, 40, 115]
        elif n == 4:
            widths = [30, 35, 60, 65]
        else:
            widths = [190 // n] * n
        for i, c in enumerate(cells):
            w = widths[i] if i < len(widths) else widths[-1]
            self.cell(w, 5.5, str(c)[:80], border=1)
        self.ln()


def gen_guide():
    pdf = DocPDF("LIGAND Connections - User Guide v5.0")
    pdf.alias_nb_pages()
    pdf.add_page()

    pdf.set_font("Helvetica", "B", 22)
    pdf.set_text_color(20, 20, 20)
    pdf.cell(0, 12, "LIGAND Connections", ln=True)
    pdf.set_font("Helvetica", "", 11)
    pdf.set_text_color(80, 80, 80)
    pdf.cell(0, 7, "User Guide v5.0  |  Fano-Geometric Protein-Ligand Design Platform", ln=True)
    pdf.ln(4)
    pdf.body("A practical walkthrough for biogenetics researchers working with protein-ligand design via the LIGAND Connections Fano geometry framework. This guide covers every feature in the platform, from structural exploration to data export.")
    pdf.ln(4)

    # Quick Start
    pdf.section_title("Quick Start for New Users")
    pdf.step(1, "Design Wizard - Guided 7-step ligand design with L1/L6/L7 presets.")
    pdf.step(2, "BLAST Align - Paste a protein to find the best LIGAND match.")
    pdf.step(3, "Run calculations - Critical angles, binding affinities, harmonic spectra.")
    pdf.step(4, "Export results - YAML, SPPS protocols, PDF, Excel, FASTA, LaTeX.")

    # Design Wizard
    pdf.section_title("Design Wizard")
    pdf.body("The Design Wizard is the primary workflow for creating new ligand designs. It guides you through a 7-step process from goal definition to final experiment creation.")
    pdf.step(1, "Goal - Select your design objective: design a new ligand, optimize an existing one, screen against a target, or run pentadic analysis.")
    pdf.step(2, "Target - Choose an existing target from your database or create a new one with CATH class, fold type, and PDB ID.")
    pdf.step(3, "Layer - Select the L-layer that matches your target fold.")
    pdf.step(4, "Geometry - Compute the critical angle and CDR arm extension. Use L1: 17/7, L6: 28/17, or L7: 28/17 presets.")
    pdf.step(5, "Affinity - Estimate thermodynamic binding parameters (delta-G, KD) from the spectral gap.")
    pdf.step(6, "Sequence - Define the peptide sequence and synthesis notes.")
    pdf.step(7, "Review & Save - Review all parameters and save. Creates ligand, target, and experiment records.")
    pdf.tip("Quick presets on the Geometry step save time. Click 'L1: 17/7' to auto-fill the exact Fano incidence values from the published framework.")

    # Genome to Proteome
    pdf.section_title("Genome to Proteome")
    pdf.body("The Genome Search page provides four tools for working with nucleotide and protein sequences, including live access to NCBI's public databases and BLAST-style alignment against the LIGAND library.")
    pdf.sub_title("Tab 1: Translate")
    pdf.body("Paste a DNA or RNA sequence and translate it to a protein. Returns the amino acid sequence with color-coded residue types, molecular weight, composition breakdown, codon-by-codon detail, and automatic fold motif detection.")
    pdf.sub_title("Tab 2: BLAST Align")
    pdf.body("Paste any unknown protein sequence to find the best L1/L6/L7 match. Scoring: Motif Match (40%), Fold Signatures (30%), Composition (20%), Local Alignment (10%).")
    pdf.sub_title("Tab 3: NCBI Search")
    pdf.body("Search NCBI's protein, gene, or nucleotide databases in real time. Click 'Fetch Sequence' on any protein result to retrieve the full amino acid sequence with fold motif analysis.")
    pdf.sub_title("Tab 4: Codon Table & Reverse Translate")
    pdf.body("Standard genetic code with all 64 RNA codons. Reverse Translate takes a protein sequence and returns all possible codons for each residue.")

    # Layer Explorer
    pdf.section_title("L0-L7 Layer Explorer")
    pdf.body("The Layer Explorer presents all eight layers of the LIGAND Connections framework. Each layer includes Key Concepts (biological/mathematical principles), Formulas (rendered equations), and Metrics (pLDDT, RMSD, KD, etc.).")
    pdf.tip("Start at L0 to understand the Fano plane foundation, then navigate to the layer matching your target's fold class.")

    # Calculator
    pdf.section_title("Ligand Calculator")
    pdf.body("Five computational modules:")
    pdf.step(1, "Critical Angle Calculator - Computes theta_crit from the Fano incidence ratio (r_shape / r_gauge). L1: 67.38 deg, L6: 58.74 deg.")
    pdf.step(2, "Binding Affinity - Estimates delta-G and KD from sigma_sigma, theta_crit, and temperature.")
    pdf.step(3, "Harmonic Spectrum - phi/pi^n quantization for n=1-7, mapping to biological function classes.")
    pdf.step(4, "Cartan Decomposition - Matrix determinant, rank, trace, and derived theta_crit verification.")

    # Structure & Analysis Platform
    pdf.section_title("Structure & Analysis Platform (13 Tabs)")
    pdf.body("The /structure page is the central hub for all Fano-based structural tools. Every tab that produces data includes a dedicated Export button for instant download.")
    pdf.ln(2)

    pdf.sub_title("1. Predict Tab")
    pdf.body("Input amino acid sequence (up to 2000 residues) and flex parameter. Returns per-residue Fano metrics (sigma, det, lane), phi/psi angles, secondary structure (100% from Fano lanes), backbone coordinates. Interactive Ramachandran plot colored by Fano lane. Exports: .pdb, .cif, .csv, .ipynb.")

    pdf.sub_title("2. 3D Structure Viewer Tab")
    pdf.body("NGL Viewer renders the predicted backbone as an interactive 3D model. Rotate by dragging, zoom with scroll.")
    pdf.step(1, "Color modes: Fano Lane (7 colors), Sec. Structure (H/E/C), Determinant (B-factor gradient), Sigma (plasma gradient).")
    pdf.step(2, "Representations: Cartoon, Backbone, Ball+Stick, Spacefill, Licorice.")
    pdf.step(3, "Auto Spin rotates continuously. .pdb and .csv buttons download directly from control bar.")
    pdf.tip("Fano Lane coloring is the most informative view - lane transitions correlate with domain boundaries and functional regions.")

    pdf.sub_title("3. Import Tab (UniProt & AlphaFold)")
    pdf.body("Search UniProt by gene name, protein name, or accession. Copy sequences to Predict tab. Fetch AlphaFold structures for comparison.")

    pdf.sub_title("4. Batch Comparison Tab")
    pdf.body("Paste multiple sequences (up to 200). Returns fitness scatter plot, ranked table with hydrophobicity, net charge, lane diversity. Export: CSV.")

    pdf.sub_title("5. PDB Overlay Tab")
    pdf.body("Enter PDB ID and chain. Fetches known structure from RCSB, runs Fano prediction, computes Kabsch RMSD and angle accuracy. SS accuracy: 100%. Exports: PDB, Summary CSV.")

    pdf.sub_title("6. Sequence Alignment Tab")
    pdf.body("Paste 2+ sequences. Returns pairwise Fano lane conservation percentages and per-sequence lane distributions. Export: CSV.")

    pdf.sub_title("7. Gene/Chromosome Viewer Tab")
    pdf.body("Enter gene name and organism. Returns Ensembl gene context: chromosome position, strand, transcripts, protein IDs. Export: JSON.")

    pdf.sub_title("8. Domain Annotation Tab")
    pdf.body("Enter UniProt accession. Returns InterPro/Pfam domain annotations with visual domain map. Export: CSV.")

    pdf.sub_title("9. Mutation Impact Scanner Tab")
    pdf.body("Paste wild-type sequence + mutations (e.g., M1A, I3V). Returns per-mutation lane changes, delta sigma/det/fitness, HIGH/MEDIUM/LOW impact. Export: CSV.")

    pdf.sub_title("10. Binding Site Prediction Tab")
    pdf.body("Paste sequence + det percentile threshold. Returns ranked binding sites (high-det clusters near lane transitions). Export: CSV.")

    pdf.sub_title("11. Disorder Prediction Tab")
    pdf.body("Paste sequence + optional UniProt accession for MobiDB overlay. Sigma > 1.5x median = disordered. Displays disorder regions, MobiDB consensus. Export: CSV.")

    pdf.sub_title("12. Amino Acid Property Heatmap Tab")
    pdf.body("Paste sequence. 7-property heatmaps: hydrophobicity, charge, MW, volume, flexibility, sigma, determinant. Multi-property strip view. Export: All Properties CSV.")

    pdf.sub_title("13. Wet-Lab Validation Feedback Loop Tab")
    pdf.body("Submit experimental results (SPR, ITC, NMR, X-ray, CD, Cryo-EM): RMSD, pLDDT, KD, measured SS. Compare vs Fano predictions. Per-user validation history. Export: Validations CSV.")

    # Other features
    pdf.section_title("Additional Features")

    pdf.sub_title("Alpha-Flex Fano-Basin Engine")
    pdf.body("4 tabs: Analyze (per-residue metrics), Interactome (cross-sequence correlation), GA Optimizer (genetic algorithm sequence design), G-Code (Fano-geometric instruction set).")

    pdf.sub_title("AI Research Assistant")
    pdf.body("GPT-powered assistant trained on the full LIGAND Connections framework. Answers questions on Fano geometry, Lie algebras, fold classification, binding thermodynamics, and design strategy.")

    pdf.sub_title("Fano Plane Visualizer")
    pdf.body("Interactive SVG of PG(2, F2). 7 fold-class points, 7 binding-mode lines, 42 flags. Hover/click to explore.")

    pdf.sub_title("Dynkin Diagrams")
    pdf.body("Interactive Lie algebra diagrams: A5, D4, E6, E7, E8, E19, E20.")

    # Export Pipeline
    pdf.section_title("Export Pipeline")
    pdf.body("Per-Tab Exports: Every analysis tab has a dedicated export button (CSV, JSON, or PDB).")
    pdf.body("Predict Exports: .pdb, .cif (mmCIF), .csv, .ipynb (Jupyter).")
    pdf.body("Platform Exports (10 formats): Ligand/Target/Experiment CSV, Full JSON, Excel Workbook, YAML Config, SPPS Protocols, PDF Report, LaTeX Formulas, FASTA Sequences.")

    # Subscription
    pdf.section_title("Subscription & Access")
    pdf.body("Multi-provider auth: Google OAuth, Email/Password, GitHub OAuth, Microsoft OAuth (ready).")
    pdf.ln(2)
    pdf.set_font("Helvetica", "B", 8)
    pdf.table_row(["Tier", "Price", "Key Features"], bold=True)
    pdf.set_font("Helvetica", "", 8)
    pdf.table_row(["Free", "$0/mo", "2hr cumulative, 3 exports, dashboard"])
    pdf.table_row(["Researcher", "$50/mo", "Predict, Ramachandran, Import, Gene, Heatmaps, Exports"])
    pdf.table_row(["Operator", "$100/mo", "+ Batch (200), Align, Overlay, API key"])
    pdf.table_row(["Validator", "$200/mo", "+ Mutation, Binding, Disorder, Wet-lab, Domains"])
    pdf.table_row(["Admin", "$500/mo", "Full access, 10k+ batch, team mgmt, priority support"])

    # Reference Values
    pdf.section_title("Reference Values for Benchmarking")
    pdf.sub_title("L1 - Greek Key Universal Binder")
    for k, v in [("theta_crit", "77.14 deg"), ("Fano incidence", "17 -> 7"), ("r_CDR", "28.0 A"), ("Partners", "127"), ("pLDDT", "97.2%"), ("RMSD", "0.84 A"), ("KD", "5.3 pM"), ("sigma_sigma", "0.00079")]:
        pdf.set_font("Helvetica", "", 8)
        pdf.cell(40, 5, k)
        pdf.set_font("Helvetica", "B", 8)
        pdf.cell(0, 5, v, ln=True)

    pdf.sub_title("L6 - E20 Quaternary Binder")
    for k, v in [("theta_crit", "58.91 deg"), ("Fano incidence", "28 -> 17"), ("r_CDR", "34.0 A"), ("Partners", "254"), ("pLDDT", "98.5%"), ("RMSD", "0.42 A"), ("KD", "2.1 pM"), ("Volume", "6664 A^3")]:
        pdf.set_font("Helvetica", "", 8)
        pdf.cell(40, 5, k)
        pdf.set_font("Helvetica", "B", 8)
        pdf.cell(0, 5, v, ln=True)

    pdf.output("/app/LIGAND_Connections_User_Guide_v5.pdf")
    print("Guide PDF generated.")


def gen_readme():
    pdf = FPDF()
    pdf.set_auto_page_break(auto=True, margin=20)
    pdf.add_page()

    with open("/app/README.md", "r") as f:
        content = f.read()

    # Sanitize unicode
    for old, new in [("\u2014","--"),("\u2013","-"),("\u2019","'"),("\u2018","'"),("\u201c",'"'),("\u201d",'"'),("\u2192","->"),("\u2082","2"),("\u00b2","2"),("\u03b8","theta"),("\u0394","delta"),("\u03c6","phi"),("\u03c0","pi"),("\u00c5","A"),("\u00b0","deg")]:
        content = content.replace(old, new)

    in_code = False
    for line in content.split("\n"):
        stripped = line.strip()

        if stripped.startswith("```"):
            in_code = not in_code
            continue

        if in_code:
            pdf.set_font("Courier", "", 7)
            pdf.set_text_color(60, 60, 60)
            pdf.set_x(10)
            pdf.cell(0, 4, "  " + line.rstrip(), ln=True)
            continue

        if not stripped:
            pdf.ln(2)
            continue

        if stripped == "---":
            pdf.set_draw_color(180, 180, 180)
            pdf.set_x(10)
            pdf.line(10, pdf.get_y(), 200, pdf.get_y())
            pdf.ln(4)
            continue

        # Clean markdown formatting
        clean = re.sub(r'\*\*(.*?)\*\*', r'\1', stripped)
        clean = re.sub(r'`(.*?)`', r'\1', clean)

        # Headers
        if stripped.startswith("# ") and not stripped.startswith("## "):
            pdf.set_font("Helvetica", "B", 20)
            pdf.set_text_color(20, 20, 20)
            pdf.set_x(10)
            pdf.cell(0, 12, clean[2:], ln=True)
            continue
        if stripped.startswith("## "):
            pdf.ln(3)
            pdf.set_font("Helvetica", "B", 13)
            pdf.set_text_color(30, 30, 30)
            pdf.set_x(10)
            pdf.cell(0, 8, clean[3:], ln=True)
            pdf.ln(2)
            continue
        if stripped.startswith("### "):
            pdf.ln(1)
            pdf.set_font("Helvetica", "B", 10)
            pdf.set_text_color(50, 50, 50)
            pdf.set_x(10)
            pdf.cell(0, 6, clean[4:], ln=True)
            pdf.ln(1)
            continue

        # Table rows
        if "|" in stripped:
            cells = [c.strip() for c in stripped.split("|") if c.strip()]
            if cells and not all(set(c) <= {"-", ":"} for c in cells):
                pdf.set_font("Helvetica", "", 7)
                pdf.set_text_color(40, 40, 40)
                pdf.set_x(10)
                pdf.cell(0, 4.5, " | ".join(str(c)[:50] for c in cells), ln=True)
            continue

        # List items
        if stripped.startswith("- "):
            pdf.set_font("Helvetica", "", 8)
            pdf.set_text_color(40, 40, 40)
            pdf.set_x(10)
            pdf.multi_cell(190, 4.5, "- " + clean[2:])
            continue

        # Regular text
        if clean:
            pdf.set_font("Helvetica", "", 9)
            pdf.set_text_color(40, 40, 40)
            pdf.set_x(10)
            pdf.multi_cell(190, 5, clean)

    pdf.output("/app/LIGAND_Connections_README_v5.pdf")
    print("README PDF generated.")


if __name__ == "__main__":
    gen_guide()
    gen_readme()
