from flask import Blueprint ,jsonify ,request 
from src .chroma .vector_store import get_all_metadatas ,search_documents, insert_documents
from src .rag .embeddings import get_embedding, get_embeddings_batch
from src.rag.ingest import load_pdf, chunk_text
import os
import base64
import re
from google import genai

reports_bp =Blueprint ('reports',__name__ )

# Validation prompt for checking if PDF is a legitimate environmental report
REPORT_VALIDATION_PROMPT = """You are an expert document classifier. Analyze the following text extracted from a PDF and determine if it is a legitimate corporate environmental/sustainability report.

A legitimate report should contain:
1. Company name and branding
2. Environmental metrics (emissions, energy usage, waste, water)
3. Sustainability goals or targets
4. Time periods/years covered
5. Professional report structure

Analyze this text and respond in JSON format:
{
    "is_valid_report": true/false,
    "confidence": "high"/"medium"/"low",
    "company_name": "extracted company name or null",
    "report_year": "extracted year or null",
    "report_type": "sustainability/environmental/impact/ESG/unknown",
    "sector": "Tech/Energy/Automotive/Aerospace/Retail/Manufacturing/Other",
    "key_topics": ["list of main topics covered"],
    "reasoning": "brief explanation of your assessment"
}

TEXT TO ANALYZE:
"""

def validate_report_with_ai(text_content):
    """Use Gemini to validate if the PDF is a legitimate environmental report."""
    try:
        # Take first 15000 chars for validation (enough to assess legitimacy)
        sample_text = text_content[:15000] if len(text_content) > 15000 else text_content
        
        client = genai.Client(api_key=os.environ.get("GOOGLE_API_KEY"))
        response = client.models.generate_content(
            model="gemini-2.0-flash",
            contents=f"{REPORT_VALIDATION_PROMPT}\n{sample_text}"
        )
        
        # Parse the JSON response
        response_text = response.text
        
        # Extract JSON from response
        import json
        json_match = re.search(r'\{[\s\S]*\}', response_text)
        if json_match:
            return json.loads(json_match.group())
        
        return {"is_valid_report": False, "reasoning": "Could not parse AI response"}
    except Exception as e:
        print(f"AI validation error: {e}")
        return {"is_valid_report": False, "reasoning": str(e)}


@reports_bp.route('/upload', methods=['POST'])
def upload_report():
    """Upload and verify a company environmental report PDF."""
    try:
        data = request.json
        pdf_data = data.get('pdf_data')
        company_name = data.get('company_name', '').strip()
        
        if not pdf_data:
            return jsonify({
                'status': 'error',
                'step': 'validation',
                'message': 'No PDF data provided'
            }), 400
        
        # Step 1: Decode PDF
        try:
            # Remove data URL prefix if present
            if ',' in pdf_data:
                pdf_data = pdf_data.split(',')[1]
            pdf_bytes = base64.b64decode(pdf_data)
        except Exception as e:
            return jsonify({
                'status': 'error',
                'step': 'decode',
                'message': f'Failed to decode PDF: {str(e)}'
            }), 400
        
        # Step 2: Extract text from PDF
        import io
        from pypdf import PdfReader
        
        try:
            pdf_file = io.BytesIO(pdf_bytes)
            reader = PdfReader(pdf_file)
            
            all_text = ""
            page_count = len(reader.pages)
            
            for page in reader.pages:
                text = page.extract_text()
                if text:
                    all_text += text + "\n\n"
            
            if len(all_text.strip()) < 500:
                return jsonify({
                    'status': 'error',
                    'step': 'extraction',
                    'message': 'PDF contains insufficient text content. It may be image-based or corrupted.'
                }), 400
                
        except Exception as e:
            return jsonify({
                'status': 'error',
                'step': 'extraction',
                'message': f'Failed to extract text from PDF: {str(e)}'
            }), 400
        
        # Step 3: Validate with AI
        validation = validate_report_with_ai(all_text)
        
        if not validation.get('is_valid_report', False):
            return jsonify({
                'status': 'rejected',
                'step': 'validation',
                'message': 'This does not appear to be a legitimate environmental/sustainability report.',
                'validation': validation
            }), 400
        
        # Step 4: Generate filename
        detected_company = validation.get('company_name') or company_name or 'Unknown'
        detected_year = validation.get('report_year') or '2024'
        report_type = validation.get('report_type', 'sustainability')
        sector = validation.get('sector', 'Other')
        
        # Clean company name for filename
        safe_company = re.sub(r'[^a-zA-Z0-9]', '-', detected_company).lower()
        filename = f"{safe_company}-{detected_year}-{report_type}-report.pdf"
        
        # Step 5: Save PDF to dataset folder
        current_dir = os.path.dirname(os.path.abspath(__file__))
        dataset_dir = os.path.join(current_dir, '..', '..', 'dataset')
        os.makedirs(dataset_dir, exist_ok=True)
        
        file_path = os.path.join(dataset_dir, filename)
        
        # Check if file already exists
        if os.path.exists(file_path):
            # Add timestamp to make unique
            import time
            timestamp = int(time.time())
            filename = f"{safe_company}-{detected_year}-{report_type}-report-{timestamp}.pdf"
            file_path = os.path.join(dataset_dir, filename)
        
        with open(file_path, 'wb') as f:
            f.write(pdf_bytes)
        
        # Step 6: Chunk and embed for RAG
        chunks = chunk_text(all_text, target_length=2000, overlap=100)
        
        if not chunks:
            chunks = [all_text[:4000]]
        
        # Get embeddings in batches
        embeddings = get_embeddings_batch(chunks)
        
        # Create metadata for each chunk
        metadata_list = []
        for i, chunk in enumerate(chunks):
            metadata_list.append({
                'source': filename,
                'company_name': detected_company,
                'year': detected_year,
                'sector': sector,
                'report_type': report_type,
                'chunk_index': i,
                'total_chunks': len(chunks),
                'page_count': page_count,
                'type': 'company_report'
            })
        
        # Insert into ChromaDB
        insert_documents(chunks, embeddings, metadata_list=metadata_list)
        
        return jsonify({
            'status': 'success',
            'message': 'Report verified and uploaded successfully',
            'filename': filename,
            'validation': validation,
            'stats': {
                'page_count': page_count,
                'text_length': len(all_text),
                'chunks_created': len(chunks),
                'company_name': detected_company,
                'year': detected_year,
                'sector': sector,
                'report_type': report_type
            }
        })
        
    except Exception as e:
        print(f"Upload error: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({
            'status': 'error',
            'step': 'unknown',
            'message': str(e)
        }), 500


@reports_bp .route ('/',methods =['GET'])
def get_reports ():
    try :
        metadatas =get_all_metadatas ()

        unique_reports ={}

        for meta in metadatas :
            filename =meta .get ('source')or meta .get ('filename')
            if not filename :
                continue 


            if meta .get ('type')=='incident_report'or filename .startswith ('incident_'):
                continue 


            if filename not in unique_reports :
                company_name ="Unknown"
                year ="N/A"
                sector ="Other"

                lower_name =filename .lower ()


                import re 
                year_match =re .search (r'20\d{2}',lower_name )
                if year_match :
                    year =year_match .group (0 )


                if 'tesla'in lower_name :
                    company_name ="Tesla"
                    sector ="Automotive"
                elif 'google'in lower_name :
                    company_name ="Google"
                    sector ="Tech"
                elif 'apple'in lower_name :
                    company_name ="Apple"
                    sector ="Tech"
                elif 'microsoft'in lower_name :
                    company_name ="Microsoft"
                    sector ="Tech"
                elif 'amazon'in lower_name :
                    company_name ="Amazon"
                    sector ="Tech"
                elif 'boeing'in lower_name :
                    company_name ="Boeing"
                    sector ="Aerospace"
                elif 'ghgp'in lower_name :
                    company_name ="GHGP Data"
                    sector ="Data"
                elif 'salesforce'in lower_name :
                    company_name ="Salesforce"
                    sector ="Tech"
                elif 'hp 'in lower_name or 'hp-'in lower_name :
                    company_name ="HP"
                    sector ="Tech"
                else :

                    parts =re .split (r'[-_.]',filename )
                    if parts :
                        company_name =parts [0 ].capitalize ()
                        if company_name .isdigit ():
                            company_name =parts [1 ].capitalize ()if len (parts )>1 else "Unknown"

                unique_reports [filename ]={
                'company_name':company_name ,
                'year':year ,
                'sector':sector ,
                'greenwashing_score':meta .get ('greenwashing_score',0 ),
                'filename':filename ,
                'title':f"{company_name } {year } Report"
                }

        reports_list =list (unique_reports .values ())
        return jsonify (reports_list )

    except Exception as e :
        print (f"Error fetching reports: {e }")
        import traceback 
        traceback .print_exc ()
        return jsonify ({'error':str (e )}),500 

@reports_bp .route ('/search',methods =['POST'])
def search_reports ():
    data =request .json 
    query =data .get ('query','')

    if not query :
        return jsonify ([])

    try :
        import re 
        query_embedding =get_embedding (query )
        results = search_documents (query_embedding ,num_results =50 )

        query_lower = query .lower ()

        def extract_company_info (filename ):
            company_name ="Unknown"
            year ="N/A"
            sector ="Other"

            lower_name =filename .lower ()


            year_match =re .search (r'20\d{2}',lower_name )
            if year_match :
                year =year_match .group (0 )


            if 'tesla'in lower_name :
                company_name ="Tesla"
                sector ="Automotive"
            elif 'google'in lower_name :
                company_name ="Google"
                sector ="Tech"
            elif 'apple'in lower_name :
                company_name ="Apple"
                sector ="Tech"
            elif 'microsoft'in lower_name :
                company_name ="Microsoft"
                sector ="Tech"
            elif 'amazon'in lower_name :
                company_name ="Amazon"
                sector ="Tech"
            elif 'boeing'in lower_name :
                company_name ="Boeing"
                sector ="Aerospace"
            elif 'ghgp'in lower_name :
                company_name ="GHGP Data"
                sector ="Data"
            elif 'salesforce'in lower_name :
                company_name ="Salesforce"
                sector ="Tech"
            elif 'hp 'in lower_name or 'hp-'in lower_name or lower_name .startswith ('hp'):
                company_name ="HP"
                sector ="Tech"
            else :
                parts =re .split (r'[-_.]',filename )
                if parts :
                    company_name =parts [0 ].capitalize ()
                    if company_name .isdigit ():
                        company_name =parts [1 ].capitalize ()if len (parts )>1 else "Unknown"

            return company_name ,year ,sector 

        output =[]
        seen_filenames =set ()

        for item in results :
            meta =item .get ('metadata',{})
            text =item .get ('text','')

            filename =meta .get ('source')or meta .get ('filename','Unknown')


            if filename in seen_filenames :
                continue 
            seen_filenames .add (filename )

            company_name ,year ,sector =extract_company_info (filename )


            match_boost =0 
            if query_lower in filename .lower ():
                match_boost =1000 
            if query_lower in company_name .lower ():
                match_boost =1000 


            semantic_score =1 /(item .get ('score',1 )+0.001 )if item .get ('score')else 0 

            combined_score =match_boost +semantic_score 


            snippet =text [:300 ]+"..."if len (text )>300 else text 

            output .append ({
            'company_name':company_name ,
            'year':year ,
            'filename':filename ,
            'sector':sector ,
            'greenwashing_score':meta .get ('greenwashing_score',0 ),
            'snippet':snippet ,
            'relevance_score':item .get ('score'),
            '_combined_score':combined_score 
            })


        output .sort (key =lambda x :x .get ('_combined_score',0 ),reverse =True )


        for item in output :
            item .pop ('_combined_score',None )

        return jsonify (output [:20 ])
    except Exception as e :
        print (f"Error searching reports: {e }")
        return jsonify ({'error':str (e )}),500 

@reports_bp .route ('/view/<path:filename>',methods =['GET'])
def view_report_file (filename ):
    import os 
    from flask import send_from_directory 

    current_dir =os .path .dirname (os .path .abspath (__file__ ))
    dataset_dir =os .path .join (current_dir ,'..','..','dataset')

    return send_from_directory (dataset_dir ,filename )


@reports_bp.route('/stats', methods=['GET'])
def get_stats():
    """Get real statistics for the landing page"""
    try:
        # 1. Count Verified Reports (Company Reports)
        metadatas = get_all_metadatas()
        unique_reports = set()
        unique_sectors = set()
        
        for meta in metadatas:
            filename = meta.get('source') or meta.get('filename')
            # Check if it's a company report (not incident)
            if filename and not filename.startswith('incident_') and meta.get('type') != 'incident_report':
                unique_reports.add(filename)
                
                # Count sectors
                sector = meta.get('sector')
                if sector and sector != 'Other':
                    unique_sectors.add(sector)
        
        verified_reports_count = len(unique_reports)
        active_sectors_count = len(unique_sectors)
        
        # Fallback if no specific sectors found but we have reports
        if active_sectors_count == 0 and verified_reports_count > 0:
            active_sectors_count = 1

        # 2. Count Products Scanned / Incidents
        from src.mongo.connection import get_mongo_client
        client = get_mongo_client()
        db = client["ethix"]
        # Count all incidents (users scanning products)
        incidents_count = db["incidents"].count_documents({})
            
        return jsonify({
            "verified_reports": verified_reports_count,
            "incidents_reported": incidents_count,
            "active_sectors": active_sectors_count
        })
    except Exception as e:
        print(f"Error fetching stats: {e}")
        return jsonify({
            "verified_reports": 0,
            "incidents_reported": 0,
            "active_sectors": 0
        })
