import json
import pandas as pd
import streamlit as st
from utils.dataframe import (
_normalize_list, _to_dataframe, _mean_effectiveness, _search_dataframe, safe_dataframe
)
def render_analyzer_results(analysis: dict, prefix: str = "") -> None:
if not isinstance(analysis, dict) or not analysis:
st.warning("No analysis available.")
return
st.markdown("""
""", unsafe_allow_html=True)
va = analysis.get("video_analysis", {}) or {}
storyboard = analysis.get("storyboard", []) or []
script = analysis.get("script", []) or []
metrics = va.get("video_metrics", []) or []
mean_score = _mean_effectiveness(metrics)
mcol1, mcol2, mcol3, mcol4 = st.columns([1,1,1,1])
with mcol1:
st.markdown(f'
', unsafe_allow_html=True)
with mcol2:
st.markdown(f'Dialogue Lines
{len(script)}
', unsafe_allow_html=True)
with mcol3:
st.markdown(f'Avg Effectiveness
{mean_score}/10
', unsafe_allow_html=True)
with mcol4:
st.markdown(f'Improvements
{len(analysis.get("timestamp_improvements", []) or [])}
', unsafe_allow_html=True)
colA, colB = st.columns([1.3,1])
with colA:
with st.container():
st.markdown("### Executive Summary")
c1, c2 = st.columns(2)
with c1:
with st.expander("Brief", expanded=True):
st.write(analysis.get("brief", "N/A"))
with st.expander("Caption Details", expanded=False):
st.write(analysis.get("caption_details", "N/A"))
with c2:
hook = analysis.get("hook", {}) or {}
with st.expander("Hook", expanded=True):
st.markdown(f"**Opening:** {hook.get('hook_text','N/A')}")
st.markdown(f"**Principle:** {hook.get('principle','N/A')}")
adv = _normalize_list(hook.get("advantages"))
if adv:
st.markdown("**Advantages:**")
st.markdown("\n".join([f"- {a}" for a in adv]))
st.divider()
st.markdown("### Narrative & Copy Frameworks")
with st.expander("Framework Analysis", expanded=True):
st.write(analysis.get("framework_analysis", "N/A"))
with colB:
st.markdown("### Snapshot")
with st.container():
st.caption("Top Drivers")
st.markdown(f'{va.get("effectiveness_factors","N/A")}', unsafe_allow_html=True)
st.markdown("")
with st.container():
st.caption("Psychological Triggers")
st.markdown(f'{va.get("psychological_triggers","N/A")}', unsafe_allow_html=True)
st.markdown("")
with st.container():
st.caption("Target Audience")
st.markdown(f'{va.get("target_audience","N/A")}', unsafe_allow_html=True)
st.divider()
tabs = st.tabs(["Storyboard", "Script", "Scored Metrics", "Improvements", "Raw JSON"])
with tabs[0]:
q = st.text_input("Search storyboard", key=f"{prefix}_storyboard")
if storyboard:
df = _to_dataframe(storyboard, {"timeline": "Timeline", "scene": "Scene", "visuals": "Visuals", "dialogue": "Dialogue", "camera": "Camera", "sound_effects": "Sound Effects"})
df = _search_dataframe(df, q)
st.dataframe(safe_dataframe(df), use_container_width=True, height=480)
else:
st.info("No storyboard available.")
with tabs[1]:
q2 = st.text_input("Search script", key=f"{prefix}_script")
if script:
df = _to_dataframe(script, {"timeline": "Timeline", "dialogue": "Dialogue"})
df = _search_dataframe(df, q2)
st.dataframe(safe_dataframe(df), use_container_width=True, height=480)
else:
st.info("No script breakdown available.")
with tabs[2]:
q3 = st.text_input("Search metrics", key=f"{prefix}_metrics")
if metrics:
dfm = _to_dataframe(metrics, {"timestamp": "Timestamp", "element": "Element", "current_approach": "Current Approach", "effectiveness_score": "Effectiveness Score", "notes": "Notes"})
dfm = _search_dataframe(dfm, q3)
st.dataframe(dfm, use_container_width=True, height=480)
else:
st.info("No video metrics available.")
with tabs[3]:
improvements = analysis.get("timestamp_improvements", []) or []
q4 = st.text_input("Search improvements", key=f"{prefix}_improvements")
if improvements:
imp_df = _to_dataframe(improvements, {"timestamp": "Timestamp", "current_element": "Current Element", "improvement_type": "Improvement Type", "recommended_change": "Recommended Change", "expected_impact": "Expected Impact", "priority": "Priority"})
if "Priority" in imp_df.columns:
order = pd.CategoricalDtype(["High", "Medium", "Low"], ordered=True)
imp_df["Priority"] = imp_df["Priority"].astype(order)
if "Timestamp" in imp_df.columns:
imp_df = imp_df.sort_values(["Priority", "Timestamp"])
imp_df = _search_dataframe(imp_df, q4)
st.dataframe(imp_df, use_container_width=True, height=480)
else:
st.info("No timestamp-based improvements available.")
with tabs[4]:
pretty = json.dumps(analysis, indent=2, ensure_ascii=False)
st.code(pretty, language="json")
st.download_button("Download JSON", data=pretty.encode("utf-8"), file_name="ad_analysis.json", mime="application/json", use_container_width=True)