#!/usr/bin/env python3
"""Add tables to the eToro SOW Google Doc."""
import json, requests, re

with open('/root/.openclaw/workspace/google-auth/token.json') as f:
    d = json.load(f)

r = requests.post('https://oauth2.googleapis.com/token', data={
    'client_id': d['client_id'],
    'client_secret': d['client_secret'],
    'refresh_token': d['refresh_token'],
    'grant_type': 'refresh_token'
})
access_token = r.json()['access_token']
headers = {'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json'}

DOC_ID = '10r3v7Xqm4tltaFoSpD4F7Vn_kGENJVQgeWrvJxKyc6Q'

def get_doc():
    r = requests.get(f'https://docs.googleapis.com/v1/documents/{DOC_ID}', headers=headers)
    return r.json()

def find_text_index(doc, text):
    """Find the start index of text in the document."""
    for elem in doc['body']['content']:
        if 'paragraph' in elem:
            for run in elem['paragraph'].get('elements', []):
                if 'textRun' in run:
                    content = run['textRun']['content']
                    if text in content:
                        return run['startIndex'] + content.index(text)
    return None

def find_line_end(doc, search_text):
    """Find the end index of the line containing search_text."""
    for elem in doc['body']['content']:
        if 'paragraph' in elem:
            full_text = ''
            for run in elem['paragraph'].get('elements', []):
                if 'textRun' in run:
                    full_text += run['textRun']['content']
            if search_text in full_text:
                return elem['endIndex']
    return None

def find_paragraph_range(doc, search_text):
    """Find start and end index of paragraph containing search_text."""
    for elem in doc['body']['content']:
        if 'paragraph' in elem:
            full_text = ''
            for run in elem['paragraph'].get('elements', []):
                if 'textRun' in run:
                    full_text += run['textRun']['content']
            if search_text in full_text:
                return elem['startIndex'], elem['endIndex']
    return None, None

def batch_update(reqs):
    r = requests.post(f'https://docs.googleapis.com/v1/documents/{DOC_ID}:batchUpdate',
        headers=headers, json={'requests': reqs})
    if r.status_code != 200:
        print(f'Error: {r.text[:500]}')
        return False
    return True

def delete_lines_between(doc, start_text, end_text):
    """Delete all content between line containing start_text and line containing end_text (exclusive)."""
    start_idx = None
    end_idx = None
    for elem in doc['body']['content']:
        if 'paragraph' in elem:
            full_text = ''
            for run in elem['paragraph'].get('elements', []):
                if 'textRun' in run:
                    full_text += run['textRun']['content']
            if start_text in full_text and start_idx is None:
                start_idx = elem['endIndex']  # delete AFTER this line
            if end_text in full_text and start_idx is not None:
                end_idx = elem['startIndex']  # delete BEFORE this line
                break
    return start_idx, end_idx

# Strategy: We'll replace the bullet-list sections with tables one at a time
# Work backwards (from bottom of doc) to avoid index shifts

doc = get_doc()
full_text = ''
for elem in doc['body']['content']:
    if 'paragraph' in elem:
        for run in elem['paragraph'].get('elements', []):
            if 'textRun' in run:
                full_text += run['textRun']['content']

# Let's take a simpler approach: delete the doc content and rebuild with tables
# First, get the total length
end_index = doc['body']['content'][-1]['endIndex']

print(f"Doc length: {end_index}")

# Delete everything
if end_index > 2:
    batch_update([{'deleteContentRange': {'range': {'startIndex': 1, 'endIndex': end_index - 1}}}])

print("Cleared doc. Rebuilding with tables...")

# Now rebuild section by section, inserting tables where needed
# We need to track the current index carefully

doc = get_doc()
idx = 1

def insert_text_at(text, bold=False, italic=False, font_size=11, font_family='Inter', color=None):
    global idx
    reqs = []
    reqs.append({'insertText': {'location': {'index': idx}, 'text': text + '\n'}})
    
    style = {'weightedFontFamily': {'fontFamily': font_family}, 'fontSize': {'magnitude': font_size, 'unit': 'PT'}}
    if bold: style['bold'] = True
    if italic: style['italic'] = True
    if color:
        rv, gv, bv = int(color[1:3],16)/255, int(color[3:5],16)/255, int(color[5:7],16)/255
        style['foregroundColor'] = {'color': {'rgbColor': {'red': rv, 'green': gv, 'blue': bv}}}
    
    reqs.append({
        'updateTextStyle': {
            'range': {'startIndex': idx, 'endIndex': idx + len(text)},
            'textStyle': style,
            'fields': 'bold,italic,fontSize,weightedFontFamily,foregroundColor'
        }
    })
    idx += len(text) + 1
    return reqs

def insert_table(rows, col_widths=None, header=True):
    """Insert a table. rows is list of lists of strings. First row is header if header=True."""
    global idx
    reqs = []
    n_rows = len(rows)
    n_cols = len(rows[0])
    
    reqs.append({'insertTable': {'rows': n_rows, 'columns': n_cols, 'location': {'index': idx}}})
    
    # We need to execute this first to get the table structure, then fill cells
    return reqs, rows, header

def execute_reqs(reqs):
    if not reqs:
        return True
    # batch in groups of 40
    for i in range(0, len(reqs), 40):
        if not batch_update(reqs[i:i+40]):
            return False
    return True

# Helper: insert text block then execute
def text_block(text, **kwargs):
    reqs = insert_text_at(text, **kwargs)
    execute_reqs(reqs)

def insert_table_with_data(rows, header_bg=True):
    """Insert table, then fill cells with data."""
    global idx
    n_rows = len(rows)
    n_cols = len(rows[0])
    
    # Insert empty table
    batch_update([{'insertTable': {'rows': n_rows, 'columns': n_cols, 'location': {'index': idx}}}])
    
    # Re-read doc to get table cell indices
    doc = get_doc()
    
    # Find the table we just inserted (should be near idx)
    table = None
    for elem in doc['body']['content']:
        if 'table' in elem and elem['startIndex'] >= idx - 1:
            table = elem['table']
            table_end = elem['endIndex']
            break
    
    if not table:
        print(f"Could not find table at index {idx}")
        return
    
    reqs = []
    for ri, row in enumerate(table['tableRows']):
        for ci, cell in enumerate(row['tableCells']):
            cell_start = cell['content'][0]['paragraph']['elements'][0]['startIndex']
            cell_end = cell['content'][0]['paragraph']['elements'][0]['endIndex']
            
            text = rows[ri][ci] if ri < len(rows) and ci < len(rows[ri]) else ''
            if text:
                reqs.append({'insertText': {'location': {'index': cell_start}, 'text': text}})
                
                style = {'fontSize': {'magnitude': 9 if ri > 0 else 9, 'unit': 'PT'}, 'weightedFontFamily': {'fontFamily': 'Inter'}}
                if ri == 0:
                    style['bold'] = True
                    style['weightedFontFamily'] = {'fontFamily': 'JetBrains Mono'}
                    style['fontSize'] = {'magnitude': 8, 'unit': 'PT'}
                    style['foregroundColor'] = {'color': {'rgbColor': {'red': 0.6, 'green': 0.6, 'blue': 0.6}}}
                
                reqs.append({
                    'updateTextStyle': {
                        'range': {'startIndex': cell_start, 'endIndex': cell_start + len(text)},
                        'textStyle': style,
                        'fields': 'bold,fontSize,weightedFontFamily,foregroundColor'
                    }
                })
    
    # Apply cell content - must go in REVERSE order to avoid index shifts
    reqs.reverse()
    execute_reqs(reqs)
    
    # Update idx to after table
    doc = get_doc()
    for elem in doc['body']['content']:
        if 'table' in elem and elem['startIndex'] >= idx - 1:
            idx = elem['endIndex']
            break
    
    # Add newline after table
    batch_update([{'insertText': {'location': {'index': idx}, 'text': '\n'}}])
    idx += 1

def sep():
    text_block('─────────────────────────────────────────────', font_size=8, color='#eeeeee')

# =================== BUILD DOCUMENT ===================

text_block('CURIOUS ENDEAVOR × eTORO', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Statement of Work', bold=True, font_size=28)
text_block('Brand Transformation & AI-Powered Production Systems', italic=True, font_size=14, color='#666666')
text_block('')
text_block('Date: February 2026  ·  Client: eToro  ·  Duration: 12-16 weeks', font_size=10, font_family='JetBrains Mono', color='#999999')
sep()
text_block('This Statement of Work ("SOW") made effective as of February 2026, is entered into by and between Curious Endeavor LLC, ("Curious Endeavor") and eToro ("Company"). Unless otherwise specified, capitalized terms used in this SOW shall have the meanings defined in the Agreement.')
text_block('')

# Timeline Overview
text_block('TIMELINE & INVESTMENT OVERVIEW', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Project Timeline', bold=True, font_size=18)
text_block('Total duration: ~5 weeks for Phases 1-2, with Phases 3-4 ongoing from Week 6. All dates assume client feedback within 2 business days per MSA Section 4.')
text_block('')

print("Inserting timeline table...")
insert_table_with_data([
    ['PHASE', 'DURATION', 'TIMELINE', 'DELIVERABLES', 'INVESTMENT'],
    ['Phase 1\nDiscovery + Tech Setup', '~2 weeks', 'Weeks 1–2', 'Competitive research, brand audit, strategy, Discord/AI infrastructure', '€50,000\ncombined'],
    ['Phase 2\nRebrand + Brand System', '~2.5 weeks', 'Weeks 3–5', 'Brand book, design system, UI component foundations', ''],
    ['Phases 3–4\nImplementation + Scale', 'Ongoing', 'Week 6+', 'Brand deployment, AI studios, campaign systems', '€20,000/mo'],
])

text_block('Note: Delays in client response extend delivery day-for-day.', italic=True, font_size=10, color='#999999')
sep()
text_block('')

# Phase 1
text_block('PHASE 1 · ~2 WEEKS', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Onboarding, Discovery & Tech Implementation', bold=True, font_size=18)
text_block('')

print("Inserting Phase 1 table...")
insert_table_with_data([
    ['PROCESS', 'TIME', 'DELIVERABLES'],
    ['C-Suite / leadership interviews', '2 days', 'Stakeholder insights document'],
    ['Brand perception audit (internal + external)', '1 day', 'Brand perception report'],
    ['Competitive deep-dive (visual, messaging, product)', '1 day', 'Exhaustive competitive research document'],
    ['Discord server setup with role-based access', '2 days', 'Dedicated Discord workspace'],
    ['AI workflow implementation', '2 days', 'AI-augmented production team + workflow docs'],
    ['Competitive research document', '2 days', 'Industry + competition landscape deck'],
    ['Technology and platform audit', 'optional', 'Platform audit report'],
    ['Brand positioning, narrative, pitch, mission', '~5 days', 'Brand narrative, mission, elevator pitch, gap analysis'],
    ['Team onboarding and training', 'optional', 'Training materials + onboarding sessions'],
    ['PHASE 1 TOTAL', '~15 DAYS', '~3 WORKING WEEKS'],
])

sep()
text_block('')

# Phase 2
text_block('PHASE 2 · ~2.5 WEEKS', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Rebrand: Design Direction & Brand System', bold=True, font_size=18)
text_block('')
text_block('Clarifications:', bold=True)
text_block('"Brand Design Lock" — formal sign-off on final creative direction.', font_size=10, color='#666666')
text_block('"UI component foundations" — core building blocks as design specs.', font_size=10, color='#666666')
text_block('"1 final design direction" — we present 2–3 options, eToro selects one.', font_size=10, color='#666666')
text_block('')

print("Inserting Phase 2 table...")
insert_table_with_data([
    ['PROCESS', 'TIME', 'DELIVERABLES'],
    ['2–3 inspiration directions + moodboards', '2 days', 'Moodboards + reference collection'],
    ['Stakeholder alignment sessions', '1 day', 'Alignment on chosen direction'],
    ['Brand Design Lock — 1 final direction', '3 days', 'Creative direction + rationale document'],
    ['Logo system development', '3 days', 'Logo system, usage + clear space rules'],
    ['Color palette + typography system', '1 day', 'Primary/secondary/extended palette + type system'],
    ['Tone of voice + photo language', '1 day', 'TOV guidelines, photo language guide'],
    ['Brand architecture + UI foundations', '1 day', 'Brand architecture map, UI foundations'],
    ['PHASE 2 TOTAL', '~12 DAYS', '~2.5 WORKING WEEKS'],
    ['Iteration rounds (3 included)', 'additional', 'Depends on client feedback turnaround'],
])

sep()
text_block('')

# Brand Book
text_block('BRAND BOOK SCOPE', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Digital, interactive brand book hosted on a dedicated webpage — not a static PDF.', italic=True)
text_block('')

print("Inserting Brand Book table...")
insert_table_with_data([
    ['SECTION', 'CONTENTS'],
    ['Brand Strategy', 'Creative direction, brand narrative, mission statement, elevator pitch, positioning'],
    ['Logo System', 'Logo concept, usage rules, clear space, minimum sizes, do\'s/don\'ts, file formats'],
    ['Color Palette', 'Primary/secondary/extended palette, hex/RGB/CMYK, usage guidelines, accessibility'],
    ['Typography', 'Type hierarchy, font families, weights, sizes, spacing, usage rules'],
    ['Tone of Voice', 'Voice principles, writing guidelines, example copy for different contexts'],
    ['Photo & Image Language', 'Photography style, treatment guide, composition rules, illustration guidelines'],
    ['Visual Language & Iconography', 'Icon system, visual language guidelines, graphic elements'],
    ['Brand Architecture', 'Sub-brand relationships, naming conventions, brand hierarchy'],
    ['UI Component Foundations', 'Core building blocks as design specifications for engineering teams'],
])

sep()
text_block('')

# Phase 3 & 4
text_block('PHASE 3 (OPTIONAL) · ~3-4 WEEKS', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Implementation', bold=True, font_size=18)
text_block('Brand deployment across touchpoints. Three AI + human studios: photography, screen/product imagery, motion design.')
sep()
text_block('')
text_block('PHASE 4 (OPTIONAL) · ~3-5 WEEKS', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Scale: Campaign Machine & Automation', bold=True, font_size=18)
text_block('Campaign generation, landing pages, multi-variant creative, full funnel automation.')
sep()
text_block('')

# Investment
text_block('YOUR INVESTMENT & PAYMENT TERMS', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('')
text_block('Brand Transformation (Phases 1-2): €50,000', bold=True, font_size=16)
text_block('Complete rebrand: discovery, strategy, brand book, design system.', color='#666666')
text_block('')
text_block('Implementation Support (Phases 3-4) · Optional: €20,000/month', bold=True, font_size=16)
text_block('Accompanying internal team through implementation and scale.', color='#666666')
text_block('')
text_block('Payment — milestone-based, invoices due within 15 days:', bold=True)
text_block('▸ 50% upon signing (€25,000) — covers Phase 1 + Phase 2 initiation')
text_block('▸ 50% upon brand book delivery (€25,000) — subject to written approval per MSA §1.3')
sep()
text_block('')

# Expenses
text_block('EXPENSES & OPERATIONAL COSTS', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('All operational expenses borne by eToro: API calls, software licenses, font licensing, image rights, domain costs, hosting, third-party fees. Itemized reporting upon request.')
sep()
text_block('')

# IP
text_block('IP & SYSTEM OWNERSHIP', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Intellectual Property & System Ownership', bold=True, font_size=18)
text_block('Licensed model: eToro interacts through brand interface (inputs → outputs). Engine remains CE\'s IP.')
text_block('')

print("Inserting IP ownership table...")
insert_table_with_data([
    ['eTORO OWNS OUTRIGHT', 'CURIOUS ENDEAVOR RETAINS'],
    ['All brand assets, design system, visual output', 'AI agent architecture, configurations, prompt engineering'],
    ['Visual language, iconography, design deliverables', 'System configuration files, setup, technical infrastructure'],
    ['Brand book and all brand documentation', 'Custom prompts, prompt templates, prompt logic'],
    ['All content/creative output from the system', 'Production workflow logic and automation systems'],
    ['Full right to use, modify, extend all output', 'Core methodology, frameworks, strategic approach'],
    ['', 'Proprietary tools, templates, base systems'],
    ['', 'Discord server structure, roles, channels, bots'],
    ['', 'Training methods and operational playbooks'],
])

text_block('')
text_block('PERPETUAL OPERATING LICENSE', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('')

print("Inserting May/May Not table...")
insert_table_with_data([
    ['eTORO MAY', 'eTORO MAY NOT'],
    ['Operate the system day-to-day for eToro brand work', 'Access/extract/inspect agent architecture, prompts, or workflow logic'],
    ['Modify brand book and design system at will', 'Duplicate or adapt for other brands or purposes beyond this SOW'],
    ['Update brand guidelines and design tokens', 'Share, sublicense, or let third parties study/copy/reverse-engineer'],
    ['Prompt the system to create assets and content', 'Hire third parties to modify agent layer or system architecture'],
    ['Evolve the brand — all brand-level changes in eToro\'s control', 'Reverse-engineer methodology to build competing system'],
    ['Use for the eToro brand as defined in this SOW', ''],
])

text_block('')
text_block('System-Level Modifications require CE. Exclusive implementation rights for 12 months post-completion.', bold=True, font_size=10)
sep()
text_block('')

# PR
text_block('PR RIGHTS & DOCUMENTATION', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('')

print("Inserting PR table...")
insert_table_with_data([
    ['CE MAY FREELY SHARE', 'REQUIRES eTORO APPROVAL'],
    ['Process, methodology, tools, behind-the-scenes on social media', 'eToro name/logo in press or marketing campaigns'],
    ['Screenshots of our own tools and systems', 'Unreleased or in-progress brand assets'],
    ['General descriptions ("working with a major fintech")', 'eToro internal or confidential materials'],
    ['Visual work samples (excl. logo + unreleased finals)', 'Formal case studies naming eToro'],
    ['Post-launch portfolio samples', 'Media interviews referencing eToro directly'],
    ['Conference/podcast appearances using process materials', ''],
])

text_block('')
text_block('Approval not unreasonably withheld. Joint PR strategy in Phase 1.', italic=True)
text_block('Credit: eToro credits CE as strategic partner incl. Dan Peguine and Assaf Dagan by name.')
sep()
text_block('')

# SLAs
text_block('SERVICE LEVEL AGREEMENTS', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('')

print("Inserting SLA table...")
insert_table_with_data([
    ['TYPE', 'CURIOUS ENDEAVOR', 'eTORO (PER MSA §4)'],
    ['Day-to-day requests', '1 business day', '2 business days'],
    ['New / unanticipated requests', '1 business day', '4 business days'],
    ['Design validation / approval', '—', '10 business days'],
])

text_block('Working days: Mon–Fri. Weekends/holidays excluded.', italic=True, font_size=10, color='#999999')
sep()
text_block('')

# Timeline Impact
text_block('TIMELINE & APPROVAL IMPACT', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Client delays extend delivery day-for-day. Example: feedback on Day 10 → timeline shifts 8 days.')
sep()
text_block('')

# Governance
text_block('GOVERNANCE', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('▸ Designated Project Contacts for day-to-day decisions')
text_block('▸ Weekly 30-min sync between contacts')
text_block('▸ Discord workspace as primary collaboration channel')
text_block('▸ 3-day escalation to senior leadership')
sep()
text_block('')

# Liability
text_block('LIABILITY', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('Per MSA §10 and §12. No indirect/consequential damages. Total liability capped at SOW amounts paid.')
sep()
text_block('')

# Signatures
text_block('SIGNATURES', bold=True, font_size=10, font_family='JetBrains Mono', color='#cc0000')
text_block('')
text_block('Curious Endeavor LLC', bold=True, font_size=14)
text_block('Name: ____________________________    Title: ____________________________')
text_block('Signature: ________________________    Date: _____________________________')
text_block('')
text_block('eToro', bold=True, font_size=14)
text_block('Name: ____________________________    Title: ____________________________')
text_block('Signature: ________________________    Date: _____________________________')
text_block('')
text_block('Creativity is a curious and unexpected endeavor.', italic=True, font_size=10, color='#cc0000')

print(f"\nDone! https://docs.google.com/document/d/{DOC_ID}/edit")
