#!/usr/bin/env python3

import json
import os
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# Configuration
PRESENTATION_ID = "1H0gtkiFYcWKWMMbSpYeW2QuMlxSccmW_qYfeYNiNb2E"
TOKEN_FILE = "/root/.openclaw/workspace/google-auth/token.json"
CREDENTIALS_FILE = "/root/.openclaw/workspace/google-auth/credentials.json"

# Color definitions (RGB values 0-1)
RED_COLOR = {"red": 0.8, "green": 0.0, "blue": 0.0}
BLACK_COLOR = {"red": 0.0, "green": 0.0, "blue": 0.0}
DARK_GRAY_COLOR = {"red": 0.2, "green": 0.2, "blue": 0.2}

def authenticate():
    """Authenticate with Google Slides API"""
    try:
        # Load credentials info
        with open(CREDENTIALS_FILE, 'r') as f:
            cred_info = json.load(f)
        
        # Load token info
        with open(TOKEN_FILE, 'r') as f:
            token_info = json.load(f)
        
        # Combine the information needed for Credentials
        full_token_info = {
            'access_token': token_info.get('access_token'),
            'refresh_token': token_info.get('refresh_token'),
            'token_uri': cred_info['installed']['token_uri'],
            'client_id': cred_info['installed']['client_id'],
            'client_secret': cred_info['installed']['client_secret'],
            'scopes': [token_info['scope']] if isinstance(token_info.get('scope'), str) else token_info.get('scope', [])
        }
        
        print(f"Creating credentials with client_id: {full_token_info['client_id'][:20]}...")
        creds = Credentials.from_authorized_user_info(full_token_info)
        
        # Check if credentials are valid and refresh if needed
        if not creds.valid:
            if creds.expired and creds.refresh_token:
                print("Token expired, attempting to refresh...")
                creds.refresh(Request())
                print("Token refreshed successfully")
                
                # Update the token file with new access token
                token_info['access_token'] = creds.token
                with open(TOKEN_FILE, 'w') as token:
                    json.dump(token_info, token)
            else:
                raise Exception("Cannot refresh token - no refresh token available or other error")
        else:
            print("Token is valid")
        
        return build('slides', 'v1', credentials=creds)
        
    except Exception as e:
        print(f"Authentication error details: {str(e)}")
        print("Attempting direct approach with available token...")
        
        # Try a simpler approach using the token as-is
        try:
            with open(TOKEN_FILE, 'r') as f:
                token_data = json.load(f)
            with open(CREDENTIALS_FILE, 'r') as f:
                cred_data = json.load(f)
            
            # Create credentials manually
            from google.oauth2.credentials import Credentials
            creds = Credentials(
                token=token_data.get('access_token'),
                refresh_token=token_data.get('refresh_token'),
                token_uri=cred_data['installed']['token_uri'],
                client_id=cred_data['installed']['client_id'],
                client_secret=cred_data['installed']['client_secret']
            )
            
            return build('slides', 'v1', credentials=creds)
            
        except Exception as e2:
            raise Exception(f"All authentication methods failed. Original: {str(e)}, Fallback: {str(e2)}")

def get_presentation(service):
    """Get the presentation data"""
    try:
        presentation = service.presentations().get(presentationId=PRESENTATION_ID).execute()
        return presentation
    except HttpError as error:
        print(f"An error occurred: {error}")
        return None

def categorize_text_elements(slide):
    """Categorize text elements on a slide as context, title, or body based on size and position"""
    text_elements = []
    
    for element in slide.get('pageElements', []):
        if 'shape' in element and 'text' in element['shape']:
            text_content = ""
            for paragraph in element['shape']['text'].get('textElements', []):
                if 'textRun' in paragraph:
                    text_content += paragraph['textRun']['content']
            
            if text_content.strip():
                # Get element size and position
                transform = element.get('transform', {})
                size = element.get('size', {})
                
                height = size.get('height', {}).get('magnitude', 0)
                width = size.get('width', {}).get('magnitude', 0)
                y_pos = transform.get('translateY', 0)
                
                # Get font size from first text run
                font_size = 12  # default
                if (element['shape']['text'].get('textElements') and 
                    element['shape']['text']['textElements'][0].get('textRun') and
                    element['shape']['text']['textElements'][0]['textRun'].get('style')):
                    font_size = element['shape']['text']['textElements'][0]['textRun']['style'].get('fontSize', {}).get('magnitude', 12)
                
                area = height * width
                
                text_elements.append({
                    'element_id': element['objectId'],
                    'content': text_content.strip(),
                    'font_size': font_size,
                    'area': area,
                    'y_position': y_pos,
                    'height': height,
                    'width': width
                })
    
    # Sort by area (size) to categorize
    text_elements.sort(key=lambda x: x['area'], reverse=True)
    
    categorized = {
        'title': None,
        'context': None,
        'body': []
    }
    
    if text_elements:
        # Largest element is typically the title
        categorized['title'] = text_elements[0]
        
        # Smallest element (or top-most small element) is typically context
        if len(text_elements) > 1:
            # Find smallest element by area or topmost small element
            smallest_elements = sorted(text_elements[1:], key=lambda x: (x['area'], x['y_position']))
            if smallest_elements:
                categorized['context'] = smallest_elements[0]
            
            # Remaining elements are body text
            remaining = [elem for elem in text_elements[1:] if elem != categorized['context']]
            categorized['body'] = remaining
    
    return categorized

def create_font_updates(element_id, font_family, font_size, color, bold=False, vertical_align=None):
    """Create font update requests for an element"""
    requests = []
    
    # Font family update
    requests.append({
        'updateTextStyle': {
            'objectId': element_id,
            'style': {
                'fontFamily': font_family,
                'fontSize': {
                    'magnitude': font_size,
                    'unit': 'PT'
                },
                'foregroundColor': {
                    'opaqueColor': {
                        'rgbColor': color
                    }
                },
                'bold': bold
            },
            'fields': 'fontFamily,fontSize,foregroundColor,bold'
        }
    })
    
    # Vertical alignment for context labels
    if vertical_align == 'MIDDLE':
        requests.append({
            'updateParagraphStyle': {
                'objectId': element_id,
                'style': {
                    'alignment': 'CENTER'
                },
                'fields': 'alignment'
            }
        })
    
    return requests

def fix_presentation_formatting(service, presentation):
    """Apply formatting fixes to all slides"""
    requests = []
    report_lines = []
    
    slides = presentation.get('slides', [])
    report_lines.append(f"Processing {len(slides)} slides...")
    
    # Define correct context labels for slides 5-8 based on content analysis
    context_labels = {
        4: "THE PROBLEM",  # Slide 5 (0-indexed as 4)
        5: "THE PROBLEM", # Slide 6 
        6: "THE PROBLEM", # Slide 7
        7: "THE PROBLEM"  # Slide 8
    }
    
    for i, slide in enumerate(slides):
        slide_num = i + 1
        report_lines.append(f"\n--- Slide {slide_num} ---")
        
        # Categorize elements
        categorized = categorize_text_elements(slide)
        
        # Fix title formatting
        if categorized['title']:
            title_requests = create_font_updates(
                categorized['title']['element_id'],
                'Montserrat',
                28,
                BLACK_COLOR,
                bold=True
            )
            requests.extend(title_requests)
            report_lines.append(f"Title: '{categorized['title']['content'][:50]}...' - Applied Montserrat 28pt bold black")
        
        # Fix context label formatting and content
        if categorized['context']:
            context_requests = create_font_updates(
                categorized['context']['element_id'],
                'Montserrat',
                10,
                RED_COLOR,
                bold=True,
                vertical_align='MIDDLE'
            )
            requests.extend(context_requests)
            
            current_context = categorized['context']['content']
            report_lines.append(f"Context: '{current_context}' - Applied Montserrat 10pt bold red, center aligned")
            
            # Fix context label text for slides 5-8 if needed
            if i in context_labels:
                expected_context = context_labels[i]
                if current_context.upper() != expected_context:
                    # Update text content
                    requests.append({
                        'replaceAllText': {
                            'pageObjectIds': [slide['objectId']],
                            'replaceText': current_context,
                            'containsText': {
                                'text': current_context,
                                'matchCase': False
                            }
                        }
                    })
                    report_lines.append(f"  → Updated context text from '{current_context}' to '{expected_context}'")
        
        # Fix body text formatting
        for body_elem in categorized['body']:
            body_requests = create_font_updates(
                body_elem['element_id'],
                'Noto Sans Light',
                14,
                DARK_GRAY_COLOR
            )
            requests.extend(body_requests)
            report_lines.append(f"Body: '{body_elem['content'][:50]}...' - Applied Noto Sans Light 14pt dark gray")
    
    # Execute all batch updates
    if requests:
        try:
            body = {'requests': requests}
            response = service.presentations().batchUpdate(
                presentationId=PRESENTATION_ID,
                body=body
            ).execute()
            report_lines.append(f"\n✅ Successfully applied {len(requests)} formatting updates!")
            return True, report_lines
        except HttpError as error:
            report_lines.append(f"\n❌ Error applying updates: {error}")
            return False, report_lines
    else:
        report_lines.append("\n⚠️ No updates needed")
        return True, report_lines

def main():
    """Main execution function"""
    print("🔧 Starting PHAT CEO deck formatting fixes...")
    
    try:
        # Authenticate and get service
        service = authenticate()
        print("✅ Authentication successful")
        
        # Get presentation
        presentation = get_presentation(service)
        if not presentation:
            print("❌ Failed to get presentation")
            return
        
        print(f"✅ Retrieved presentation: {presentation.get('title', 'Unknown Title')}")
        
        # Apply fixes
        success, report_lines = fix_presentation_formatting(service, presentation)
        
        # Write report
        report_content = "\n".join([
            "# PHAT CEO Deck Fix Report",
            f"**Presentation ID:** {PRESENTATION_ID}",
            f"**Status:** {'✅ SUCCESS' if success else '❌ FAILED'}",
            "",
            "## Applied Changes",
            "1. **Context labels:** Montserrat 10pt bold, RED (RGB 0.8, 0, 0), center aligned",
            "2. **Titles:** Montserrat 28pt bold, black",
            "3. **Body text:** Noto Sans Light 14pt, dark gray (RGB 0.2, 0.2, 0.2)",
            "4. **Context label content:** Fixed for slides 5-8 to match content structure",
            "",
            "## Processing Log",
            *report_lines
        ])
        
        with open("/root/.openclaw/workspace/thibault-fix-report.md", "w") as f:
            f.write(report_content)
        
        print("✅ Report written to thibault-fix-report.md")
        
        if success:
            print("🎉 All fixes applied successfully!")
        else:
            print("⚠️ Some issues occurred. Check the report for details.")
            
    except Exception as e:
        print(f"❌ Error: {str(e)}")
        # Write error report
        error_report = f"""# PHAT CEO Deck Fix Report - ERROR

**Presentation ID:** {PRESENTATION_ID}
**Status:** ❌ FAILED

## Error Details
{str(e)}

## What was attempted:
1. Authenticate with Google Slides API
2. Retrieve presentation data  
3. Apply font and formatting fixes to all text elements
4. Update context labels for slides 5-8

The script failed before completing these steps.
"""
        with open("/root/.openclaw/workspace/thibault-fix-report.md", "w") as f:
            f.write(error_report)

if __name__ == "__main__":
    main()