from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify, current_app, session
from datetime import datetime
import os
import uuid
import threading
from werkzeug.utils import secure_filename

from database import db
from models import User, Company, SummarizationJob, SummarizationResult, ActivityLog, Case, CaseDocument
from auth_routes import login_required, log_activity

# Create a Blueprint for summarization routes
summarization_bp = Blueprint('summarization', __name__, url_prefix='/summarization')

def allowed_file(filename, allowed_extensions):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in allowed_extensions

@summarization_bp.route('/')
@login_required
def summarization_form():
    """Display the document summarization form"""
    # Get case information if provided
    case_id = request.args.get('case_id')
    document_id = request.args.get('document_id')
    
    case = None
    document = None
    
    if case_id:
        case = Case.query.get(case_id)
        user_id = session.get('user_id')
        user = User.query.get(user_id)
        
        # Check if user can access this case
        if case and not user.can_view_case(case):
            flash('You do not have permission to access this case', 'danger')
            return redirect(url_for('dashboard'))
    
    if document_id:
        document = CaseDocument.query.get(document_id)
    
    return render_template('summarization/form.html', case=case, document=document)

@summarization_bp.route('/upload', methods=['POST'])
@login_required
def upload_for_summarization():
    """Handle file upload for summarization - FIXED to handle existing case documents"""
    try:
        # Get form parameters first
        summary_type = request.form.get('summary_type', 'standard')
        summary_length = request.form.get('summary_length', 'medium')
        additional_instructions = request.form.get('additional_instructions', '')
        case_id = request.form.get('case_id')
        document_id = request.form.get('document_id')  # Key for existing documents
        retry_file_path = request.form.get('retry_file_path')  # For retry from error page
        
        # Validate parameters
        valid_types = ['standard', 'executive', 'bullet_points', 'key_facts']
        valid_lengths = ['short', 'medium', 'long']
        
        if summary_type not in valid_types:
            return jsonify({"error": "Invalid summary type"}), 400
        if summary_length not in valid_lengths:
            return jsonify({"error": "Invalid summary length"}), 400
        
        # Get current user
        user_id = session.get('user_id')
        user = User.query.get(user_id)
        
        # Handle retry from error page
        if retry_file_path:
            print(f"🔄 Retrying with existing file: {retry_file_path}")
            if os.path.exists(retry_file_path):
                file_path = retry_file_path
                original_filename = request.form.get('original_filename', 'document.pdf')
            else:
                return jsonify({'error': 'Retry file not found'}), 404
        # ✅ FIXED: Handle existing case document
        elif document_id:
            print(f"🔄 Summarizing existing case document ID: {document_id}")
            
            # Get the existing document
            existing_doc = CaseDocument.query.get(document_id)
            if not existing_doc:
                return jsonify({'error': 'Document not found'}), 404
            
            # Verify user can access this document
            if existing_doc.case and not user.can_view_case(existing_doc.case):
                return jsonify({'error': 'Access denied'}), 403
            
            # Check if file still exists
            if not existing_doc.file_path or not os.path.exists(existing_doc.file_path):
                return jsonify({'error': 'Document file not found on server'}), 404
            
            # Use existing document info
            file_path = existing_doc.file_path
            original_filename = existing_doc.original_filename
            print(f"✅ Using existing document: {original_filename}")
            
        else:
            # ✅ Handle new file upload (original logic)
            if 'file' not in request.files:
                return jsonify({"error": "No file part"}), 400
                
            file = request.files['file']
            if file.filename == '':
                return jsonify({"error": "No selected file"}), 400
            
            # Check file type
            allowed_extensions = {'pdf', 'txt', 'docx', 'doc', 'jpg', 'jpeg', 'png', 'tif', 'tiff', 'bmp'}
            if not allowed_file(file.filename, allowed_extensions):
                return jsonify({"error": "File type not allowed. Supported formats: PDF, TXT, DOCX, DOC, JPG, JPEG, PNG, TIFF, BMP"}), 400
            
            # Check file size (100MB limit for now, can be adjusted)
            MAX_FILE_SIZE = 100 * 1024 * 1024  # 100MB
            file.seek(0, os.SEEK_END)
            file_size = file.tell()
            file.seek(0)  # Reset file pointer
            
            if file_size > MAX_FILE_SIZE:
                return jsonify({"error": f"File too large. Maximum size is {MAX_FILE_SIZE // (1024*1024)}MB. For large documents like Dobbs (281 pages), try splitting into sections."}), 400
            
            # Generate unique job ID and save the file
            job_uuid = str(uuid.uuid4())
            original_filename = secure_filename(file.filename)
            file_path = os.path.join(current_app.config['UPLOAD_FOLDER'], f"{job_uuid}_{original_filename}")
            file.save(file_path)
            print(f"✅ New file uploaded: {original_filename}")
        
        # Generate unique job ID (for existing docs too)
        job_uuid = str(uuid.uuid4())
        
        # Create database record for this job
        job = SummarizationJob(
            job_uuid=job_uuid,
            user_id=user_id,
            company_id=user.company_id,
            case_id=case_id if case_id else None,
            filename=os.path.basename(file_path),
            original_filename=original_filename,
            file_path=file_path,
            summary_type=summary_type,
            summary_length=summary_length,
            additional_instructions=additional_instructions,
            status="processing"
        )
        
        db.session.add(job)
        db.session.commit()
        
        # Log the activity
        action_desc = f'Started {summary_type} summarization ({summary_length})'
        if document_id:
            action_desc += f' of existing document {original_filename}'
        else:
            action_desc += f' of {original_filename}'
        
        log_activity(
            user_id, 
            'summarization_started', 
            action_desc + (f" for case {job.case.case_name}" if job.case else ""),
            'summarization_job',
            job.id
        )
        
        # Log case activity if applicable
        if case_id:
            from case_routes import log_case_activity
            log_case_activity(
                case_id,
                user_id,
                'summarization_started',
                f'{user.username} started {summary_type} summarization of {original_filename}',
                'summarization',
                job.id
            )
        
        # Start processing in a background thread
        threading.Thread(target=process_summarization_job, args=(job_uuid, file_path, summary_type, summary_length, additional_instructions, user_id, document_id)).start()

        return jsonify({
            "success": True,
            "job_id": job_uuid,
            "message": "Summarization started successfully"
        })
        
    except Exception as e:
        import traceback
        error_details = traceback.format_exc()
        print(f"Error in upload_for_summarization: {str(e)}\n{error_details}")
        
        # Clean up file if it was created for new uploads
        if 'file_path' in locals() and not document_id and os.path.exists(file_path):
            os.remove(file_path)
        
        return jsonify({"error": f"Upload failed: {str(e)}"}), 500

def process_summarization_job(job_uuid, file_path, summary_type, summary_length, additional_instructions, user_id, document_id=None):
    """Process summarization in background thread with timeout protection"""
    from app import app
    import time
    
    # Set maximum processing time (10 minutes)
    MAX_PROCESSING_TIME = 600
    start_time = time.time()
    
    with app.app_context():
        try:
            # Get the job from the database
            job = SummarizationJob.query.filter_by(job_uuid=job_uuid).first()
            
            if not job:
                print(f"Error: Summarization job with UUID {job_uuid} not found")
                return
            
            # Import the summarization processor
            from document_summarization_processor import DocumentSummarizationProcessor
            
            processor = DocumentSummarizationProcessor(api_key=app.config['OPENAI_API_KEY'])
            
            print(f"[SUMMARIZATION] Starting processing for job {job_uuid}")
            print(f"[SUMMARIZATION] File: {file_path}, Type: {summary_type}, Length: {summary_length}")
            
            # Check if we've been running too long
            if time.time() - start_time > MAX_PROCESSING_TIME:
                raise TimeoutError("Processing exceeded maximum time limit")
            
            # Process document
            print(f"[SUMMARIZATION] Calling processor.summarize_document...")
            result = processor.summarize_document(
                file_path=file_path,
                summary_type=summary_type,
                summary_length=summary_length,
                additional_instructions=additional_instructions,
                detail=0.5  # Default detail level
            )
            
            print(f"[SUMMARIZATION] Processing complete, checking results...")
            
            # Check for errors
            if "summary" not in result or not result["summary"]:
                print(f"[SUMMARIZATION] ERROR: No summary in result")
                job.status = "failed"
                job.error_message = "Summarization failed to generate results. Please try a smaller document."
                db.session.commit()
                return
            
            print(f"[SUMMARIZATION] Success! Summary length: {len(result.get('summary', ''))}")
            
            # 🔥 FIXED: Use correct field name 'processing_info' instead of 'metadata'
            summarization_result = SummarizationResult(
                job_id=job.id,
                summary=result["summary"],
                section_summaries=result.get("section_summaries", []),
                processing_info=result.get("metadata", {})  # ← FIXED: Changed from metadata= to processing_info=
            )
            
            # Update job status
            job.status = "completed"
            job.completed_at = datetime.utcnow()
            
            db.session.add(summarization_result)
            db.session.commit()
            
            # Log the activity
            log_activity(
                user_id, 
                'summarization_completed', 
                f"Completed {summary_type} summarization of {job.original_filename}" +
                (f" for case {job.case.case_name}" if job.case else ""),
                'summarization_job',
                job.id
            )
            
            # Log case activity if applicable
            if job.case_id:
                from case_routes import log_case_activity
                log_case_activity(
                    job.case_id,
                    user_id,
                    'summarization_completed',
                    f'Completed {summary_type} summarization of {job.original_filename}',
                    'summarization',
                    job.id
                )

            # Link summarization back to the case document if this was for an existing document
            if document_id:
                try:
                    case_doc = CaseDocument.query.get(document_id)
                    if case_doc:
                        case_doc.summarization_job_id = job_uuid
                        db.session.commit()
                        print(f"✅ Linked summarization {job_uuid} to document {document_id}")
                except Exception as link_error:
                    print(f"⚠️  Failed to link summarization to document: {link_error}")

            # Clean up file after 1 hour (optional)
            threading.Timer(3600, lambda: os.remove(file_path) if os.path.exists(file_path) else None).start()
            
        except TimeoutError as e:
            # Handle timeout specifically
            print(f"Timeout error processing summarization: {str(e)}")
            
            # Update job status
            job = SummarizationJob.query.filter_by(job_uuid=job_uuid).first()
            if job:
                job.status = "failed"
                job.error_message = "Processing timeout - document is too large. For documents like the Dobbs decision (281 pages), please split into sections (e.g., pages 1-50, 51-100) or use 'Short' summary length."
                db.session.commit()
                
                # Log the activity
                log_activity(
                    user_id,
                    'summarization_timeout',
                    f'Summarization timed out for {job.original_filename}',
                    'summarization_job',
                    job.id
                )
            
        except Exception as e:
            import traceback
            error_details = traceback.format_exc()
            print(f"Error processing summarization: {str(e)}\n{error_details}")
            
            # Update job status
            job = SummarizationJob.query.filter_by(job_uuid=job_uuid).first()
            if job:
                job.status = "failed"
                job.error_message = str(e)
                db.session.commit()
                
                # Log the activity
                log_activity(
                    user_id, 
                    'summarization_failed', 
                    f"Failed summarization of {job.original_filename}: {str(e)}",
                    'summarization_job',
                    job.id
                )

@summarization_bp.route('/job_status/<job_id>', methods=['GET'])
@login_required
def job_status(job_id):
    """Check status of a processing summarization job"""
    job = SummarizationJob.query.filter_by(job_uuid=job_id).first()
    
    if not job:
        return jsonify({"error": "Job not found"}), 404
    
    # Check if user has permission to view this job
    user_id = session.get('user_id')
    user = User.query.get(user_id)
    
    # Check case access if job is associated with a case
    if job.case and not user.can_view_case(job.case):
        return jsonify({"error": "You do not have permission to view this job"}), 403
    
    # Otherwise check standard permissions
    if not user.is_admin() and not user.is_company_admin() and job.user_id != user_id:
        return jsonify({"error": "You do not have permission to view this job"}), 403
    
    # Calculate progress (simplified)
    progress = 0
    if job.status == "completed":
        progress = 100
    elif job.status == "processing":
        # Simulate progress based on time elapsed (up to 90%)
        elapsed = (datetime.utcnow() - job.created_at).total_seconds()
        progress = min(90, int(elapsed / 2))  # Rough estimate
    
    return jsonify({
        "job_id": job.job_uuid,
        "status": job.status,
        "progress": progress,
        "filename": job.original_filename,
        "summary_type": job.summary_type,
        "summary_length": job.summary_length,
        "completed": job.status == "completed"
    })

@summarization_bp.route('/results/<job_id>', methods=['GET'])
@login_required
def get_results(job_id):
    """Get results of a completed summarization job"""
    job = SummarizationJob.query.filter_by(job_uuid=job_id).first()
    
    if not job:
        return jsonify({"error": "Job not found"}), 404
    
    # Check if user has permission to view this job
    user_id = session.get('user_id')
    user = User.query.get(user_id)
    
    # Check case access if job is associated with a case
    if job.case and not user.can_view_case(job.case):
        return jsonify({"error": "You do not have permission to view this job"}), 403
    
    if not user.is_admin() and not user.is_company_admin() and job.user_id != user_id:
        return jsonify({"error": "You do not have permission to view this job"}), 403
    
    if job.status != "completed":
        return jsonify({
            "error": "Job not completed",
            "status": job.status
        }), 400
    
    # Get the results
    results = job.results
    
    if not results:
        return jsonify({"error": "Results not found"}), 404
    
    return jsonify({
        "job_id": job.job_uuid,
        "status": "completed",
        "filename": job.original_filename,
        "summary_type": job.summary_type,
        "summary_length": job.summary_length,
        "summary": results.summary,
        "section_summaries": results.section_summaries_json,
        "metadata": results.metadata_json,
        "case": {
            "id": job.case.id,
            "name": job.case.case_name,
            "number": job.case.case_number
        } if job.case else None
    })

@summarization_bp.route('/summary/<job_id>', methods=['GET'])
@login_required
def show_summary(job_id):
    """Display summarization results"""
    job = SummarizationJob.query.filter_by(job_uuid=job_id).first()
    
    if not job:
        return render_template('error.html', error="Summarization not found")
    
    # Check if user has permission to view this job
    user_id = session.get('user_id')
    user = User.query.get(user_id)
    
    # Check case access if job is associated with a case
    if job.case and not user.can_view_case(job.case):
        return render_template('error.html', error="You do not have permission to view this summarization")
    
    if not user.is_admin() and not user.is_company_admin() and job.user_id != user_id:
        return render_template('error.html', error="You do not have permission to view this summarization")
    
    # Handle failed jobs with retry options
    if job.status == "failed":
        # Check if it's a large document
        is_large_document = False
        if job.file_path and os.path.exists(job.file_path):
            file_size = os.path.getsize(job.file_path)
            is_large_document = file_size > 10 * 1024 * 1024  # 10MB
        
        return render_template('error_with_retry.html',
                             job_type='summarization',
                             job=job,
                             error_message=job.error_message or "Document processing failed. This may be due to document size or complexity.",
                             error_type='Processing Error',
                             is_large_document=is_large_document,
                             now=datetime.utcnow())
    
    if job.status != "completed":
        return render_template('summarization/processing.html', job_id=job_id, job=job)
    
    # Get the results
    results = job.results
    
    if not results:
        return render_template('error_with_retry.html',
                             job_type='summarization',
                             job=job,
                             error_message="Summarization results not found. Please try again.",
                             error_type='No Results',
                             is_large_document=False,
                             now=datetime.utcnow())
    
    # Format job data for template
    formatted_job = {
        "job_id": job.job_uuid,
        "filename": job.original_filename,
        "summary_type": job.summary_type,
        "summary_length": job.summary_length,
        "status": job.status,
        "case": job.case,
        "additional_instructions": job.additional_instructions
    }
    
    return render_template('summarization/results.html', 
                          job_id=job_id, 
                          job=formatted_job, 
                          summary=results.summary,
                          section_summaries=results.section_summaries_json,
                          metadata=results.metadata_json)

# FIXED: Updated API endpoint to return 'analysis' field instead of 'summary_text'
# This matches what the frontend copy functionality expects
@summarization_bp.route('/api/get-summary/<job_id>', methods=['GET'])
@login_required
def get_summary_for_copy(job_id):
    """
    API endpoint to get summarization results for copying to clipboard
    Returns data in the format expected by the copy functionality
    """
    try:
        print(f"Copy request for summarization job ID: {job_id}")
        
        job = SummarizationJob.query.filter_by(job_uuid=job_id).first()
        
        if not job:
            return jsonify({"error": "Summarization not found"}), 404
        
        # Check if user has permission to view this job
        user_id = session.get('user_id')
        user = User.query.get(user_id)
        
        if not user:
            return jsonify({
                "success": False,
                "error": "User not found"
            }), 403
        
        # Check case access if job is associated with a case
        if job.case and not user.can_view_case(job.case):
            return jsonify({
                "success": False,
                "error": "You do not have permission to view this summarization"
            }), 403
        
        if not user.is_admin() and not user.is_company_admin() and job.user_id != user_id:
            return jsonify({
                "success": False,
                "error": "You do not have permission to view this summarization"
            }), 403
        
        if job.status != "completed":
            return jsonify({
                "success": False,
                "error": "Job not completed",
                "status": job.status
            }), 400
        
        # Get the results
        results = job.results
        
        if not results:
            return jsonify({
                "success": False,
                "error": "Results not found"
            }), 404
        
        # Format the summary as plain text in the 'analysis' field (not 'summary_text')
        summary_type = job.summary_type.replace('_', ' ').title()
        summary_length = job.summary_length.title()
        
        # Create nicely formatted analysis text
        formatted_analysis = f"{summary_type} Summary ({summary_length} Length)\n"
        formatted_analysis += "=" * 60 + "\n\n"
        
        # Add case information if available
        if job.case:
            formatted_analysis += f"Case: {job.case.case_name} (#{job.case.case_number})\n"
            if job.case.client_name:
                formatted_analysis += f"Client: {job.case.client_name}\n"
            formatted_analysis += "\n"
        
        formatted_analysis += f"Document: {job.original_filename}\n"
        formatted_analysis += f"Job ID: {job_id}\n"
        formatted_analysis += f"Generated: {datetime.utcnow().strftime('%B %d, %Y at %I:%M %p UTC')}\n\n"
        
        # Add additional instructions if provided
        if job.additional_instructions:
            formatted_analysis += f"Special Instructions: {job.additional_instructions}\n\n"
        
        formatted_analysis += "SUMMARY:\n"
        formatted_analysis += "-" * 40 + "\n\n"
        formatted_analysis += results.summary + "\n\n"
        
        # Add section summaries if available
        if results.section_summaries_json:
            formatted_analysis += "SECTION SUMMARIES:\n"
            formatted_analysis += "-" * 40 + "\n\n"
            for i, section in enumerate(results.section_summaries_json, 1):
                formatted_analysis += f"Section {i}:\n{section}\n\n"
        
        # Add metadata if available
        if results.metadata_json:
            metadata = results.metadata_json
            formatted_analysis += "PROCESSING INFORMATION:\n"
            formatted_analysis += "-" * 40 + "\n"
            if 'chunks_processed' in metadata:
                formatted_analysis += f"Sections Processed: {metadata['chunks_processed']}\n"
            if 'total_tokens' in metadata:
                formatted_analysis += f"Document Length: {metadata['total_tokens']} tokens\n"
            formatted_analysis += "\n"
        
        formatted_analysis += "=" * 60 + "\n"
        formatted_analysis += "Generated by LawBot Summarization Engine\n"
        formatted_analysis += "This summary is for informational purposes only.\n"
        
        # Return in the format expected by the frontend copy function
        # CRITICAL: Use 'analysis' field name, not 'summary_text'
        return jsonify({
            'success': True,
            'job_id': job_id,
            'analysis': formatted_analysis,  # This is the key field name the frontend expects
            'summary_type': summary_type,
            'summary_length': summary_length,
            'word_count': len(results.summary.split()) if results.summary else 0,
            'char_count': len(formatted_analysis),
            'case': {
                'id': job.case.id,
                'name': job.case.case_name,
                'number': job.case.case_number
            } if job.case else None
        })
                
    except Exception as e:
        import traceback
        error_details = traceback.format_exc()
        print(f"Error getting summary for copy: {str(e)}\n{error_details}")
        return jsonify({
            'success': False,
            'error': f"Internal server error: {str(e)}"
        }), 500

# ADD: Additional endpoint alias for template compatibility
# The template calls 'get_summary_text' so we need this endpoint name
@summarization_bp.route('/api/get-summary-text/<job_id>', methods=['GET'])
@login_required
def get_summary_text(job_id):
    """
    Alias for get_summary_for_copy to maintain template compatibility
    """
    return get_summary_for_copy(job_id)
