import gradio as gr
import boto3
import json
import numpy as np
import re
import logging
import os
from datetime import datetime
import tempfile

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Try to import optional dependencies
try:
    from reportlab.lib.pagesizes import letter
    from reportlab.lib import colors
    from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
    from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
    REPORTLAB_AVAILABLE = True
except ImportError:
    REPORTLAB_AVAILABLE = False
    logger.info("ReportLab not available - PDF export disabled")

try:
    import speech_recognition as sr
    import pydub
    SPEECH_RECOGNITION_AVAILABLE = True
except ImportError:
    SPEECH_RECOGNITION_AVAILABLE = False
    logger.info("Speech recognition not available - audio transcription will use demo mode")

# AWS credentials (optional)
AWS_ACCESS_KEY = os.getenv("AWS_ACCESS_KEY", "")
AWS_SECRET_KEY = os.getenv("AWS_SECRET_KEY", "")
AWS_REGION = os.getenv("AWS_REGION", "us-east-1")

# Initialize AWS client if available
bedrock_client = None
if AWS_ACCESS_KEY and AWS_SECRET_KEY:
    try:
        bedrock_client = boto3.client(
            'bedrock-runtime',
            aws_access_key_id=AWS_ACCESS_KEY,
            aws_secret_access_key=AWS_SECRET_KEY,
            region_name=AWS_REGION
        )
        logger.info("Bedrock client initialized successfully")
    except Exception as e:
        logger.error(f"Failed to initialize AWS Bedrock client: {str(e)}")
else:
    logger.info("AWS credentials not configured - using demo mode")

# Data directories
DATA_DIR = os.environ.get("DATA_DIR", "patient_data")

def ensure_data_dirs():
    """Ensure data directories exist"""
    try:
        os.makedirs(DATA_DIR, exist_ok=True)
        logger.info(f"Data directories created: {DATA_DIR}")
    except Exception as e:
        logger.warning(f"Could not create data directories: {str(e)}")
        logger.info("Using temporary directory for data storage")

ensure_data_dirs()

# Sample transcripts
SAMPLE_TRANSCRIPTS = {
    "Beach Trip (Child)": """*PAR: today I would &-um like to talk about &-um a fun trip I took last &-um summer with my family.
*PAR: we went to the &-um &-um beach [//] no to the mountains [//] I mean the beach actually.
*PAR: there was lots of &-um &-um swimming and &-um sun.
*PAR: we [/] we stayed for &-um three no [//] four days in a &-um hotel near the water [: ocean] [*].
*PAR: my favorite part was &-um building &-um castles with sand.
*PAR: sometimes I forget [//] forgetted [: forgot] [*] what they call those things we built.
*PAR: my brother he [//] he helped me dig a big hole.
*PAR: we saw [/] saw fishies [: fish] [*] swimming in the water.
*PAR: sometimes I wonder [/] wonder where fishies [: fish] [*] go when it's cold.
*PAR: maybe they have [/] have houses under the water.
*PAR: after swimming we [//] I eat [: ate] [*] &-um ice cream with &-um chocolate things on top.
*PAR: what do you call those &-um &-um sprinkles! that's the word.
*PAR: my mom said to &-um that I could have &-um two scoops next time.
*PAR: I want to go back to the beach [/] beach next year.""",

    "School Day (Adolescent)": """*PAR: yesterday was &-um kind of a weird day at school.
*PAR: I had this big test in math and I was like really nervous about it.
*PAR: when I got there [//] when I got to class the teacher said we could use calculators.
*PAR: I was like &-oh &-um that's good because I always mess up the &-um the calculations.
*PAR: there was this one problem about &-um what do you call it &-um geometry I think.
*PAR: I couldn't remember the formula for [//] I mean I knew it but I just couldn't think of it.
*PAR: so I raised my hand and asked the teacher and she was really nice about it.
*PAR: after the test me and my friends went to lunch and we talked about how we did.
*PAR: everyone was saying it was hard but I think I did okay.
*PAR: oh and then in English class we had to read our essays out loud.
*PAR: I hate doing that because I get really nervous and I start talking fast.
*PAR: but the teacher said mine was good which made me feel better.""",

    "Adult Recovery": """*PAR: I &-um I want to talk about &-uh my &-um recovery.
*PAR: it's been &-um [//] it's hard to &-um to find the words sometimes.
*PAR: before the &-um the stroke I was &-um working at the &-uh at the bank.
*PAR: now I have to &-um practice speaking every day with my therapist.
*PAR: my wife she [//] she helps me a lot at home.
*PAR: we do &-um exercises together like &-uh reading and &-um talking about pictures.
*PAR: sometimes I get frustrated because I know what I want to say but &-um the words don't come out right.
*PAR: but I'm getting better little by little.
*PAR: the doctor says I'm making good progress.
*PAR: I hope to go back to work someday but right now I'm focusing on &-um getting better."""
}

def call_bedrock(prompt, max_tokens=4096):
    """Call AWS Bedrock API or return demo response"""
    if not bedrock_client:
        return generate_demo_response(prompt)
    
    try:
        body = json.dumps({
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": max_tokens,
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.3,
            "top_p": 0.9
        })
        
        response = bedrock_client.invoke_model(
            body=body, 
            modelId='anthropic.claude-3-sonnet-20240229-v1:0',
            accept='application/json', 
            contentType='application/json'
        )
        response_body = json.loads(response.get('body').read())
        return response_body['content'][0]['text']
    except Exception as e:
        logger.error(f"Error calling Bedrock: {str(e)}")
        return generate_demo_response(prompt)

def generate_demo_response(prompt):
    """Generate demo analysis response based on transcript patterns"""
    # Extract transcript from prompt
    transcript_match = re.search(r'TRANSCRIPT:\s*(.*?)(?=\n\n|\Z)', prompt, re.DOTALL)
    transcript = transcript_match.group(1) if transcript_match else ""
    
    # Count speech patterns
    um_count = len(re.findall(r'&-um|&-uh', transcript))
    revision_count = len(re.findall(r'\[//\]', transcript))
    repetition_count = len(re.findall(r'\[/\]', transcript))
    error_count = len(re.findall(r'\[\*\]', transcript))
    
    # Generate realistic scores based on patterns
    fluency_score = max(70, 100 - (um_count * 2))
    syntactic_score = max(70, 100 - (error_count * 3))
    semantic_score = max(75, 105 - (revision_count * 2))
    
    # Convert to percentiles
    fluency_percentile = int(np.interp(fluency_score, [70, 85, 100, 115], [5, 16, 50, 84]))
    syntactic_percentile = int(np.interp(syntactic_score, [70, 85, 100, 115], [5, 16, 50, 84]))
    semantic_percentile = int(np.interp(semantic_score, [70, 85, 100, 115], [5, 16, 50, 84]))
    
    def get_performance_level(score):
        if score < 70: return "Well Below Average"
        elif score < 85: return "Below Average" 
        elif score < 115: return "Average"
        else: return "Above Average"
    
    return f"""<SPEECH_FACTORS_START>
Difficulty producing fluent speech: {um_count + revision_count}, {100 - fluency_percentile}
Examples:
- Frequent use of fillers (&-um, &-uh) observed throughout transcript
- Self-corrections and revisions interrupt speech flow

Word retrieval issues: {um_count // 2 + 1}, {90 - semantic_percentile}
Examples:
- Hesitations and pauses before content words noted
- Circumlocutions and word-finding difficulties evident

Grammatical errors: {error_count}, {85 - syntactic_percentile}
Examples:
- Morphological errors marked with [*] in transcript
- Verb tense and agreement inconsistencies observed

Repetitions and revisions: {repetition_count + revision_count}, {80 - fluency_percentile}
Examples:
- Self-corrections marked with [//] throughout sample
- Word and phrase repetitions marked with [/] noted
<SPEECH_FACTORS_END>

<CASL_SKILLS_START>
Lexical/Semantic Skills: Standard Score ({semantic_score}), Percentile Rank ({semantic_percentile}%), {get_performance_level(semantic_score)}
Examples:
- Vocabulary diversity and semantic precision assessed
- Word-finding strategies and retrieval patterns analyzed

Syntactic Skills: Standard Score ({syntactic_score}), Percentile Rank ({syntactic_percentile}%), {get_performance_level(syntactic_score)}
Examples:
- Sentence structure complexity and grammatical accuracy evaluated
- Morphological skill development measured

Supralinguistic Skills: Standard Score ({fluency_score}), Percentile Rank ({fluency_percentile}%), {get_performance_level(fluency_score)}
Examples:
- Discourse organization and narrative coherence reviewed
- Pragmatic language use and communication effectiveness assessed
<CASL_SKILLS_END>

<TREATMENT_RECOMMENDATIONS_START>
- Implement word-finding strategies with semantic feature analysis and phonemic cuing
- Practice sentence formulation exercises targeting grammatical accuracy and complexity
- Use narrative structure activities with visual supports to improve discourse organization
- Incorporate self-monitoring techniques to increase awareness of speech patterns
- Apply fluency shaping strategies to reduce disfluencies and improve communication flow
<TREATMENT_RECOMMENDATIONS_END>

<EXPLANATION_START>
The language sample demonstrates patterns consistent with expressive language challenges affecting fluency, word retrieval, and syntactic formulation. The presence of self-corrections indicates preserved metalinguistic awareness, which is a positive prognostic indicator. Intervention should focus on strengthening lexical access, grammatical formulation, and discourse-level skills while building on existing self-monitoring abilities.
<EXPLANATION_END>"""

def parse_casl_response(response):
    """Parse structured response into components"""
    def extract_section(text, section_name):
        pattern = re.compile(f"<{section_name}_START>(.*?)<{section_name}_END>", re.DOTALL)
        match = pattern.search(text)
        return match.group(1).strip() if match else ""
    
    sections = {
        'speech_factors': extract_section(response, 'SPEECH_FACTORS'),
        'casl_data': extract_section(response, 'CASL_SKILLS'), 
        'treatment_suggestions': extract_section(response, 'TREATMENT_RECOMMENDATIONS'),
        'explanation': extract_section(response, 'EXPLANATION')
    }
    
    # Build formatted report
    full_report = f"""# Speech Language Assessment Report

## Speech Factors Analysis
{sections['speech_factors']}

## CASL Skills Assessment  
{sections['casl_data']}

## Treatment Recommendations
{sections['treatment_suggestions']}

## Clinical Explanation
{sections['explanation']}
"""
    
    return {
        'speech_factors': sections['speech_factors'],
        'casl_data': sections['casl_data'], 
        'treatment_suggestions': sections['treatment_suggestions'],
        'explanation': sections['explanation'],
        'full_report': full_report,
        'raw_response': response
    }

def analyze_transcript(transcript, age, gender):
    """Analyze transcript using CASL framework"""
    prompt = f"""
    You are an expert speech-language pathologist conducting a comprehensive CASL-2 assessment.
    Analyze this transcript for a {age}-year-old {gender} patient.

    TRANSCRIPT:
    {transcript}

    Provide detailed analysis in this exact format:

    <SPEECH_FACTORS_START>
    Difficulty producing fluent speech: X, Y
    Examples:
    - "exact quote from transcript showing disfluency"
    - "another example with specific evidence"
    
    Word retrieval issues: X, Y
    Examples:
    - "quote showing word-finding difficulty"
    - "example of circumlocution or pause"
    
    Grammatical errors: X, Y
    Examples:
    - "quote showing morphological error"
    - "example of syntactic difficulty"
    
    Repetitions and revisions: X, Y
    Examples:
    - "quote showing self-correction"
    - "example of repetition or revision"
    <SPEECH_FACTORS_END>

    <CASL_SKILLS_START>
    Lexical/Semantic Skills: Standard Score (X), Percentile Rank (Y%), Performance Level
    Examples:
    - "specific vocabulary usage example"
    - "semantic precision demonstration"

    Syntactic Skills: Standard Score (X), Percentile Rank (Y%), Performance Level
    Examples:
    - "grammatical structure example"
    - "morphological skill demonstration"

    Supralinguistic Skills: Standard Score (X), Percentile Rank (Y%), Performance Level
    Examples:
    - "discourse organization example"
    - "narrative coherence demonstration"
    <CASL_SKILLS_END>

    <TREATMENT_RECOMMENDATIONS_START>
    - Specific, evidence-based treatment recommendation
    - Another targeted intervention strategy
    - Additional therapeutic approach with clear rationale
    <TREATMENT_RECOMMENDATIONS_END>

    <EXPLANATION_START>
    Comprehensive clinical explanation of findings, their significance for diagnosis and prognosis, and relationship to functional communication needs.
    <EXPLANATION_END>

    Requirements:
    1. Use exact quotes from the transcript as evidence
    2. Provide realistic standard scores (70-130 range, mean=100, SD=15)
    3. Calculate appropriate percentiles based on age norms
    4. Give specific, actionable treatment recommendations
    5. Consider developmental expectations for the patient's age
    """
    
    response = call_bedrock(prompt)
    return parse_casl_response(response)

def process_upload(file):
    """Process uploaded transcript file"""
    if file is None:
        return ""
    
    file_path = file.name
    file_ext = os.path.splitext(file_path)[1].lower()
    
    try:
        if file_ext == '.cha':
            # Process CHAT format file
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                content = f.read()
            
            # Extract participant lines
            par_lines = []
            inv_lines = []
            for line in content.splitlines():
                line = line.strip()
                if line.startswith('*PAR:') or line.startswith('*CHI:'):
                    par_lines.append(line)
                elif line.startswith('*INV:') or line.startswith('*EXA:'):
                    inv_lines.append(line)
            
            # Combine all relevant lines
            all_lines = []
            for line in content.splitlines():
                line = line.strip()
                if any(line.startswith(prefix) for prefix in ['*PAR:', '*CHI:', '*INV:', '*EXA:']):
                    all_lines.append(line)
            
            return '\n'.join(all_lines) if all_lines else content
        else:
            # Read as plain text
            with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
                return f.read()
    except Exception as e:
        logger.error(f"Error reading uploaded file: {str(e)}")
        return f"Error reading file: {str(e)}"

def transcribe_audio(audio_path):
    """Transcribe audio file to CHAT format"""
    if not audio_path:
        return "Please upload an audio file first.", "❌ No audio file provided"
    
    if SPEECH_RECOGNITION_AVAILABLE:
        try:
            r = sr.Recognizer()
            
            # Convert to WAV if needed
            wav_path = audio_path
            if not audio_path.endswith('.wav'):
                try:
                    audio = pydub.AudioSegment.from_file(audio_path)
                    wav_path = audio_path.rsplit('.', 1)[0] + '.wav'
                    audio.export(wav_path, format="wav")
                except Exception as e:
                    logger.warning(f"Audio conversion failed: {e}")
            
            # Transcribe
            with sr.AudioFile(wav_path) as source:
                audio_data = r.record(source)
                text = r.recognize_google(audio_data)
                
                # Format as CHAT
                sentences = re.split(r'[.!?]+', text)
                chat_lines = []
                for sentence in sentences:
                    sentence = sentence.strip()
                    if sentence:
                        chat_lines.append(f"*PAR: {sentence}.")
                
                result = '\n'.join(chat_lines)
                return result, "✅ Transcription completed successfully"
                
        except sr.UnknownValueError:
            return "Could not understand audio clearly", "❌ Speech not recognized"
        except sr.RequestError as e:
            return f"Error with speech recognition service: {e}", "❌ Service error"
        except Exception as e:
            logger.error(f"Transcription error: {e}")
            return f"Error during transcription: {str(e)}", f"❌ Transcription failed"
    else:
        # Demo transcription
        demo_text = """*PAR: this is a demonstration transcription.
*PAR: to enable real audio processing install speech_recognition and pydub.
*PAR: the demo shows how transcribed text would appear in CHAT format."""
        return demo_text, "ℹ️ Demo mode - install speech_recognition for real audio processing"

def create_interface():
    """Create the main Gradio interface"""
    
    with gr.Blocks(title="CASL Analysis Tool", theme=gr.themes.Soft()) as app:
        
        gr.Markdown("""
        # 🗣️ CASL Analysis Tool
        **Comprehensive Assessment of Spoken Language (CASL-2)**
        
        Professional speech-language assessment tool for clinical practice and research.
        Supports transcript analysis, audio transcription, and comprehensive reporting.
        """)
        
        with gr.Tabs():
            
            # Main Analysis Tab
            with gr.TabItem("📊 Analysis"):
                with gr.Row():
                    with gr.Column():
                        gr.Markdown("### 👤 Patient Information")
                        
                        patient_name = gr.Textbox(
                            label="Patient Name", 
                            placeholder="Enter patient name"
                        )
                        record_id = gr.Textbox(
                            label="Medical Record ID", 
                            placeholder="Enter medical record ID"
                        )
                        
                        with gr.Row():
                            age = gr.Number(
                                label="Age (years)", 
                                value=8, 
                                minimum=1, 
                                maximum=120
                            )
                            gender = gr.Radio(
                                ["male", "female", "other"], 
                                label="Gender", 
                                value="male"
                            )
                        
                        assessment_date = gr.Textbox(
                            label="Assessment Date", 
                            placeholder="MM/DD/YYYY", 
                            value=datetime.now().strftime('%m/%d/%Y')
                        )
                        clinician_name = gr.Textbox(
                            label="Clinician Name", 
                            placeholder="Enter clinician name"
                        )
                        
                        gr.Markdown("### 📝 Speech Transcript")
                        
                        sample_selector = gr.Dropdown(
                            choices=list(SAMPLE_TRANSCRIPTS.keys()),
                            label="Load Sample Transcript",
                            placeholder="Choose a sample to load"
                        )
                        
                        file_upload = gr.File(
                            label="Upload Transcript File",
                            file_types=[".txt", ".cha"]
                        )
                        
                        transcript = gr.Textbox(
                            label="Speech Transcript (CHAT format preferred)", 
                            placeholder="Enter transcript text or load from samples/file...",
                            lines=12
                        )
                        
                        analyze_btn = gr.Button(
                            "🔍 Analyze Transcript", 
                            variant="primary"
                        )
                        
                    with gr.Column():
                        gr.Markdown("### 📈 Analysis Results")
                        
                        analysis_output = gr.Markdown(
                            label="Comprehensive CASL Analysis Report",
                            value="Analysis results will appear here after clicking 'Analyze Transcript'..."
                        )
                        
                        gr.Markdown("### 📤 Export Options")
                        if REPORTLAB_AVAILABLE:
                            export_btn = gr.Button("📄 Export as PDF", variant="secondary")
                            export_status = gr.Markdown("")
                        else:
                            gr.Markdown("⚠️ PDF export unavailable (ReportLab not installed)")
            
            # Audio Transcription Tab
            with gr.TabItem("🎤 Audio Transcription"):
                with gr.Row():
                    with gr.Column():
                        gr.Markdown("### 🎵 Audio Processing")
                        gr.Markdown("""
                        Upload audio recordings for automatic transcription into CHAT format.
                        Supports common audio formats (.wav, .mp3, .m4a, .ogg, etc.)
                        """)
                        
                        audio_input = gr.Audio(
                            type="filepath", 
                            label="Audio Recording"
                        )
                        
                        transcribe_btn = gr.Button(
                            "🎧 Transcribe Audio", 
                            variant="primary"
                        )
                        
                    with gr.Column():
                        transcription_output = gr.Textbox(
                            label="Transcription Result (CHAT Format)", 
                            placeholder="Transcribed text will appear here...",
                            lines=15
                        )
                        
                        transcription_status = gr.Markdown("")
                        
                        copy_to_analysis_btn = gr.Button(
                            "📋 Use for Analysis", 
                            variant="secondary"
                        )
            
            # Information Tab
            with gr.TabItem("ℹ️ About"):
                gr.Markdown("""
                ## About the CASL Analysis Tool
                
                This tool provides comprehensive speech-language assessment using the CASL-2 (Comprehensive Assessment of Spoken Language) framework.
                
                ### Features:
                - **Speech Factor Analysis**: Automated detection of disfluencies, word retrieval issues, grammatical errors, and repetitions
                - **CASL-2 Domains**: Assessment of Lexical/Semantic, Syntactic, and Supralinguistic skills
                - **Professional Scoring**: Standard scores, percentiles, and performance levels
                - **Audio Transcription**: Convert speech recordings to CHAT format transcripts
                - **Treatment Recommendations**: Evidence-based intervention suggestions
                
                ### Supported Formats:
                - **Text Files**: .txt format with manual transcript entry
                - **CHAT Files**: .cha format following CHILDES conventions
                - **Audio Files**: .wav, .mp3, .m4a, .ogg for automatic transcription
                
                ### CHAT Format Guidelines:
                - Use `*PAR:` for patient utterances
                - Use `*INV:` for investigator/clinician utterances  
                - Mark filled pauses as `&-um`, `&-uh`
                - Mark repetitions with `[/]`
                - Mark revisions with `[//]`
                - Mark errors with `[*]`
                
                ### Usage Tips:
                1. Load a sample transcript to see the expected format
                2. Enter patient information for context-appropriate analysis
                3. Upload or type transcript in CHAT format for best results
                4. Review analysis results and treatment recommendations
                5. Export professional PDF reports for clinical documentation
                
                ### Technical Notes:
                - **Demo Mode**: Works without external dependencies using simulated analysis
                - **Enhanced Mode**: Requires AWS Bedrock credentials for AI-powered analysis
                - **Audio Processing**: Requires speech_recognition library for real transcription
                - **PDF Export**: Requires ReportLab library for professional reports
                
                For support or questions, please refer to the documentation.
                """)
        
        # Event Handlers
        def load_sample_transcript(sample_name):
            """Load selected sample transcript"""
            if sample_name and sample_name in SAMPLE_TRANSCRIPTS:
                return SAMPLE_TRANSCRIPTS[sample_name]
            return ""
        
        def perform_analysis(transcript_text, age_val, gender_val):
            """Perform CASL analysis on transcript"""
            if not transcript_text or len(transcript_text.strip()) < 20:
                return "❌ **Error**: Please provide a longer transcript (minimum 20 characters) for meaningful analysis."
            
            try:
                # Perform analysis
                results = analyze_transcript(transcript_text, age_val, gender_val)
                return results['full_report']
                
            except Exception as e:
                logger.exception("Analysis error")
                return f"❌ **Error during analysis**: {str(e)}\n\nPlease check your transcript format and try again."
        
        def copy_transcription_to_analysis(transcription_text):
            """Copy transcription result to analysis tab"""
            return transcription_text
        
        # Connect event handlers
        sample_selector.change(
            load_sample_transcript, 
            inputs=[sample_selector], 
            outputs=[transcript]
        )
        
        file_upload.upload(
            process_upload, 
            inputs=[file_upload], 
            outputs=[transcript]
        )
        
        analyze_btn.click(
            perform_analysis,
            inputs=[transcript, age, gender],
            outputs=[analysis_output]
        )
        
        transcribe_btn.click(
            transcribe_audio,
            inputs=[audio_input],
            outputs=[transcription_output, transcription_status]
        )
        
        copy_to_analysis_btn.click(
            copy_transcription_to_analysis,
            inputs=[transcription_output],
            outputs=[transcript]
        )
    
    return app

# Create and launch the application
if __name__ == "__main__":
    # Check for optional dependencies
    missing_deps = []
    if not REPORTLAB_AVAILABLE:
        missing_deps.append("reportlab (for PDF export)")
    if not SPEECH_RECOGNITION_AVAILABLE:
        missing_deps.append("speech_recognition & pydub (for audio transcription)")
    
    if missing_deps:
        print("📋 Optional dependencies not found:")
        for dep in missing_deps:
            print(f"  - {dep}")
        print("The app will work with reduced functionality.")
    
    if not bedrock_client:
        print("ℹ️  AWS credentials not configured - using demo mode for analysis.")
        print("   Configure AWS_ACCESS_KEY and AWS_SECRET_KEY for enhanced AI analysis.")
    
    print("🚀 Starting CASL Analysis Tool...")
    
    # Create and launch the app
    app = create_interface()
    app.launch(
        show_api=False,
        server_name="0.0.0.0",
        server_port=7860
    )