import os
import tempfile
import streamlit as st
from openai import AzureOpenAI
from git import Repo, GitCommandError
import mimetypes
import tiktoken

class FileHandler:
    def __init__(self):
        self.file_queue = []
        self.processed_files = set()
        self.encoder = tiktoken.get_encoding("cl100k_base")
        self.repo_path = None  # Initialize repo_path
    
    def scan_repository(self, repo_path):
        """Scan repository and create processing queue"""
        self.repo_path = repo_path  # Store repo_path as instance variable
        self.file_queue = []
        for root, _, files in os.walk(repo_path):
            for file in files:
                file_path = os.path.join(root, file)
                mime_type, _ = mimetypes.guess_type(file_path)
                if mime_type and mime_type.startswith('text'):
                    self.file_queue.append(file_path)
    
    def get_next_chunk(self, max_tokens=30000):
        """Get next chunk of files within token limits"""
        chunk = []
        current_tokens = 0
        
        while self.file_queue:
            file_path = self.file_queue[0]
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    content = f.read()
                tokens = len(self.encoder.encode(content))
                
                # Use stored repo_path for relative paths
                rel_path = os.path.relpath(file_path, self.repo_path)
                
                if current_tokens + tokens > max_tokens:
                    if not chunk:  # Handle single large file
                        content = content[:int(max_tokens*3.5)]  # Approx 30k tokens
                        self.file_queue.pop(0)
                    return chunk
                
                chunk.append({
                    'path': rel_path,  # Use calculated relative path
                    'content': content
                })
                current_tokens += tokens
                self.file_queue.pop(0)
                self.processed_files.add(file_path)
                
            except Exception as e:
                st.error(f"Error reading {file_path}: {str(e)}")
                self.file_queue.pop(0)
        
        return chunk if chunk else None

class SummaryAgent:
    def __init__(self, client, deployment):
        self.client = client
        self.deployment = deployment
    
    def generate_chunk_summary(self, chunk):
        """Generate summary for a chunk of files"""
        system_msg = """You are a senior software architect. Analyze these files and provide a concise technical summary focusing on:
        - Key functionality
        - Architectural patterns
        - Critical components
        - Notable dependencies
        Keep summary under 500 words."""
        
        user_content = "Files to analyze:\n\n"
        for file in chunk:
            user_content += f"### {file['path']}\n{file['content'][:5000]}\n\n"

        messages = [
            {"role": "system", "content": system_msg},
            {"role": "user", "content": user_content}
        ]
        
        response = self.client.chat.completions.create(
            model=self.deployment,
            messages=messages,
            temperature=0.2
        )
        return response.choices[0].message.content

class SummaryConsolidator:
    def __init__(self, client, deployment):
        self.client = client
        self.deployment = deployment
    
    def finalize_summary(self, chunk_summaries):
        """Combine chunk summaries into final summary"""
        system_msg = """You are a lead technical writer. Synthesize these partial summaries into a cohesive project overview:
        - Maintain technical accuracy
        - Highlight key architectural decisions
        - Identify core components
        - Note any potential red flags
        Keep final summary under 1000 words."""
        
        user_content = "Partial summaries to combine:\n\n"
        for i, summary in enumerate(chunk_summaries, 1):
            user_content += f"### Part {i}\n{summary}\n\n"

        messages = [
            {"role": "system", "content": system_msg},
            {"role": "user", "content": user_content}
        ]
        
        response = self.client.chat.completions.create(
            model=self.deployment,
            messages=messages,
            temperature=0.1
        )
        return response.choices[0].message.content

class ImprovementAgent:
    def __init__(self, client, deployment):
        self.client = client
        self.deployment = deployment
    
    def generate_improvements(self, final_summary):
        """Generate improvements based on final summary"""
        system_msg = """You are a software quality expert. Provide actionable recommendations:
        - Code quality improvements
        - Architectural enhancements
        - Security considerations
        - Performance optimizations
        Organize by priority with brief rationale for each."""
        
        messages = [
            {"role": "system", "content": system_msg},
            {"role": "user", "content": final_summary}
        ]
        
        response = self.client.chat.completions.create(
            model=self.deployment,
            messages=messages,
            temperature=0.3
        )
        return response.choices[0].message.content

# Streamlit UI Configuration
st.set_page_config(page_title="GitHub Repo Analyzer", layout="wide")

# Sidebar Configuration
with st.sidebar:
    st.header("Settings")
    azure_endpoint = st.text_input("Azure Endpoint", "https://your-resource.openai.azure.com/")
    api_key = st.text_input("API Key", type="password")
    deployment_name = st.text_input("Deployment Name", "gpt-4")
    analysis_mode = st.radio("Analysis Mode", ["Summary", "Improvements"])

# Main Interface
st.title("🤖 GitHub Repository Analyzer")
repo_url = st.text_input("GitHub Repository URL", help="Enter public repository URL")

if repo_url and api_key and azure_endpoint and deployment_name:
    client = AzureOpenAI(
        azure_endpoint=azure_endpoint,
        api_key=api_key,
        api_version="2023-05-15"
    )
    
    if st.button("Start Analysis"):
        with tempfile.TemporaryDirectory() as tmp_dir:
            try:
                # Clone repository
                with st.status("Cloning repository..."):
                    Repo.clone_from(repo_url, tmp_dir)
                
                # Initialize agents
                file_handler = FileHandler()
                summary_agent = SummaryAgent(client, deployment_name)
                consolidator = SummaryConsolidator(client, deployment_name)
                improv_agent = ImprovementAgent(client, deployment_name)
                
                # Scan repository
                with st.status("Scanning repository..."):
                    file_handler.scan_repository(tmp_dir)
                
                chunk_summaries = []
                progress_bar = st.progress(0)
                
                # Process files in chunks
                while True:
                    chunk = file_handler.get_next_chunk()
                    if not chunk:
                        break
                    
                    progress = len(file_handler.processed_files)/len(file_handler.file_queue)
                    progress_bar.progress(min(progress, 1.0))
                    
                    with st.status(f"Analyzing {len(chunk)} files..."):
                        chunk_summary = summary_agent.generate_chunk_summary(chunk)
                        chunk_summaries.append(chunk_summary)
                
                # Generate final output
                if analysis_mode == "Summary":
                    with st.status("Finalizing summary..."):
                        final_summary = consolidator.finalize_summary(chunk_summaries)
                        st.subheader("Comprehensive Summary")
                        st.markdown(final_summary)
                
                elif analysis_mode == "Improvements":
                    with st.status("Generating improvements..."):
                        final_summary = consolidator.finalize_summary(chunk_summaries)
                        improvements = improv_agent.generate_improvements(final_summary)
                        st.subheader("Improvement Recommendations")
                        st.markdown(improvements)
                
                progress_bar.empty()
            
            except GitCommandError as e:
                st.error(f"Cloning failed: {str(e)}")
            except Exception as e:
                st.error(f"Analysis error: {str(e)}")


can you make this code not in single page make the code that looks good and make different files that is good for understanding