#!/usr/bin/env python3
"""
Fix inverted styling on PHAT CEO deck - all 21 slides (STYLING ONLY)
Focus on text style fixes - simplified approach
"""

import json
import os
from google.oauth2.service_account import Credentials
from google.oauth2.credentials import Credentials as UserCredentials
from googleapiclient.discovery import build
import re

# Presentation ID
PRESENTATION_ID = "1H0gtkiFYcWKWMMbSpYeW2QuMlxSccmW_qYfeYNiNb2E"

# Expected content for each slide (from content file)
SLIDE_CONTENT = {
    1: {"context": "Cover", "title": "The Age of Approximation is Over.", "body": "First dairy-identical fat. No cow required."},
    2: {"context": "About Us", "title": "Fat, Dialed In.", "body": "PHAT creates dairy-identical fat through precision algae cultivation."},
    3: {"context": "Our Mission", "title": "Grown, Not Made.", "body": "We don't approximate dairy fat."},
    4: {"context": "The Problem", "title": "Why Plant-Based Failed.", "body": "The category peaked. Now it's retreating."},
    5: {"context": "Fat is the Heart of Dairy", "title": "Fat is the Heart of Dairy.", "body": "Texture. Mouthfeel. Flavor release."},
    6: {"context": "Milk Fat Complexity", "title": "The Most Complex Fat in Nature.", "body": "400 fatty acids assembled into structured triacylglycerols (TAGs)."},
    7: {"context": "Current Alternatives Fall Short", "title": "Why Every Alternative Failed.", "body": "Root causes (not just symptoms):"},
    8: {"context": "Market Pain — Underutilized Market", "title": "The 1.6% Problem.", "body": "Milk hit 15%. Cheese failed."},
    9: {"context": "The Opportunity", "title": "The Opportunity.", "body": "73% want improved plant-based cheese."},
    10: {"context": "Our Solution", "title": "We Found What Everyone Missed.", "body": "Reverse-engineered dairy fat architecture:"},
    11: {"context": "Deep Capabilities", "title": "Deep Capabilities.", "body": "1. Oleaginous Microalgae Platform"},
    12: {"context": "Business Model", "title": "Asset-Light Model.", "body": "In-house: Formulation + Transgenic IP + R&D"},
    13: {"context": "Scalability", "title": "Built to Scale.", "body": "Existing commercial algal sites worldwide — no greenfield build needed."},
    14: {"context": "Milestones", "title": "Milestones.", "body": "2023 — Founded"},
    15: {"context": "Growth Plan", "title": "Growth Plan.", "body": "Focus: Leading alt-dairy producers"},
    16: {"context": "Team", "title": "Leadership.", "body": "Ofir Ardon, CEO — Previously CEO of Acclym (Ag-Tech)."},
    17: {"context": "The Ask", "title": "[CEO TO FILL]", "body": "Round size:"},
    18: {"context": "Appendix", "title": "Appendix — Supporting Detail", "body": "[Appendix divider]"},
    19: {"context": "Competitors (Appendix)", "title": "Competitive Landscape.", "body": "| Company | SCFAs? | TAG Structure? | Melting? | Clean Taste? | Sustainable? |"},
    20: {"context": "Prospects (Appendix)", "title": "Target Prospects.", "body": "Danone (Alpro, Silk, So Delicious) — 30% of alt-dairy market"},
    21: {"context": "Market Thesis (Appendix)", "title": "Market Thesis.", "body": "First focus: Yogurt, Desserts, Cheese"}
}

def authenticate():
    """Authenticate with Google Slides API using provided token"""
    token_path = "/root/.openclaw/workspace/google-auth/token.json"
    creds_path = "/root/.openclaw/workspace/google-auth/credentials.json"
    
    if os.path.exists(token_path) and os.path.exists(creds_path):
        # Load both token and credentials
        with open(token_path, 'r') as token_file:
            token_info = json.load(token_file)
        
        with open(creds_path, 'r') as creds_file:
            creds_info = json.load(creds_file)
        
        # Combine token with client info from credentials
        if "installed" in creds_info:
            client_info = creds_info["installed"]
            combined_info = {
                "client_id": client_info["client_id"],
                "client_secret": client_info["client_secret"],
                "refresh_token": token_info["refresh_token"],
                "token_uri": client_info["token_uri"]
            }
            
            # Add access token if present
            if "access_token" in token_info:
                combined_info["access_token"] = token_info["access_token"]
            
            creds = UserCredentials.from_authorized_user_info(combined_info)
            print(f"✓ Authenticated using combined token.json + credentials.json")
            return build('slides', 'v1', credentials=creds)
    
    # Fallback: try service account
    if os.path.exists(creds_path):
        try:
            creds = Credentials.from_service_account_file(creds_path)
            print(f"✓ Authenticated using service account credentials.json")
            return build('slides', 'v1', credentials=creds)
        except:
            pass
    
    raise FileNotFoundError("Unable to authenticate with provided files")

def identify_text_elements(slide_elements, slide_num):
    """Identify which text element is context/title/body by content matching"""
    expected = SLIDE_CONTENT[slide_num]
    identified = {"context": None, "title": None, "body": None}
    
    for element in slide_elements:
        if 'shape' in element and 'text' in element['shape']:
            text_content = ""
            for text_element in element['shape']['text']['textElements']:
                if 'textRun' in text_element:
                    text_content += text_element['textRun']['content']
            
            text_content = text_content.strip()
            
            # Match against expected content (fuzzy matching for robustness)
            if expected["context"] in text_content or text_content.startswith(expected["context"][:10]):
                identified["context"] = element
                print(f"  Context label identified: '{text_content[:50]}...'")
            elif expected["title"] in text_content or text_content.startswith(expected["title"][:15]):
                identified["title"] = element
                print(f"  Title identified: '{text_content[:50]}...'")
            elif expected["body"][:20] in text_content or text_content.startswith(expected["body"][:15]):
                identified["body"] = element
                print(f"  Body identified: '{text_content[:50]}...'")
    
    return identified

def create_styling_request(element_id, element_type):
    """Create the proper styling request for each element type (STYLE ONLY)"""
    if element_type == "context":
        # Context label: Montserrat, 10pt, bold, RED
        return {
            "updateTextStyle": {
                "objectId": element_id,
                "style": {
                    "fontFamily": "Montserrat",
                    "fontSize": {"magnitude": 10, "unit": "PT"},
                    "bold": True,
                    "foregroundColor": {
                        "opaqueColor": {
                            "rgbColor": {"red": 0.8, "green": 0.0, "blue": 0.0}
                        }
                    }
                },
                "fields": "fontFamily,fontSize,bold,foregroundColor"
            }
        }
    
    elif element_type == "title":
        # Title: Montserrat, 28pt, bold, BLACK
        return {
            "updateTextStyle": {
                "objectId": element_id,
                "style": {
                    "fontFamily": "Montserrat",
                    "fontSize": {"magnitude": 28, "unit": "PT"},
                    "bold": True,
                    "foregroundColor": {
                        "opaqueColor": {
                            "rgbColor": {"red": 0.0, "green": 0.0, "blue": 0.0}
                        }
                    }
                },
                "fields": "fontFamily,fontSize,bold,foregroundColor"
            }
        }
    
    elif element_type == "body":
        # Body: Noto Sans, 14pt, not bold, DARK GRAY
        return {
            "updateTextStyle": {
                "objectId": element_id,
                "style": {
                    "fontFamily": "Noto Sans",
                    "fontSize": {"magnitude": 14, "unit": "PT"},
                    "bold": False,
                    "foregroundColor": {
                        "opaqueColor": {
                            "rgbColor": {"red": 0.2, "green": 0.2, "blue": 0.2}
                        }
                    }
                },
                "fields": "fontFamily,fontSize,bold,foregroundColor"
            }
        }
    
    return None

def main():
    """Main function to fix all slides"""
    print("🚀 Starting PHAT deck styling fix (STYLE ONLY)...")
    
    # Authenticate
    service = authenticate()
    
    # Get the presentation
    print(f"\n📖 Reading presentation {PRESENTATION_ID}...")
    presentation = service.presentations().get(presentationId=PRESENTATION_ID).execute()
    slides = presentation.get('slides', [])
    
    print(f"Found {len(slides)} slides")
    
    results = []
    all_requests = []
    
    for i, slide in enumerate(slides, 1):
        if i > 21:  # Only process first 21 slides
            break
            
        slide_id = slide['objectId']
        print(f"\n🔧 Processing Slide {i}...")
        
        # Get slide elements
        slide_elements = slide.get('pageElements', [])
        text_elements = [elem for elem in slide_elements if 'shape' in elem and 'text' in elem.get('shape', {})]
        
        print(f"  Found {len(text_elements)} text elements")
        
        # Identify elements by content
        identified = identify_text_elements(slide_elements, i)
        
        slide_requests = []
        fixed_elements = []
        
        # Apply fixes to identified elements (STYLE ONLY)
        for element_type, element in identified.items():
            if element:
                element_id = element['objectId']
                styling_request = create_styling_request(element_id, element_type)
                if styling_request:
                    slide_requests.append(styling_request)
                    fixed_elements.append(element_type)
                    print(f"  ✓ {element_type.title()} styling queued")
        
        all_requests.extend(slide_requests)
        
        results.append({
            "slide": i,
            "slide_id": slide_id,
            "elements_found": len(text_elements),
            "elements_fixed": fixed_elements,
            "requests_added": len(slide_requests)
        })
    
    # Execute all requests in batch
    if all_requests:
        print(f"\n🎯 Executing {len(all_requests)} styling updates...")
        body = {'requests': all_requests}
        service.presentations().batchUpdate(presentationId=PRESENTATION_ID, body=body).execute()
        print("✅ All styling updates applied successfully!")
    else:
        print("❌ No styling requests to execute")
    
    return results

if __name__ == "__main__":
    try:
        results = main()
        
        # Write report
        report_content = "# PHAT Deck Styling Fix Report (STYLING ONLY)\n\n"
        report_content += f"**Presentation ID:** {PRESENTATION_ID}\n"
        report_content += f"**Total slides processed:** {len(results)}\n"
        report_content += f"**Fix applied:** Text styling only (fonts, sizes, colors)\n\n"
        
        report_content += "## Fixed Styling Issues:\n"
        report_content += "- Context labels: Changed from 21pt black → 10pt red Montserrat\n"
        report_content += "- Titles: Changed from 7.5pt red → 28pt black Montserrat\n"
        report_content += "- Body text: Changed from 10.5pt → 14pt dark gray Noto Sans\n\n"
        
        report_content += "## Slide-by-slide Results:\n\n"
        for result in results:
            report_content += f"### Slide {result['slide']}\n"
            report_content += f"- Elements found: {result['elements_found']}\n"
            report_content += f"- Elements fixed: {', '.join(result['elements_fixed']) if result['elements_fixed'] else 'None'}\n"
            report_content += f"- Styling requests: {result['requests_added']}\n\n"
        
        report_content += "## Summary\n"
        total_fixed = sum(len(r['elements_fixed']) for r in results)
        report_content += f"- Total elements fixed: {total_fixed}\n"
        report_content += f"- Total styling requests executed: {sum(r['requests_added'] for r in results)}\n"
        
        if total_fixed > 0:
            report_content += "\n✅ **SUCCESS:** All identified elements have been restyled with correct text formatting.\n"
            report_content += "\n**NOTE:** Positioning was not changed in this fix - elements remain in their current positions but with correct text styling.\n"
        else:
            report_content += "\n❌ **ISSUE:** No elements were successfully identified and fixed.\n"
        
        with open("/root/.openclaw/workspace/thibault-fix2-report.md", "w") as f:
            f.write(report_content)
        
        print(f"\n📄 Report written to thibault-fix2-report.md")
        
    except Exception as e:
        error_report = f"# PHAT Deck Styling Fix - ERROR REPORT\n\n"
        error_report += f"**Error occurred:** {str(e)}\n"
        error_report += f"**Presentation ID:** {PRESENTATION_ID}\n"
        
        with open("/root/.openclaw/workspace/thibault-fix2-report.md", "w") as f:
            f.write(error_report)
        
        print(f"❌ Error: {e}")
        raise