"""TargetRecon — premium dark dashboard UI."""
from __future__ import annotations

import asyncio
import json
import os
from pathlib import Path

import streamlit as st

st.set_page_config(
    page_title="TargetRecon",
    page_icon="🎯",
    layout="wide",
    initial_sidebar_state="expanded",
)

# ═══════════════════════════════════════════════════════════════════════════
#  GLOBAL CSS — override ALL Streamlit chrome, force dark premium theme
# ═══════════════════════════════════════════════════════════════════════════
st.markdown("""
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap');

:root {
  --bg:      #070b14;
  --s1:      #0c1020;
  --s2:      #121828;
  --s3:      #1a2236;
  --border:  rgba(255,255,255,0.07);
  --border2: rgba(255,255,255,0.04);
  --t1:      #eaedf5;
  --t2:      #8891a8;
  --t3:      #4a5168;
  --blue:    #4080ff;
  --green:   #1ec97a;
  --orange:  #f5a623;
  --purple:  #8b80f5;
  --red:     #f5605c;
  --mono:    'JetBrains Mono', monospace;
}

html, body, .stApp, [data-testid="stApp"] {
  background: var(--bg) !important;
  color: var(--t1) !important;
  font-family: 'Inter', system-ui, sans-serif !important;
  font-size: 13px !important;
}

/* ── Hide only safe Streamlit chrome ── */
#MainMenu { visibility: hidden; }
footer { visibility: hidden; }
[data-testid="stDecoration"] { display: none !important; }

/* ── Shrink the top header bar but keep sidebar toggle visible ── */
[data-testid="stHeader"] {
  background: var(--bg) !important;
  height: 2.5rem !important;
  min-height: 2.5rem !important;
  border-bottom: none !important;
}
[data-testid="stSidebarCollapseButton"] {
  color: #4a5168 !important;
}
[data-testid="stSidebarCollapseButton"]:hover {
  color: #8891a8 !important;
  background: rgba(255,255,255,0.04) !important;
}

/* ── Main container ── */
.main .block-container {
  padding: 1rem 1.5rem 2rem !important;
  max-width: 100% !important;
}

/* ── Sidebar ── */
[data-testid="stSidebar"] {
  background: #050810 !important;
  border-right: 1px solid var(--border) !important;
}
[data-testid="stSidebar"] .block-container { padding: 1.5rem 1rem !important; }
[data-testid="stSidebar"] label,
[data-testid="stSidebar"] p { color: var(--t3) !important; font-size: 11px !important; font-weight: 500; text-transform: uppercase; letter-spacing: .04em; }
[data-testid="stSidebar"] input,
[data-testid="stSidebar"] textarea {
  background: var(--s2) !important;
  border: 1px solid var(--border) !important;
  color: var(--t1) !important;
  border-radius: 7px !important;
  font-size: 13px !important;
}
[data-testid="stSidebar"] input:focus,
[data-testid="stSidebar"] textarea:focus {
  border-color: rgba(64,128,255,0.4) !important;
  box-shadow: 0 0 0 3px rgba(64,128,255,0.1) !important;
  outline: none !important;
}
/* Slider */
[data-testid="stSlider"] [data-baseweb="slider"] div[role="slider"] {
  background: var(--blue) !important;
}
[data-testid="stSlider"] [data-testid="stTickBarMin"],
[data-testid="stSlider"] [data-testid="stTickBarMax"] { color: var(--t3) !important; }

/* Sidebar button */
[data-testid="stSidebar"] button[kind="primary"] {
  background: var(--blue) !important;
  border: none !important;
  border-radius: 8px !important;
  color: #fff !important;
  font-weight: 600 !important;
  font-size: 12.5px !important;
  letter-spacing: .02em !important;
  padding: .55rem 1rem !important;
  transition: opacity .15s, transform .1s !important;
  width: 100% !important;
}
[data-testid="stSidebar"] button[kind="primary"]:hover { opacity: .88 !important; transform: translateY(-1px) !important; }
[data-testid="stSidebar"] button[kind="primary"]:active { transform: translateY(0) !important; }

/* Selectbox */
[data-testid="stSelectbox"] > div > div {
  background: var(--s2) !important;
  border: 1px solid var(--border) !important;
  color: var(--t1) !important;
  border-radius: 7px !important;
}

/* ── Tabs ── */
[data-testid="stTabs"] [role="tablist"] {
  background: transparent !important;
  border-bottom: 1px solid var(--border) !important;
  gap: 0 !important; padding: 0 !important;
}
[data-testid="stTabs"] [role="tab"] {
  background: transparent !important;
  color: var(--t3) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  padding: .55rem 1.1rem !important;
  border: none !important;
  border-bottom: 2px solid transparent !important;
  border-radius: 0 !important;
  transition: color .15s !important;
  letter-spacing: .01em !important;
}
[data-testid="stTabs"] [role="tab"]:hover { color: var(--t2) !important; }
[data-testid="stTabs"] [role="tab"][aria-selected="true"] {
  color: var(--t1) !important;
  border-bottom-color: var(--blue) !important;
}
[data-testid="stTabsContent"] { background: transparent !important; border: none !important; padding: 1rem 0 0 !important; }

/* ── Download buttons ── */
[data-testid="stDownloadButton"] button {
  background: rgba(64,128,255,0.1) !important;
  border: 1px solid rgba(64,128,255,0.25) !important;
  color: #6b9ef8 !important;
  border-radius: 7px !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  transition: all .15s !important;
}
[data-testid="stDownloadButton"] button:hover {
  background: rgba(64,128,255,0.2) !important;
  border-color: rgba(64,128,255,0.45) !important;
}

/* ── Primary action buttons ── */
.stButton button[kind="primary"] {
  background: linear-gradient(135deg, #3b7bf8 0%, #6b4ff8 100%) !important;
  border: none !important;
  border-radius: 8px !important;
  color: #fff !important;
  font-weight: 600 !important;
  font-size: 12.5px !important;
  padding: .5rem 1.4rem !important;
  transition: opacity .15s, transform .1s !important;
  box-shadow: 0 4px 15px rgba(64,128,255,0.25) !important;
}
.stButton button[kind="primary"]:hover { opacity: .88 !important; transform: translateY(-1px) !important; }

/* ── Text area ── */
[data-testid="stTextArea"] textarea {
  background: var(--s2) !important;
  border: 1px solid var(--border) !important;
  color: var(--t1) !important;
  border-radius: 8px !important;
  font-size: 13px !important;
  line-height: 1.6 !important;
}
[data-testid="stTextArea"] textarea:focus {
  border-color: rgba(64,128,255,0.4) !important;
  box-shadow: 0 0 0 3px rgba(64,128,255,0.1) !important;
  outline: none !important;
}

/* ── Spinner ── */
.stSpinner > div { color: var(--blue) !important; }

/* ── Checkbox ── */
[data-testid="stCheckbox"] span { color: var(--t2) !important; font-size: 12px !important; }

/* ── Number input ── */
[data-testid="stNumberInput"] input {
  background: var(--s2) !important;
  border: 1px solid var(--border) !important;
  color: var(--t1) !important;
  border-radius: 6px !important;
}

/* ── Alert / info ── */
[data-testid="stAlert"] {
  background: var(--s2) !important;
  border: 1px solid var(--border) !important;
  border-radius: 8px !important;
  color: var(--t2) !important;
}
</style>
""", unsafe_allow_html=True)


# ═══════════════════════════════════════════════════════════════════════════
#  SIDEBAR
# ═══════════════════════════════════════════════════════════════════════════
with st.sidebar:
    st.markdown("""
<div style="margin-bottom:1.5rem">
  <div style="font-size:17px;font-weight:700;color:#eaedf5;letter-spacing:-.01em">🎯 TargetRecon</div>
  <div style="font-size:11px;color:#2d3450;margin-top:2px;font-weight:500;text-transform:uppercase;letter-spacing:.06em">Drug target intelligence</div>
</div>
""", unsafe_allow_html=True)

    query = st.text_input("query", value="", placeholder="EGFR · P00533 · CHEMBL203",
                          label_visibility="collapsed")

    st.markdown("<div style='height:.5rem'></div>", unsafe_allow_html=True)
    st.markdown("<div style='font-size:10.5px;color:#2d3450;text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-bottom:.4rem'>Filters</div>", unsafe_allow_html=True)
    max_resolution   = st.slider("Max resolution (Å)", 1.0, 6.0, 4.0, 0.5)
    max_structures   = st.number_input("Max PDB structures", 5, 200, 50, 5)
    max_bioactivities = st.number_input("Max bioactivities", 50, 2000, 500, 50)
    min_pchembl      = st.slider("Min pChEMBL", 0.0, 12.0, 0.0, 0.5)

    st.markdown("<div style='height:.75rem'></div>", unsafe_allow_html=True)
    st.markdown("<div style='font-size:10.5px;color:#2d3450;text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-bottom:.4rem'>AI Agent</div>", unsafe_allow_html=True)
    api_key_input = st.text_input("Anthropic API key", value=os.environ.get("ANTHROPIC_API_KEY",""),
                                   type="password", placeholder="sk-ant-…",
                                   label_visibility="collapsed")
    ai_model = st.selectbox("model", ["claude-opus-4-6","claude-sonnet-4-6","claude-haiku-4-5-20251001"],
                             label_visibility="collapsed")

    st.markdown("<div style='height:.75rem'></div>", unsafe_allow_html=True)
    st.markdown("<div style='font-size:10.5px;color:#2d3450;text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-bottom:.4rem'>Export</div>", unsafe_allow_html=True)
    export_html_cb = st.checkbox("HTML report", True)
    export_json_cb = st.checkbox("JSON data",   True)
    export_sdf_cb  = st.checkbox("SDF ligands", False)

    st.markdown("<div style='height:.75rem'></div>", unsafe_allow_html=True)
    run_button = st.button("Run reconnaissance", type="primary")

    st.markdown("""
<div style="margin-top:2rem;padding-top:1rem;border-top:1px solid rgba(255,255,255,0.05);
font-size:10.5px;color:#202540;line-height:1.7">
v0.1.0 &nbsp;·&nbsp;
<a href="https://github.com/hyadav/targetrecon" target="_blank"
   style="color:#2a3c70;text-decoration:none">GitHub</a>
</div>
""", unsafe_allow_html=True)


# ═══════════════════════════════════════════════════════════════════════════
#  LANDING
# ═══════════════════════════════════════════════════════════════════════════
if not run_button or not query.strip():
    if "auto_query" in st.session_state:
        query = st.session_state.pop("auto_query")
        run_button = True
    else:
        st.markdown("""
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;
            min-height:55vh;text-align:center;gap:1rem">
  <div style="font-size:13px;color:#1a2040;letter-spacing:.12em;text-transform:uppercase;
              font-weight:600">Drug Target Intelligence</div>
  <div style="font-size:38px;font-weight:700;color:#eaedf5;letter-spacing:-.03em;
              line-height:1.15">Aggregate. Analyse.<br>
    <span style="background:linear-gradient(90deg,#4080ff,#8b80f5);
                 -webkit-background-clip:text;-webkit-text-fill-color:transparent">Discover.</span>
  </div>
  <div style="font-size:14px;color:#4a5168;max-width:480px;line-height:1.7">
    UniProt · RCSB PDB · AlphaFold · ChEMBL · BindingDB — in one command.
    Enter a gene name, UniProt accession, or ChEMBL ID in the sidebar.
  </div>
</div>
""", unsafe_allow_html=True)

        cols = st.columns(5)
        for col, ex in zip(cols, ["EGFR", "BRAF", "CDK2", "ABL1", "JAK2"]):
            with col:
                if st.button(ex, key=f"ex_{ex}"):
                    st.session_state["auto_query"] = ex
                    st.rerun()
        st.stop()


# ═══════════════════════════════════════════════════════════════════════════
#  RUN RECON
# ═══════════════════════════════════════════════════════════════════════════
with st.spinner(f"Fetching data for **{query.strip()}** …"):
    from targetrecon.core import recon_async
    try:
        report = asyncio.run(recon_async(
            query.strip(),
            max_pdb_resolution=max_resolution,
            max_pdb_structures=int(max_structures),
            max_bioactivities=int(max_bioactivities),
            min_pchembl=min_pchembl if min_pchembl > 0 else None,
            verbose=False,
        ))
    except Exception as exc:
        st.error(f"Error: {exc}")
        st.stop()

if report.uniprot is None:
    st.error(f"Could not resolve '{query}'. Try EGFR, P00533, or CHEMBL203.")
    st.stop()

st.session_state["report"] = report
u    = report.uniprot
gene = u.gene_name or query.strip()


# ═══════════════════════════════════════════════════════════════════════════
#  HEADER CARD
# ═══════════════════════════════════════════════════════════════════════════
chembl_badge = ""
if u.chembl_id:
    chembl_badge = (
        f'<span style="color:var(--t3)">ChEMBL</span> '
        f'<a href="https://www.ebi.ac.uk/chembl/target_report_card/{u.chembl_id}" '
        f'target="_blank" style="color:#4f8ef7;text-decoration:none;'
        f'font-family:var(--mono)">{u.chembl_id}</a>'
    )

st.markdown(f"""
<style>
:root{{--t1:#eaedf5;--t2:#8891a8;--t3:#4a5168;--blue:#4080ff;--green:#1ec97a;
       --orange:#f5a623;--purple:#8b80f5;--mono:'JetBrains Mono',monospace;
       --s1:#0c1020;--s2:#121828;--s3:#1a2236;--border:rgba(255,255,255,0.07);
       --border2:rgba(255,255,255,0.04);}}
</style>
<div style="background:linear-gradient(135deg,#0b1128 0%,#0f1730 55%,#0b1820 100%);
     border:1px solid var(--border);border-radius:12px;
     padding:1.4rem 1.75rem 1.2rem;margin-bottom:8px;
     box-shadow:0 4px 24px rgba(0,0,0,0.4)">
  <div style="display:flex;align-items:baseline;gap:14px;margin-bottom:10px;flex-wrap:wrap">
    <span style="font-size:28px;font-weight:700;color:#f0f3fc;letter-spacing:-.025em">{gene}</span>
    <span style="font-size:14px;color:#5a647a;line-height:1.4">{u.protein_name}</span>
  </div>
  <div style="display:flex;gap:22px;font-size:12px;flex-wrap:wrap;align-items:center">
    <span style="color:var(--t3)">UniProt
      <a href="https://www.uniprot.org/uniprot/{u.uniprot_id}" target="_blank"
         style="color:#4f8ef7;text-decoration:none;font-family:var(--mono);margin-left:4px">{u.uniprot_id}</a></span>
    {"<span>" + chembl_badge + "</span>" if chembl_badge else ""}
    <span style="color:var(--t3)">Organism
      <span style="color:#9aa0b8;font-family:var(--mono);margin-left:4px">{u.organism}</span></span>
    <span style="color:var(--t3)">Length
      <span style="color:#9aa0b8;font-family:var(--mono);margin-left:4px">{u.sequence_length:,} aa</span></span>
  </div>
</div>
""", unsafe_allow_html=True)


# ═══════════════════════════════════════════════════════════════════════════
#  STATS BAR
# ═══════════════════════════════════════════════════════════════════════════
best_pc = f"{report.best_ligand.best_pchembl:.2f}" if (report.best_ligand and report.best_ligand.best_pchembl) else "—"
af_txt  = "Available" if report.alphafold else "None"
af_color = "#4080ff" if report.alphafold else "#4a5168"

def _stat(val, label, color, last=False):
    sep = "" if last else "border-right:1px solid rgba(255,255,255,0.05);"
    return f"""
<div style="flex:1;padding:.9rem 1rem;text-align:center;{sep}">
  <div style="font-size:22px;font-weight:600;color:{color};
              font-family:'JetBrains Mono',monospace;line-height:1.15">{val}</div>
  <div style="font-size:10px;color:#3a4060;text-transform:uppercase;
              letter-spacing:.07em;margin-top:5px;font-weight:600">{label}</div>
</div>"""

st.markdown(f"""
<div style="display:flex;background:#0b1020;border:1px solid var(--border);
     border-radius:10px;overflow:hidden;margin-bottom:14px;
     box-shadow:0 2px 16px rgba(0,0,0,0.35)">
  {_stat(report.num_pdb_structures, "PDB Structures", "#4080ff")}
  {_stat(f"{report.num_bioactivities:,}", "Bioactivities", "#1ec97a")}
  {_stat(f"{report.num_unique_ligands:,}", "Unique Ligands", "#f5a623")}
  {_stat(best_pc, "Best pChEMBL", "#8b80f5")}
  {_stat(af_txt, "AlphaFold", af_color, last=True)}
</div>
""", unsafe_allow_html=True)


# ═══════════════════════════════════════════════════════════════════════════
#  TABS
# ═══════════════════════════════════════════════════════════════════════════
tab_ov, tab_st, tab_bio, tab_lig, tab_pdb, tab_ai = st.tabs([
    "Overview", "3D Structure", "Bioactivity", "Ligands",
    f"PDB ({report.num_pdb_structures})", "🤖 AI Agent",
])


# ───────────────────────────────────────────────────────────────────────────
#  TAB: OVERVIEW
# ───────────────────────────────────────────────────────────────────────────
with tab_ov:
    def _tag(text, style="background:rgba(64,128,255,.15);color:#6b9ef8"):
        return f'<span style="display:inline-block;padding:2px 9px;border-radius:4px;font-size:11px;margin:2px;{style}">{text}</span>'

    subcell = "".join(_tag(l, "background:rgba(64,128,255,.12);color:#7aabff") for l in u.subcellular_locations) or "<span style='color:var(--t3)'>—</span>"
    kw_tags = "".join(_tag(k, "background:rgba(139,128,245,.12);color:#a89cf5") for k in u.keywords[:22]) or "<span style='color:var(--t3)'>—</span>"
    dis_list = "".join(f'<div style="font-size:12px;color:#7a8298;padding:2px 0;line-height:1.5">· {d}</div>' for d in u.disease_associations[:8]) or '<span style="color:var(--t3)">—</span>'

    go_by_cat: dict[str, list] = {}
    for go in u.go_terms:
        go_by_cat.setdefault(go.category, []).append(go.term)

    go_sections = ""
    go_colors = {
        "molecular_function":  ("rgba(30,201,122,.1)", "#2dcf8a"),
        "biological_process":  ("rgba(64,128,255,.1)", "#6b9ef8"),
        "cellular_component":  ("rgba(139,128,245,.1)", "#a89cf5"),
    }
    for cat, terms in go_by_cat.items():
        bg, fg = go_colors.get(cat, ("rgba(255,255,255,.06)", "#8891a8"))
        cat_label = cat.replace("_", " ").title()
        tgs = "".join(_tag(t, f"background:{bg};color:{fg}") for t in terms[:10])
        go_sections += f"""
<div style="margin-bottom:.75rem">
  <div style="font-size:10px;color:#3a4060;text-transform:uppercase;letter-spacing:.07em;
              font-weight:600;margin-bottom:4px">{cat_label}</div>
  {tgs}
</div>"""

    st.markdown(f"""
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px">

  <!-- left col -->
  <div style="display:flex;flex-direction:column;gap:12px">

    <!-- function -->
    <div style="background:var(--s1);border:1px solid var(--border);border-radius:10px;padding:1.1rem 1.25rem">
      <div style="font-size:10px;color:var(--t3);text-transform:uppercase;letter-spacing:.07em;
                  font-weight:600;margin-bottom:.6rem">Function</div>
      <div style="font-size:12.5px;color:#9aa4bc;line-height:1.75">
        {u.function_description or '<span style="color:var(--t3)">No function annotation</span>'}
      </div>
    </div>

    <!-- subcellular -->
    <div style="background:var(--s1);border:1px solid var(--border);border-radius:10px;padding:1.1rem 1.25rem">
      <div style="font-size:10px;color:var(--t3);text-transform:uppercase;letter-spacing:.07em;
                  font-weight:600;margin-bottom:.6rem">Subcellular Location</div>
      {subcell}
    </div>

    <!-- diseases -->
    <div style="background:var(--s1);border:1px solid var(--border);border-radius:10px;padding:1.1rem 1.25rem">
      <div style="font-size:10px;color:var(--t3);text-transform:uppercase;letter-spacing:.07em;
                  font-weight:600;margin-bottom:.6rem">Disease Associations</div>
      {dis_list}
    </div>

  </div>

  <!-- right col -->
  <div style="display:flex;flex-direction:column;gap:12px">

    <!-- keywords -->
    <div style="background:var(--s1);border:1px solid var(--border);border-radius:10px;padding:1.1rem 1.25rem">
      <div style="font-size:10px;color:var(--t3);text-transform:uppercase;letter-spacing:.07em;
                  font-weight:600;margin-bottom:.6rem">Keywords</div>
      {kw_tags}
    </div>

    <!-- GO terms -->
    <div style="background:var(--s1);border:1px solid var(--border);border-radius:10px;padding:1.1rem 1.25rem;flex:1">
      <div style="font-size:10px;color:var(--t3);text-transform:uppercase;letter-spacing:.07em;
                  font-weight:600;margin-bottom:.75rem">Gene Ontology</div>
      {go_sections or '<span style="color:var(--t3);font-size:12px">No GO terms</span>'}
    </div>

  </div>
</div>
""", unsafe_allow_html=True)


# ───────────────────────────────────────────────────────────────────────────
#  TAB: 3D STRUCTURE
# ───────────────────────────────────────────────────────────────────────────
with tab_st:
    struct_options, struct_urls, struct_is_af = [], [], []

    if report.alphafold:
        plddt_s = f" — pLDDT {report.alphafold.mean_plddt:.0f}" if report.alphafold.mean_plddt else ""
        struct_options.append(f"AlphaFold prediction{plddt_s}")
        struct_urls.append(report.alphafold.pdb_url or
                           f"https://alphafold.ebi.ac.uk/files/AF-{u.uniprot_id}-F1-model_v4.pdb")
        struct_is_af.append(True)

    for s in report.pdb_structures[:30]:
        res_s = f" — {s.resolution:.1f} Å" if s.resolution else ""
        struct_options.append(f"{s.pdb_id}  {s.method.value}{res_s}")
        struct_urls.append(f"https://files.rcsb.org/download/{s.pdb_id}.pdb")
        struct_is_af.append(False)

    if struct_options:
        idx = st.selectbox("Structure", range(len(struct_options)),
                           format_func=lambda i: struct_options[i],
                           label_visibility="collapsed")
        pdb_url = struct_urls[idx]
        is_af   = struct_is_af[idx]

        af_style_js = """
          viewer.setStyle({}, {cartoon:{colorfunc:function(a){
            var b=a.b;
            return b>90?'#0053d6':b>70?'#65cbf3':b>50?'#ffdb13':'#ff7d45';
          }}});"""
        xr_style_js = """
          viewer.setStyle({},{cartoon:{colorscheme:'ssJmol'}});
          viewer.setStyle({hetflag:true},{stick:{colorscheme:'greenCarbon',radius:0.14,
            singleBond:false}});"""

        style_js = af_style_js if is_af else xr_style_js

        legend_html = """
<div style="display:flex;gap:16px;margin-top:8px;font-size:10.5px;color:#3a4060;flex-wrap:wrap">
  <span><span style="display:inline-block;width:10px;height:10px;background:#0053d6;
    border-radius:2px;margin-right:5px;vertical-align:middle"></span>Very high (&gt;90)</span>
  <span><span style="display:inline-block;width:10px;height:10px;background:#65cbf3;
    border-radius:2px;margin-right:5px;vertical-align:middle"></span>Confident (70–90)</span>
  <span><span style="display:inline-block;width:10px;height:10px;background:#ffdb13;
    border-radius:2px;margin-right:5px;vertical-align:middle"></span>Low (50–70)</span>
  <span><span style="display:inline-block;width:10px;height:10px;background:#ff7d45;
    border-radius:2px;margin-right:5px;vertical-align:middle"></span>Very low (&lt;50)</span>
</div>""" if is_af else ""

        st.components.v1.html(f"""
<!DOCTYPE html><html><head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/3Dmol/2.1.0/3Dmol-min.js"></script>
<style>
  * {{ margin:0;padding:0;box-sizing:border-box }}
  body {{ background:#070b14;font-family:Inter,system-ui,sans-serif }}
  #wrap {{
    width:100%;height:500px;background:#06090f;border-radius:10px;
    border:1px solid rgba(255,255,255,0.07);overflow:hidden;position:relative
  }}
  #viewer {{ width:100%;height:100% }}
  #loading {{
    position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
    flex-direction:column;gap:10px;color:#3a4060;font-size:12px;
    background:#06090f;z-index:10;transition:opacity .3s
  }}
  .spinner {{
    width:28px;height:28px;border:2px solid rgba(64,128,255,0.15);
    border-top-color:#4080ff;border-radius:50%;animation:spin .8s linear infinite
  }}
  @keyframes spin {{to{{transform:rotate(360deg)}}}}
  {legend_html.replace('<div','<div id="legend"').replace('</div>','</div>', 1) if legend_html else ''}
</style>
</head><body>
<div id="wrap">
  <div id="loading"><div class="spinner"></div><span>Loading structure…</span></div>
  <div id="viewer"></div>
</div>
{('<div id="legend" style="display:flex;gap:16px;margin-top:8px;font-size:10.5px;color:#3a4060;flex-wrap:wrap">'
  '<span><span style="display:inline-block;width:10px;height:10px;background:#0053d6;border-radius:2px;margin-right:5px;vertical-align:middle"></span>Very high (&gt;90)</span>'
  '<span><span style="display:inline-block;width:10px;height:10px;background:#65cbf3;border-radius:2px;margin-right:5px;vertical-align:middle"></span>Confident (70–90)</span>'
  '<span><span style="display:inline-block;width:10px;height:10px;background:#ffdb13;border-radius:2px;margin-right:5px;vertical-align:middle"></span>Low (50–70)</span>'
  '<span><span style="display:inline-block;width:10px;height:10px;background:#ff7d45;border-radius:2px;margin-right:5px;vertical-align:middle"></span>Very low (&lt;50)</span>'
  '</div>') if is_af else ''}
<script>
var viewer = $3Dmol.createViewer(document.getElementById('viewer'),
  {{backgroundColor:'#06090f',antialias:true}});
fetch('{pdb_url}')
  .then(r=>r.text())
  .then(pdb=>{{
    viewer.addModel(pdb,'pdb');
    {style_js}
    viewer.zoomTo();viewer.render();
    var ld=document.getElementById('loading');
    if(ld){{ld.style.opacity='0';setTimeout(()=>ld.remove(),350);}}
  }})
  .catch(e=>{{
    var ld=document.getElementById('loading');
    if(ld) ld.innerHTML='<span style="color:#f5605c">Failed to load structure</span>';
  }});
</script>
</body></html>
""", height=540)
    else:
        st.info("No structures available for this target.")


# ───────────────────────────────────────────────────────────────────────────
#  TAB: BIOACTIVITY
# ───────────────────────────────────────────────────────────────────────────
with tab_bio:
    if report.bioactivities:
        pchembl_vals = [r.pchembl_value for r in report.bioactivities if r.pchembl_value is not None]
        atype_counts: dict[str,int] = {}
        for r in report.bioactivities:
            if r.activity_type:
                atype_counts[r.activity_type] = atype_counts.get(r.activity_type, 0) + 1
        method_counts: dict[str,int] = {}
        for s in report.pdb_structures:
            method_counts[s.method.value] = method_counts.get(s.method.value, 0) + 1
        source_counts: dict[str,int] = {}
        for r in report.bioactivities:
            source_counts[r.source] = source_counts.get(r.source, 0) + 1

        st.components.v1.html(f"""
<!DOCTYPE html><html><head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js"></script>
<style>
  *{{margin:0;padding:0;box-sizing:border-box}}
  body{{background:#070b14;font-family:Inter,system-ui,sans-serif;color:#8891a8;padding:4px}}
  .grid{{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:12px}}
  .card{{background:#0c1020;border:1px solid rgba(255,255,255,0.07);border-radius:10px;
         padding:1.1rem 1.25rem}}
  .card-title{{font-size:10px;color:#3a4060;text-transform:uppercase;letter-spacing:.07em;
               font-weight:600;margin-bottom:1rem}}
  canvas{{max-height:220px}}
  .stat-row{{display:flex;flex-wrap:wrap;gap:8px}}
  .stat-chip{{display:flex;align-items:center;gap:8px;background:#111828;border:1px solid rgba(255,255,255,.06);
              border-radius:7px;padding:.45rem .9rem;font-size:11.5px}}
  .stat-chip .num{{font-weight:600;color:#eaedf5;font-family:'JetBrains Mono',monospace}}
  .stat-chip .lbl{{color:#3a4060;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em}}
  .dot{{width:8px;height:8px;border-radius:50%}}
</style>
</head><body>
<div class="grid">
  <div class="card">
    <div class="card-title">pChEMBL Distribution</div>
    <canvas id="pchemblChart"></canvas>
  </div>
  <div class="card">
    <div class="card-title">Structures by Method</div>
    <canvas id="methodChart"></canvas>
  </div>
</div>
<div class="grid" style="grid-template-columns:1fr 1fr">
  <div class="card">
    <div class="card-title">Activity Type Breakdown</div>
    <div class="stat-row">
      {''.join(f'<div class="stat-chip"><span class="num">{cnt}</span><span class="lbl">{atype}</span></div>' for atype, cnt in sorted(atype_counts.items(), key=lambda x:-x[1])[:8])}
    </div>
  </div>
  <div class="card">
    <div class="card-title">Data Sources</div>
    <div class="stat-row">
      {''.join(f'<div class="stat-chip"><span class="num">{cnt:,}</span><span class="lbl">{src}</span></div>' for src, cnt in source_counts.items())}
    </div>
  </div>
</div>
<script>
var pvals = {json.dumps(pchembl_vals[:3000])};
var bins={{}};
pvals.forEach(v=>{{var b=(Math.floor(v*2)/2).toFixed(1);bins[b]=(bins[b]||0)+1;}});
var bL=Object.keys(bins).sort((a,b)=>+a-+b), bD=bL.map(k=>bins[k]);

Chart.defaults.color='#3a4060';
Chart.defaults.borderColor='rgba(255,255,255,0.05)';

new Chart(document.getElementById('pchemblChart'),{{
  type:'bar',
  data:{{labels:bL,datasets:[{{data:bD,
    backgroundColor:bL.map(v=>+v>=9?'rgba(30,201,122,.75)':+v>=7?'rgba(245,166,35,.75)':'rgba(64,128,255,.65)'),
    borderRadius:3,borderSkipped:false,barPercentage:.85}}]}},
  options:{{responsive:true,maintainAspectRatio:true,
    plugins:{{legend:{{display:false}},tooltip:{{backgroundColor:'#1a2236',
      titleColor:'#eaedf5',bodyColor:'#8891a8',borderColor:'rgba(255,255,255,.1)',borderWidth:1}}}},
    scales:{{
      x:{{title:{{display:true,text:'pChEMBL',font:{{size:10}}}},
         ticks:{{font:{{size:9}},maxRotation:0,autoSkip:true}},
         grid:{{display:false}},border:{{color:'rgba(255,255,255,.05)'}}}},
      y:{{title:{{display:true,text:'Count',font:{{size:10}}}},
         ticks:{{font:{{size:9}}}},grid:{{color:'rgba(255,255,255,.04)'}},
         border:{{color:'rgba(255,255,255,.05)'}}}}
    }}
  }}
}});

var mL={json.dumps(list(method_counts.keys()))};
var mD={json.dumps(list(method_counts.values()))};
new Chart(document.getElementById('methodChart'),{{
  type:'doughnut',
  data:{{labels:mL,datasets:[{{data:mD,
    backgroundColor:['#4080ff','#8b80f5','#1ec97a','#f5a623','#f5605c'],
    borderWidth:0,hoverOffset:4}}]}},
  options:{{responsive:true,maintainAspectRatio:true,cutout:'60%',
    plugins:{{
      legend:{{display:true,position:'right',
        labels:{{color:'#5a6278',font:{{size:10}},boxWidth:10,padding:10}}}},
      tooltip:{{backgroundColor:'#1a2236',titleColor:'#eaedf5',
        bodyColor:'#8891a8',borderColor:'rgba(255,255,255,.1)',borderWidth:1}}
    }}
  }}
}});
</script>
</body></html>
""", height=560)
    else:
        st.info("No bioactivity data available.")


# ───────────────────────────────────────────────────────────────────────────
#  TAB: LIGANDS
# ───────────────────────────────────────────────────────────────────────────
with tab_lig:
    if report.ligand_summary:
        rows_html = ""
        for i, lig in enumerate(report.ligand_summary[:60], 1):
            p = lig.best_pchembl
            pc_color = ("#1ec97a" if p and p >= 9 else
                        "#f5a623" if p and p >= 7 else
                        "#f5605c" if p else "#4a5168")
            pc_str  = f"{p:.2f}" if p else "—"
            nm_str  = f"{lig.best_activity_value_nM:.2f}" if lig.best_activity_value_nM else "—"
            src_badges = "".join(
                f'<span style="display:inline-block;padding:1px 7px;border-radius:4px;font-size:10px;margin:1px;'
                f'background:rgba(30,201,122,.12);color:#2dcf8a">{s}</span>'
                for s in lig.sources)
            type_badge = (f'<span style="display:inline-block;padding:1px 7px;border-radius:4px;'
                          f'font-size:10px;background:rgba(64,128,255,.12);color:#6b9ef8">'
                          f'{lig.best_activity_type}</span>') if lig.best_activity_type else "—"
            chembl_lnk = (f'<a href="https://www.ebi.ac.uk/chembl/compound_report_card/{lig.chembl_id}"'
                          f' target="_blank" style="color:#4f8ef7;text-decoration:none;'
                          f'font-family:monospace;font-size:10px">{lig.chembl_id}</a>'
                          ) if lig.chembl_id else ""
            smiles_s = (lig.smiles[:42] + "…") if len(lig.smiles) > 42 else lig.smiles

            rows_html += f"""
<tr>
  <td style="color:#2d3450;font-size:11px;width:32px">{i}</td>
  <td><div style="color:#d8dce8;font-size:12.5px">{lig.name or "—"}</div>
      <div style="margin-top:1px">{chembl_lnk}</div></td>
  <td>{type_badge}</td>
  <td style="text-align:right;font-family:monospace;font-size:11px;color:#8891a8">{nm_str}</td>
  <td style="text-align:right;font-family:monospace;font-weight:600;color:{pc_color}">{pc_str}</td>
  <td style="text-align:center;font-family:monospace;font-size:11px;color:#5a6278">{lig.num_assays}</td>
  <td>{src_badges}</td>
  <td style="font-family:monospace;font-size:10px;color:#3a4060;max-width:180px;
      overflow:hidden;text-overflow:ellipsis;white-space:nowrap" title="{lig.smiles}">{smiles_s}</td>
</tr>"""

        st.markdown(f"""
<style>
.lig-wrap {{background:#0b1020;border:1px solid rgba(255,255,255,.07);border-radius:10px;overflow:hidden}}
.lig-wrap table {{width:100%;border-collapse:collapse;font-size:12.5px}}
.lig-wrap th {{
  padding:8px 10px;font-size:10px;font-weight:600;color:#2d3450;
  text-transform:uppercase;letter-spacing:.07em;
  border-bottom:1px solid rgba(255,255,255,.06);background:#080d18
}}
.lig-wrap td {{padding:7px 10px;border-bottom:1px solid rgba(255,255,255,.035)}}
.lig-wrap tr:last-child td {{border-bottom:none}}
.lig-wrap tr:hover td {{background:rgba(255,255,255,.018)}}
.lig-head {{display:flex;justify-content:space-between;align-items:center;
            padding:.9rem 1.1rem;border-bottom:1px solid rgba(255,255,255,.06)}}
.lig-head-title {{font-size:12px;font-weight:600;color:#eaedf5;letter-spacing:-.01em}}
.lig-count {{font-size:10px;padding:2px 9px;border-radius:99px;
             background:rgba(64,128,255,.12);color:#6b9ef8}}
</style>
<div class="lig-wrap">
  <div class="lig-head">
    <div class="lig-head-title">Top ligands by potency</div>
    <span class="lig-count">{min(60, len(report.ligand_summary))} of {len(report.ligand_summary)}</span>
  </div>
  <div style="overflow-x:auto">
  <table>
    <thead><tr>
      <th>#</th><th>Name / ChEMBL</th><th>Type</th>
      <th style="text-align:right">nM</th>
      <th style="text-align:right">pChEMBL</th>
      <th style="text-align:center">Assays</th>
      <th>Sources</th><th>SMILES</th>
    </tr></thead>
    <tbody>{rows_html}</tbody>
  </table>
  </div>
</div>
""", unsafe_allow_html=True)
    else:
        st.info("No ligand data.")


# ───────────────────────────────────────────────────────────────────────────
#  TAB: PDB STRUCTURES
# ───────────────────────────────────────────────────────────────────────────
with tab_pdb:
    if report.pdb_structures:
        method_style = {
            "X-RAY DIFFRACTION":  ("rgba(64,128,255,.13)", "#6b9ef8"),
            "ELECTRON MICROSCOPY":("rgba(139,128,245,.13)","#a89cf5"),
            "SOLUTION NMR":       ("rgba(30,201,122,.13)", "#2dcf8a"),
            "NEUTRON DIFFRACTION":("rgba(245,166,35,.13)", "#f5b83a"),
        }
        rows_html = ""
        for s in report.pdb_structures:
            bg, fg = method_style.get(s.method.value, ("rgba(255,255,255,.06)","#8891a8"))
            res_s   = f"{s.resolution:.2f} Å" if s.resolution else "—"
            ligs_s  = ", ".join(f'<span style="font-family:monospace;font-size:10px;padding:1px 6px;'
                                f'border-radius:3px;background:rgba(30,201,122,.1);color:#2dcf8a">'
                                f'{l.ligand_id}</span>' for l in s.ligands) or "—"
            title_s = (s.title[:95] + "…") if len(s.title) > 95 else s.title
            rows_html += f"""
<tr>
  <td><a href="https://www.rcsb.org/structure/{s.pdb_id}" target="_blank"
      style="color:#4f8ef7;text-decoration:none;font-family:monospace;font-size:12px;
             font-weight:500">{s.pdb_id}</a></td>
  <td><span style="display:inline-block;padding:2px 8px;border-radius:4px;font-size:10.5px;
              background:{bg};color:{fg}">{s.method.value}</span></td>
  <td style="text-align:right;font-family:monospace;font-size:11px;color:#8891a8">{res_s}</td>
  <td style="font-size:11px;color:#3a4060">{s.release_date or "—"}</td>
  <td>{ligs_s}</td>
  <td style="font-size:11px;color:#5a6278;max-width:300px;overflow:hidden;
      text-overflow:ellipsis;white-space:nowrap">{title_s}</td>
</tr>"""

        st.markdown(f"""
<style>
.pdb-wrap {{background:#0b1020;border:1px solid rgba(255,255,255,.07);border-radius:10px;overflow:hidden}}
.pdb-wrap table {{width:100%;border-collapse:collapse;font-size:12px}}
.pdb-wrap th {{padding:8px 10px;font-size:10px;font-weight:600;color:#2d3450;
               text-transform:uppercase;letter-spacing:.07em;
               border-bottom:1px solid rgba(255,255,255,.06);background:#080d18}}
.pdb-wrap td {{padding:7px 10px;border-bottom:1px solid rgba(255,255,255,.035)}}
.pdb-wrap tr:last-child td {{border-bottom:none}}
.pdb-wrap tr:hover td {{background:rgba(255,255,255,.018)}}
.pdb-head {{display:flex;justify-content:space-between;align-items:center;
            padding:.9rem 1.1rem;border-bottom:1px solid rgba(255,255,255,.06)}}
</style>
<div class="pdb-wrap">
  <div class="pdb-head">
    <span style="font-size:12px;font-weight:600;color:#eaedf5">PDB Structures</span>
    <span style="font-size:10px;padding:2px 9px;border-radius:99px;
                 background:rgba(64,128,255,.12);color:#6b9ef8">{report.num_pdb_structures}</span>
  </div>
  <div style="overflow-x:auto">
  <table>
    <thead><tr>
      <th>PDB ID</th><th>Method</th>
      <th style="text-align:right">Resolution</th>
      <th>Date</th><th>Ligands</th><th>Title</th>
    </tr></thead>
    <tbody>{rows_html}</tbody>
  </table>
  </div>
</div>
""", unsafe_allow_html=True)
    else:
        st.info("No PDB structures found.")


# ───────────────────────────────────────────────────────────────────────────
#  TAB: AI AGENT
# ───────────────────────────────────────────────────────────────────────────
with tab_ai:
    st.markdown("""
<div style="background:#0b1020;border:1px solid rgba(255,255,255,.07);border-radius:10px;
     padding:1.25rem 1.5rem;margin-bottom:14px">
  <div style="font-size:13px;font-weight:600;color:#eaedf5;margin-bottom:5px">Claude AI Analysis</div>
  <div style="font-size:12px;color:#4a5168;line-height:1.65">
    Ask Claude to interpret the aggregated target data — druggability, inhibitor scaffolds,
    structural insights, or any custom question.
    Set your API key in the sidebar.
  </div>
</div>
""", unsafe_allow_html=True)

    question = st.text_area(
        "question",
        placeholder=(
            "Leave blank for a full analysis…\n"
            "Or ask something specific:\n"
            "  · What are the most potent inhibitor scaffolds?\n"
            "  · Which PDB structures are best for covalent docking?\n"
            "  · Summarise the resistance mutation landscape"
        ),
        height=110,
        label_visibility="collapsed",
    )

    c1, c2 = st.columns([1, 5])
    with c1:
        run_ai = st.button("Analyse", type="primary")

    if run_ai:
        key = api_key_input.strip() or os.environ.get("ANTHROPIC_API_KEY", "")
        if not key:
            st.warning("Enter your Anthropic API key in the sidebar.")
        else:
            with st.spinner("Asking Claude…"):
                from targetrecon.agent import analyze_async
                try:
                    result = asyncio.run(analyze_async(
                        report,
                        question=question.strip() or None,
                        api_key=key,
                        model=ai_model,
                    ))
                    st.session_state["ai_analysis"] = result
                except Exception as exc:
                    st.error(f"AI error: {exc}")

    if "ai_analysis" in st.session_state:
        analysis_text = st.session_state["ai_analysis"]
        # Escape HTML
        safe = analysis_text.replace("&","&amp;").replace("<","&lt;").replace(">","&gt;")
        st.markdown(f"""
<div style="background:#0b1020;border:1px solid rgba(64,128,255,.2);border-radius:10px;
     padding:1.4rem 1.6rem;margin-top:12px;
     box-shadow:0 0 30px rgba(64,128,255,.06) inset">
  <div style="font-size:10px;color:#2d4080;text-transform:uppercase;letter-spacing:.08em;
              font-weight:600;margin-bottom:.9rem">Claude Analysis · {ai_model}</div>
  <div style="font-size:13px;color:#9aa4bc;line-height:1.8;white-space:pre-wrap">{safe}</div>
</div>
""", unsafe_allow_html=True)

        col_save, _ = st.columns([1, 4])
        with col_save:
            if st.button("Embed in report files"):
                from targetrecon.core import save_html, save_json
                report.ai_analysis = analysis_text
                base = gene.replace(" ", "_")
                save_html(report, f"{base}_report.html")
                save_json(report, f"{base}_report.json")
                st.success(f"Saved {base}_report.html / .json")


# ═══════════════════════════════════════════════════════════════════════════
#  EXPORT ROW
# ═══════════════════════════════════════════════════════════════════════════
st.markdown("<div style='height:.5rem'></div>", unsafe_allow_html=True)
ec = st.columns(3)

with ec[0]:
    if export_json_cb:
        st.download_button("↓ JSON", data=report.model_dump_json(indent=2),
                           file_name=f"{gene}_report.json", mime="application/json")
with ec[1]:
    if export_html_cb:
        try:
            from targetrecon.report import render_html
            st.download_button("↓ HTML report", data=render_html(report),
                               file_name=f"{gene}_report.html", mime="text/html")
        except Exception as exc:
            st.warning(f"HTML export: {exc}")
with ec[2]:
    if export_sdf_cb:
        try:
            from targetrecon.core import save_sdf
            import tempfile
            with tempfile.NamedTemporaryFile(suffix=".sdf", delete=False) as tmp:
                save_sdf(report, tmp.name, top_n=20)
                sdf_bytes = Path(tmp.name).read_bytes()
            st.download_button("↓ SDF ligands", data=sdf_bytes,
                               file_name=f"{gene}_ligands.sdf",
                               mime="chemical/x-mdl-sdfile")
        except Exception as exc:
            st.warning(f"SDF: {exc}")

# ── Footer ──
st.markdown(
    "<div style='text-align:center;font-size:10.5px;color:#1a2040;margin-top:2.5rem;"
    "padding-top:1rem;border-top:1px solid rgba(255,255,255,0.04)'>"
    "TargetRecon v0.1.0 &nbsp;·&nbsp; "
    "UniProt · RCSB PDB · AlphaFold DB · ChEMBL · BindingDB"
    "</div>",
    unsafe_allow_html=True,
)
