#!/usr/bin/env python3
"""
Fix inverted styling on PHAT CEO deck - all 21 slides
"""

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"""
    requests = []
    
    if element_type == "context":
        # Context label: Montserrat, 10pt, bold, RED, center aligned, positioned top-left small
        requests.extend([
            {
                "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"
                }
            },
            {
                "updateParagraphStyle": {
                    "objectId": element_id,
                    "style": {
                        "alignment": "CENTER"
                    },
                    "fields": "alignment"
                }
            },
            {
                "updatePageElementTransform": {
                    "objectId": element_id,
                    "transform": {
                        "scaleX": 1.0,
                        "scaleY": 1.0,
                        "translateX": 457200,
                        "translateY": 274320,
                        "unit": "EMU"
                    },
                    "fields": "scaleX,scaleY,translateX,translateY"
                }
            },
            {
                "updatePageElementSize": {
                    "objectId": element_id,
                    "size": {
                        "width": {"magnitude": 1828800, "unit": "EMU"},
                        "height": {"magnitude": 274320, "unit": "EMU"}
                    },
                    "fields": "width,height"
                }
            }
        ])
    
    elif element_type == "title":
        # Title: Montserrat, 28pt, bold, BLACK, positioned below context
        requests.extend([
            {
                "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"
                }
            },
            {
                "updatePageElementTransform": {
                    "objectId": element_id,
                    "transform": {
                        "scaleX": 1.0,
                        "scaleY": 1.0,
                        "translateX": 457200,
                        "translateY": 640080,
                        "unit": "EMU"
                    },
                    "fields": "scaleX,scaleY,translateX,translateY"
                }
            },
            {
                "updatePageElementSize": {
                    "objectId": element_id,
                    "size": {
                        "width": {"magnitude": 7772400, "unit": "EMU"},
                        "height": {"magnitude": 548640, "unit": "EMU"}
                    },
                    "fields": "width,height"
                }
            }
        ])
    
    elif element_type == "body":
        # Body: Noto Sans, 14pt, not bold, DARK GRAY, positioned below title
        requests.extend([
            {
                "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"
                }
            },
            {
                "updatePageElementTransform": {
                    "objectId": element_id,
                    "transform": {
                        "scaleX": 1.0,
                        "scaleY": 1.0,
                        "translateX": 457200,
                        "translateY": 1371600,
                        "unit": "EMU"
                    },
                    "fields": "scaleX,scaleY,translateX,translateY"
                }
            },
            {
                "updatePageElementSize": {
                    "objectId": element_id,
                    "size": {
                        "width": {"magnitude": 7772400, "unit": "EMU"},
                        "height": {"magnitude": 3200400, "unit": "EMU"}
                    },
                    "fields": "width,height"
                }
            }
        ])
    
    return requests

def main():
    """Main function to fix all slides"""
    print("🚀 Starting PHAT deck styling fix...")
    
    # 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
        for element_type, element in identified.items():
            if element:
                element_id = element['objectId']
                styling_requests = create_styling_request(element_id, element_type)
                slide_requests.extend(styling_requests)
                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\n\n"
        report_content += f"**Presentation ID:** {PRESENTATION_ID}\n"
        report_content += f"**Total slides processed:** {len(results)}\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 formatting and positioning.\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