import streamlit as st
from io import BytesIO
from datetime import datetime

from utils.pdf_utils import extract_text
from clients.azure_client import AzureClient
from clients.gemini_client import GeminiClient

from agents.tariff_agent import TariffTradeAgent
from agents.sales_agent import SalesAgent
from agents.supply_chain_agent import SupplyChainAgent
from agents.overall_agent import OverallAgent
from agents.enhanced_chat_agent import EnhancedChatAgent

def main():
    st.set_page_config(page_title="Macy's Document Analysis Pro", layout="wide")
    st.title("📄 Macy's Document Analysis & Chat Tool")

    # Mode selection (Azure or Gemini)
    provider_select = st.radio("Select AI Provider", ["Azure GPT", "Google Gemini"])

    # Session Initialization
    if "session" not in st.session_state:
        st.session_state.session = {
            'uploaded_files': {},
            'processed_files_overall': {},
            'processed_files_tariff': {},
            'processed_files_sales': {},
            'processed_files_supplychain': {},
            'active_file': None,
            'active_topic': None,
            'topic_details_cache': {},
            'chat_history': [],
            'consolidated_summary_overall': None,
            'consolidated_summary_tariff': None,
            'consolidated_summary_sales': None,
            'consolidated_summary_supplychain': None,
            'last_analysis_mode': None
        }

    if "client" not in st.session_state or st.session_state.get("provider") != provider_select:
        # Initialize clients and agents based on selection
        if provider_select == "Azure GPT":
            st.session_state.client = AzureClient()
            is_azure = True
        else:
            st.session_state.client = GeminiClient()
            is_azure = False

        # Setup agents
        st.session_state.agent_overall = OverallAgent(st.session_state.client, is_azure)
        st.session_state.agent_tariff = TariffTradeAgent(st.session_state.client, is_azure)
        st.session_state.agent_sales = SalesAgent(st.session_state.client, is_azure)
        st.session_state.agent_supplychain = SupplyChainAgent(st.session_state.client, is_azure)
        st.session_state.chat_agent = EnhancedChatAgent(st.session_state.client, is_azure)
        st.session_state.provider = provider_select

    sess = st.session_state.session

    # --- File Upload Section ---
    st.subheader("1. Upload Documents")
    uploaded_files = st.file_uploader(
        "Upload Macy's earnings transcript PDFs",
        type=["pdf"],
        accept_multiple_files=True,
        key="file_uploader",
    )
    if uploaded_files:
        for file in uploaded_files:
            if file.name not in sess['uploaded_files']:
                sess['uploaded_files'][file.name] = file.getvalue()

    # --- Analysis Buttons Section ---
    st.subheader("2. Analyze Documents")
    col0, col1, col2, col3 = st.columns(4)
    analyze_overall = col0.button("📑 Overall Concise Summary")
    analyze_tariff = col1.button("🔍 Analyze Tariffs & Trade")
    analyze_sales = col2.button("📈 Analyze Sales & Consumer Behavior")
    analyze_supplychain = col3.button("🚚 Analyze Supply Chain & Logistics")

    mode = None
    agent = None
    processed_files = None

    if analyze_overall or analyze_tariff or analyze_sales or analyze_supplychain:
        if not sess['uploaded_files']:
            st.error("Please upload documents before analyzing.")
            st.stop()

        if analyze_overall:
            mode = "overall"
            agent = st.session_state.agent_overall
            processed_files = sess['processed_files_overall']
        elif analyze_tariff:
            mode = "tariff"
            agent = st.session_state.agent_tariff
            processed_files = sess['processed_files_tariff']
        elif analyze_sales:
            mode = "sales"
            agent = st.session_state.agent_sales
            processed_files = sess['processed_files_sales']
        elif analyze_supplychain:
            mode = "supplychain"
            agent = st.session_state.agent_supplychain
            processed_files = sess['processed_files_supplychain']

        with st.spinner(f"Analyzing {mode} documents..."):
            for filename, file_bytes in sess['uploaded_files'].items():
                if filename not in processed_files:
                    try:
                        file_obj = BytesIO(file_bytes)
                        file_obj.name = filename
                        text = extract_text(file_obj)
                        if text:
                            topics = agent.analyze_document(text)
                            processed_files[filename] = {
                                "text": text,
                                "topics": topics,
                                "context": text,
                            }
                            st.toast(f"✅ Processed {filename}")
                        else:
                            st.error(f"❌ Failed to extract text for {filename}")
                    except Exception as e:
                        st.error(f"Error processing {filename}: {str(e)}")

        with st.spinner("Generating consolidated summary..."):
            summary = agent.generate_consolidated_summary_from_topics(processed_files)
            if mode == "overall":
                sess['consolidated_summary_overall'] = summary
            elif mode == "tariff":
                sess['consolidated_summary_tariff'] = summary
            elif mode == "sales":
                sess['consolidated_summary_sales'] = summary
            elif mode == "supplychain":
                sess['consolidated_summary_supplychain'] = summary

        sess['last_analysis_mode'] = mode
        sess['active_file'] = None
        sess['active_topic'] = None

        st.success(f"Analysis and summary generated for {mode}.")

    # --- Show consolidated summary and topics ---
    last_mode = sess['last_analysis_mode']
    if last_mode is None:
        st.info("Select an analysis type above to get started.")
        return

    if last_mode == "overall":
        processed_files = sess['processed_files_overall']
        consolidated_summary = sess['consolidated_summary_overall']
        sidebar_header = "Overall Topics"
        main_header = "🌟 Consolidated Executive Summary"
        agent = st.session_state.agent_overall
    elif last_mode == "tariff":
        processed_files = sess['processed_files_tariff']
        consolidated_summary = sess['consolidated_summary_tariff']
        sidebar_header = "Tariff Topics"
        main_header = "🌟 Consolidated Tariff & Trade Summary"
        agent = st.session_state.agent_tariff
    elif last_mode == "sales":
        processed_files = sess['processed_files_sales']
        consolidated_summary = sess['consolidated_summary_sales']
        sidebar_header = "Sales Topics"
        main_header = "🌟 Consolidated Sales & Consumer Behavior Summary"
        agent = st.session_state.agent_sales
    else:  # supplychain
        processed_files = sess['processed_files_supplychain']
        consolidated_summary = sess['consolidated_summary_supplychain']
        sidebar_header = "Supply Chain Topics"
        main_header = "🌟 Consolidated Supply Chain & Logistics Summary"
        agent = st.session_state.agent_supplychain

    st.header(main_header)
    if consolidated_summary:
        st.markdown(consolidated_summary)
    else:
        st.info(f"No consolidated summary available for {last_mode.capitalize()} yet.")

    st.markdown("---")

    st.sidebar.header(sidebar_header)
    
    if last_mode == "overall":
        # Aggregate topics across all documents
        topics_by_file = {}
        for filename, filedata in processed_files.items():
            for topic in filedata["topics"]:
                topics_by_file.setdefault(topic['name'], []).append({
                    'file': filename,
                    'score': topic['score']
                })

        # Display aggregated topics
        for topic_name, occurrences in sorted(topics_by_file.items(), 
                                           key=lambda x: max(x[1], key=lambda y: y['score'])['score'], 
                                           reverse=True):
            total_score = sum(occ['score'] for occ in occurrences)
            file_count = len(occurrences)
            btn_label = f"{topic_name} (📈 {total_score} | 📁 {file_count})"
            
            if st.sidebar.button(
                btn_label,
                key=f"overall_topic_{topic_name}",
                use_container_width=True,
            ):
                sess['active_topic'] = topic_name
    else:
        # Original per-file topic display
        for filename, filedata in processed_files.items():
            expanded = (filename == sess['active_file'])
            with st.sidebar.expander(f"📄 {filename}", expanded=expanded):
                topics = sorted(filedata["topics"], key=lambda t: t["score"], reverse=True)
                for topic in topics:
                    is_selected = (
                        sess['active_file'] == filename and sess['active_topic'] == topic['name']
                    )
                    style = "primary" if is_selected else "secondary"

                    if st.button(
                        f"• {topic['name']} (Score: {topic['score']})",
                        key=f"{last_mode}_topic_{filename}_{topic['name']}",
                        type=style,
                        use_container_width=True,
                    ):
                        sess['active_file'] = filename
                        sess['active_topic'] = topic['name']

    st.subheader("Detailed Topic Analysis")
    if last_mode == "overall" and sess['active_topic']:
        # Cross-document topic analysis
        st.subheader(f"Cross-Document Analysis: {sess['active_topic']}")
        
        # Collect all relevant mentions
        mentions = []
        for filename, filedata in processed_files.items():
            for topic in filedata["topics"]:
                if topic['name'] == sess['active_topic']:
                    mentions.append({
                        'file': filename,
                        'summary': topic['summary'],
                        'score': topic['score'],
                        'context': filedata['context']
                    })

        # Display prevalence metrics
        with st.expander("📊 Topic Prevalence Across Documents"):
            cols = st.columns(3)
            cols[0].metric("Total Documents", len(mentions))
            cols[1].metric("Average Relevance", f"{sum(m['score'] for m in mentions)/len(mentions):.1f}")
            cols[2].metric("First Mentioned", mentions[0]['file'] if mentions else "N/A")

        # Generate deep analysis
        if mentions:
            combined_context = "\n\n".join(
                f"=== {m['file']} ===\n{m['context']}" 
                for m in mentions
            )
            
            key_cache = (last_mode, sess['active_topic'])
            if key_cache in sess['topic_details_cache']:
                st.markdown(sess['topic_details_cache'][key_cache])
            else:
                placeholder = st.empty()
                collected_text = ""
                
                try:
                    for chunk in agent.generate_topic_detail(combined_context, sess['active_topic']):
                        if chunk:
                            collected_text = chunk
                            if "▌" in collected_text:
                                # Streaming in progress
                                placeholder.markdown(collected_text)
                            else:
                                # Final chunk
                                placeholder.markdown(collected_text)
                                sess['topic_details_cache'][key_cache] = collected_text
                except Exception as e:
                    st.error(f"Error generating analysis: {str(e)}")
                    sess['topic_details_cache'][key_cache] = f"Error: {str(e)}"
        else:
            st.warning("No document mentions found for this topic")
    
    elif sess['active_file'] and sess['active_topic']:
        # Original single-document analysis
        key_cache = (last_mode, sess['active_file'], sess['active_topic'])
        if key_cache in sess['topic_details_cache']:
            st.markdown(sess['topic_details_cache'][key_cache])
        else:
            placeholder = st.empty()
            collected_text = ""

            try:
                for chunk in agent.generate_topic_detail(
                    processed_files[sess['active_file']]['context'],
                    sess['active_topic'],
                ):
                    if chunk:
                        collected_text = chunk
                        if "▌" in collected_text:
                            placeholder.markdown(collected_text)
                        else:
                            placeholder.markdown(collected_text)
                            sess['topic_details_cache'][key_cache] = collected_text
            except Exception as e:
                st.error(f"Error showing topic detail: {str(e)}")
                sess['topic_details_cache'][key_cache] = f"Error: {str(e)}"
    else:
        st.info("Select a file and topic from the sidebar to view detailed analysis.")

    st.divider()

    # --- Advanced Chat: Tariff & Trade Policies ---
    st.subheader("💬 Advanced Document Analysis (Tariff & Trade)")
    tariff_files = list(sess['processed_files_tariff'].keys())
    selected_files = st.multiselect("Select documents for question answering:", tariff_files)

    for msg in sess['chat_history']:
        with st.chat_message(msg["role"]):
            st.markdown(msg["content"])

    question = st.chat_input("Ask a question about tariffs and trade policies")
    if question:
        if not selected_files:
            st.error("Select one or more documents for context before asking a question.")
            st.stop()

        sess['chat_history'].append({
            "role": "user",
            "content": question,
            "timestamp": datetime.utcnow().isoformat(),
        })

        if len(selected_files) == 1:
            context = sess['processed_files_tariff'][selected_files[0]]['context']
        else:
            context = "\n\n".join([
                f"=== Document: {fname} ===\n{sess['processed_files_tariff'][fname]['context']}"
                for fname in selected_files
            ])

        try:
            answer, q_type = st.session_state.chat_agent.generate_answer(question, context)
            sess['chat_history'].append({
                "role": "assistant",
                "content": answer,
                "timestamp": datetime.utcnow().isoformat(),
                "analysis_type": q_type
            })
            st.chat_message("assistant").markdown(answer)
        except Exception as e:
            st.error(f"Error during chat: {str(e)}")
            sess['chat_history'].append({
                "role": "assistant",
                "content": f"Error: {str(e)}",
                "timestamp": datetime.utcnow().isoformat(),
            })

    if st.button("🔄 Reset Session", type="secondary"):
        preserved_keys = [
            "client", "agent_overall", "agent_tariff", 
            "agent_sales", "agent_supplychain", "chat_agent", "provider"
        ]
        preserved = {k: st.session_state[k] for k in preserved_keys if k in st.session_state}
        st.session_state.clear()
        st.session_state.update(preserved)
        st.session_state.session = {
            'uploaded_files': {},
            'processed_files_overall': {},
            'processed_files_tariff': {},
            'processed_files_sales': {},
            'processed_files_supplychain': {},
            'active_file': None,
            'active_topic': None,
            'topic_details_cache': {},
            'chat_history': [],
            'consolidated_summary_overall': None,
            'consolidated_summary_tariff': None,
            'consolidated_summary_sales': None,
            'consolidated_summary_supplychain': None,
            'last_analysis_mode': None,
        }
        st.experimental_rerun()

if __name__ == "__main__":
    main()

when people clicl on topics topic must apper in front of it we do not need to scroll down and see that