import streamlit as st
import openai
import os
from datetime import datetime
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.lib.utils import simpleSplit

# ===== Azure Text Bot Class =====
class AzureTextBot:
    def __init__(self, api_key, endpoint, deployment_id, api_version):
        self.client = openai.AzureOpenAI(
            api_key=api_key,
            api_version=api_version,
            azure_endpoint=endpoint,
        )
        self.deployment_id = deployment_id

    def read_txt_file(self, file_path):
        with open(file_path, "r", encoding="utf-8") as f:
            return f.read()

    def generate_summary(self, context, prompt_type):
        if prompt_type == "Earnings Summary":
            prompt = f"""
You are a financial data assistant. Use **step-by-step extraction** to carefully and accurately generate a fully structured earnings summary based strictly on the input context.

---

**STEP 1: Process the input carefully.**
- Identify **all companies and tickers** mentioned.
- Identify **quarter-ends** (December, January, February).
- Identify exact **% changes** for **day-of-print** and **week-prior-to-print**, including whether they are Up or Down.
- Extract whether companies **beat or missed** on Sales and Adj. EPS.
- Check if FY guidance for **Sales and Adj. EPS** was provided or not.
⚠️ DO NOT add, omit, or infer anything that’s not explicitly written.

---

**STEP 2: Generate the output in the following strict format**:

Earnings Summary  
• In addition to Macy’s, Inc. (M), X companies that we follow reported this week: [List all company names and tickers].  
[State the quarter-end month (Dec/Jan/Feb) for each company based ONLY on input.]

o Trading Day of Print:  
 Up: [ALL companies with exact tickers and percentage gains, sorted from largest to smallest]  
 Down: [ALL companies with exact tickers and percentage losses, sorted from largest to smallest]

o Trading Week Prior to Print:  
 Up: [ALL companies with weekly gains]  
 Down: [ALL companies with weekly losses]

o Results vs. Consensus:  
 Sales: Beat – [Only companies that beat]; Miss – [Only companies that missed]  
 Adj. EPS: Beat – [Only companies that beat]; Miss – [Only companies that missed]  
*[Ticker] did not report adj. EPS (if applicable)*

o Annual Guidance Updates:  
 Sales: Provided by – [Only tickers that provided]; Not provided by – [Only tickers that did not]  
 Adj EPS: Provided by – [Only tickers that provided]; Not provided by – [Only tickers that did not]

---

**STRICT RULES:**  
- Use 100% of the input data with no summarization or rounding.  
- Preserve the exact structure, indentation, bullet points, and symbols (•, ).  
- Sort % change entries by magnitude from largest to smallest.  
- DO NOT hallucinate or infer; only extract and reformat.  
- If multiple files are merged, include ALL companies and data from ALL files.  
- Maintain accuracy even if companies have similar names, tickers, or small variations in performance.

---

Here is the input context:  
{context}
"""


            
        elif prompt_type == "Detailed Hot Topics (Positive / Neutral / Negative)":
            prompt = f"""
You are a financial analyst assistant. Based on the earnings and retail commentary text I provide, produce a **detailed and categorized Hot Topic Summary** using the exact structure below. Your responses must be **descriptive, professional, and well-organized** — **do not use one-liner summaries**. Include **all companies mentioned** in the text and apply the proper sentiment tags only where indicated. Follow this format exactly:

---

**Hot Topics**  
• Start with a paragraph summarizing the overall tone or sentiment across companies (e.g., cautious optimism, softening trends, improving momentum, etc.).

---

1. **Consumer Health Commentary**  
• Begin with a detailed summary paragraph on consumer behavior and demand trends across the companies.  
• Then group company commentary under the following **required sentiment labels**:  
   - **Positive**  
   - **Neutral**  
   - **Negative**  
• Within each sentiment group, use bullet points. Each bullet must begin with the company name in bold, followed by a detailed description of their consumer-related commentary.  

---

2. **QTD Performance**  
• Start with a paragraph summarizing quarter-to-date trends.  
• Then categorize company-specific comments under these headings (required):  
   - **Positive**  
   - **Neutral**  
   - **Negative**  
• Use bullet points under each heading. Each bullet must begin with the company name in bold and describe their QTD trends in detail.  

---

3. **Fiscal Year Expectations**  
• Provide a detailed summary of fiscal year guidance and outlooks (e.g., FY24, FY25).  
• Use bullet points starting with company names in bold, followed by their guidance commentary.

---

4. **Tariff Commentary**  
• Provide a paragraph summarizing how tariffs or trade policies are impacting performance.  
• Then use bullet points beginning with company names in bold, followed by tariff-related commentary.

---

5. **Weather Commentary**  
• Summarize how weather trends are affecting companies.  
• Then list each relevant company in bold with their respective weather-related commentary.

---

6. **Stock Initiations and Re-Ratings**  
• Provide a detailed summary of analyst rating changes or new stock coverage.  
• Use bullet points starting with company names in bold, followed by details of the rating/initiation.

---

7. **Largest Stock Movements**  
• Summarize notable stock price changes across companies, with reasoning if mentioned.  
• Use bullet points starting with company names in bold, followed by details of the movement and drivers.

---

⚠️ Important Notes:  
• Use **Positive / Neutral / Negative** tags **only in the Consumer Health Commentary and QTD Performance sections**.  
• Every section should be **detailed and professional** — **do not summarize in a single sentence**.  
• Use proper bullet formatting and structure.  
• Do not hellucinate or make up information.
• Do not include any disclaimers or unnecessary information.
• If you are combining multiple files, do not exclude any information from any of the files.

---

Here is the text to analyze:  
{context}
"""
        else:
            prompt = f"Summarize this document clearly for investor insight:\n\n{context}"

        messages = [
            {"role": "system", "content": "You are a helpful financial analyst assistant."},
            {"role": "user", "content": prompt}
        ]

        response = self.client.chat.completions.create(
            model=self.deployment_id,
            messages=messages,
            temperature=0
        )
        return response.choices[0].message.content.strip()

# ===== PDF Generation Function =====
def create_pdf(content_dict):
    file_path = os.path.join("temp", f"summary_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf")
    os.makedirs("temp", exist_ok=True)

    c = canvas.Canvas(file_path, pagesize=letter)
    width, height = letter
    margin = 50
    y = height - margin
    line_height = 14
    max_width = width - 2 * margin

    for title, content in content_dict.items():
        if y < margin + 100:
            c.showPage()
            y = height - margin

        c.setFont("Helvetica-Bold", 16)
        c.drawString(margin, y, title)
        y -= line_height * 1.5

        lines = content.split("\n")
        for line in lines:
            stripped_line = line.strip()
            if not stripped_line:
                y -= line_height * 0.5
                continue

            if stripped_line in ["Positive", "Neutral", "Negative"]:
                if y < margin + line_height:
                    c.showPage()
                    y = height - margin
                c.setFont("Helvetica-Bold", 13)
                c.drawString(margin + 10, y, stripped_line)
                y -= line_height * 1.2
                continue

            bullet_indent = 20
            if stripped_line.startswith("•") or stripped_line.startswith("-"):
                text = stripped_line
                c.setFont("Helvetica", 11)
            else:
                text = stripped_line
                c.setFont("Helvetica", 12)

            wrapped = simpleSplit(text, c._fontname, c._fontsize, max_width)
            for wrap_line in wrapped:
                if y < margin + line_height:
                    c.showPage()
                    y = height - margin
                c.drawString(margin + bullet_indent, y, wrap_line)
                y -= line_height

        y -= line_height * 2

    c.save()
    return file_path

# ===== Streamlit UI =====
st.set_page_config(page_title="📈 Macy's Earnings Summary", layout="wide")
st.title("📈 Summarize Macy’s Earnings from Transcript Files")

# Load Azure API credentials
api_key = st.secrets["AZURE_API_KEY"]
endpoint = st.secrets["AZURE_ENDPOINT"]
deployment_id = st.secrets["AZURE_DEPLOYMENT"]
api_version = st.secrets["AZURE_API_VERSION"]

bot = AzureTextBot(api_key, endpoint, deployment_id, api_version)

if "summaries_by_file" not in st.session_state:
    st.session_state.summaries_by_file = {}
if "final_summaries" not in st.session_state:
    st.session_state.final_summaries = {}

uploaded_files = st.file_uploader(
    "Upload one or more `.txt` files with earnings info",
    type=["txt"],
    accept_multiple_files=True
)

if uploaded_files:
    st.markdown("### Select summary types and click Submit:")
    prompt_types = st.multiselect(
        "Select the types of summaries you want to generate",
        ["Earnings Summary", "Detailed Hot Topics (Positive / Neutral / Negative)", "Basic Summary"]
    )

    if st.button("🚀 Submit"):
        if prompt_types:
            with st.spinner("Generating summaries for each file..."):
                summaries_by_file = {}

                for uploaded_file in uploaded_files:
                    file_path = os.path.join("temp", f"{uploaded_file.name}_{datetime.now().strftime('%H%M%S')}.txt")
                    os.makedirs("temp", exist_ok=True)
                    with open(file_path, "wb") as f:
                        f.write(uploaded_file.read())

                    context = bot.read_txt_file(file_path)
                    summaries = {}
                    for ptype in prompt_types:
                        summaries[ptype] = bot.generate_summary(context, ptype)

                    summaries_by_file[uploaded_file.name] = summaries
                    os.remove(file_path)

                st.session_state.summaries_by_file = summaries_by_file
                st.success("✅ File-level summaries generated!")

            with st.spinner("Generating final unified summaries..."):
                final_summaries = {}
                for ptype in prompt_types:
                    combined = ""
                    for fname, summary_dict in summaries_by_file.items():
                        summary = summary_dict.get(ptype, "")
                        combined += f"\n\n--- START OF SUMMARY FROM {fname} ---\n{summary}\n--- END OF SUMMARY ---\n"

                    final_summary = bot.generate_summary(combined, ptype)
                    final_summaries[ptype] = final_summary

                st.session_state.final_summaries = final_summaries
                st.success("🎯 Final combined summaries generated!")

        else:
            st.warning("⚠️ Please select at least one summary type.")

# ===== Display Results =====
if st.session_state.final_summaries:
    st.markdown("## 📊 Final Combined Summary:")
    for ptype, text in st.session_state.final_summaries.items():
        st.subheader(f"📄 {ptype}")
        st.markdown(text)

    pdf_path = create_pdf(st.session_state.final_summaries)
    with open(pdf_path, "rb") as f:
        st.download_button(
            "📥 Download Combined Summary as PDF",
            f,
            file_name="final_combined_summary.pdf",
            mime="application/pdf"
        )

if st.session_state.summaries_by_file:
    with st.expander("📂 View Individual Summaries for Each File"):
        for file_name, summaries in st.session_state.summaries_by_file.items():
            st.markdown(f"### 🗂️ File: `{file_name}`")
            for ptype, summary_text in summaries.items():
                st.markdown(f"**{ptype}**")
                st.markdown(summary_text)

with this code i tryied making chain of thogths gives correct answer but still answer if  i am running twice are different somewhere company name are missgin somer where % are different can you correct the chain of thoughts promt and make my code perfect which can give always a similar type of response means allways correct information in Earning summary as well as Hot topics?