import http.server, json, os, socketserver
from datetime import datetime
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
from googleapiclient.discovery import build

BASE       = '/Users/bryce/FLSM/.tmp'
SHEET_ID   = '1-GbrRGO165TVfr8W4aM6TtiJ_5EeK9bxR-Ryic63LAc'
CREDS_FILE = '/Users/bryce/.config/google-workspace-mcp/profiles/emerson-north/credentials.json'
TOKEN_FILE = '/Users/bryce/.config/google-workspace-mcp/profiles/emerson-north/tokens.json'
RSVP_FILE  = f'{BASE}/rsvps.json'  # local backup
SCOPES     = ['https://www.googleapis.com/auth/spreadsheets']

def get_sheets_service():
    with open(TOKEN_FILE) as f:
        t = json.load(f)
    with open(CREDS_FILE) as f:
        c = json.load(f)
    client = c.get('installed') or c.get('web', {})
    creds = Credentials(
        token=t['access_token'],
        refresh_token=t['refresh_token'],
        token_uri='https://oauth2.googleapis.com/token',
        client_id=client.get('client_id'),
        client_secret=client.get('client_secret'),
        scopes=SCOPES
    )
    if creds.expired:
        creds.refresh(Request())
        t['access_token'] = creds.token
        with open(TOKEN_FILE, 'w') as f:
            json.dump(t, f)
    return build('sheets', 'v4', credentials=creds, cache_discovery=False)

def rows_to_dicts(rows):
    if len(rows) < 2:
        return []
    headers = rows[0]
    return [dict(zip(headers, r + [''] * (len(headers) - len(r)))) for r in rows[1:]]

def get_all_rows():
    svc = get_sheets_service()
    res = svc.spreadsheets().values().get(spreadsheetId=SHEET_ID, range='Sheet1').execute()
    return res.get('values', [])

def find_existing_row(party_lead):
    rows = get_all_rows()
    for i, row in enumerate(rows[1:], start=2):  # 1-indexed, skip header
        if row and row[2].strip().lower() == party_lead.strip().lower():
            return i  # sheet row number
    return None

def upsert_rsvp(payload):
    party      = payload['party']
    welcome    = payload.get('welcome_party', True)
    message    = payload.get('message', '')
    party_lead = party[0]['name']
    now        = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    svc        = get_sheets_service()

    # Build rows — one per guest
    rows = []
    for i, member in enumerate(party):
        row = [
            now if i == 0 else '',   # Submitted At (first member only)
            now,                      # Updated At
            party_lead if i == 0 else '',
            member['name'],
            member['category'],
            'Yes' if member['attending'] else 'No',
            member.get('meal', ''),
            ('Yes' if welcome else 'No') if i == 0 else '',
            message if i == 0 else '',
        ]
        rows.append(row)

    existing_row = find_existing_row(party_lead)

    if existing_row:
        # Update in place — overwrite the block of rows starting at existing_row
        end_row = existing_row + len(rows) - 1
        range_str = f'Sheet1!A{existing_row}:I{end_row}'
        # Preserve original submission time
        existing = get_all_rows()
        orig_submitted = existing[existing_row - 1][0] if len(existing) >= existing_row else now
        rows[0][0] = orig_submitted  # keep original submitted_at
        svc.spreadsheets().values().update(
            spreadsheetId=SHEET_ID, range=range_str,
            valueInputOption='RAW', body={'values': rows}
        ).execute()
    else:
        svc.spreadsheets().values().append(
            spreadsheetId=SHEET_ID, range='Sheet1!A:I',
            valueInputOption='RAW', insertDataOption='INSERT_ROWS',
            body={'values': rows}
        ).execute()

    # Local backup
    local = []
    if os.path.exists(RSVP_FILE):
        with open(RSVP_FILE) as f:
            local = json.load(f)
    # Upsert locally too
    for i, entry in enumerate(local):
        if entry.get('party', [{}])[0].get('name', '').lower() == party_lead.lower():
            local[i] = payload
            break
    else:
        payload['submitted_at'] = now
        local.append(payload)
    payload['updated_at'] = now
    with open(RSVP_FILE, 'w') as f:
        json.dump(local, f, indent=2)

def get_existing_rsvp(party_lead):
    """Return existing RSVP for a party lead if found."""
    if not os.path.exists(RSVP_FILE):
        return None
    with open(RSVP_FILE) as f:
        data = json.load(f)
    for entry in data:
        if entry.get('party', [{}])[0].get('name', '').lower() == party_lead.lower():
            return entry
    return None

class Handler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=BASE, **kwargs)

    def end_headers(self):
        self.send_header('Cache-Control', 'no-store')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        super().end_headers()

    def do_OPTIONS(self):
        self.send_response(200); self.end_headers()

    def do_POST(self):
        length = int(self.headers.get('Content-Length', 0))
        body   = json.loads(self.rfile.read(length))

        if self.path == '/rsvp':
            try:
                upsert_rsvp(body)
                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.end_headers()
                self.wfile.write(json.dumps({'ok': True}).encode())
            except Exception as e:
                print(f'ERROR saving RSVP: {e}')
                self.send_response(500)
                self.send_header('Content-Type', 'application/json')
                self.end_headers()
                self.wfile.write(json.dumps({'ok': False, 'error': str(e)}).encode())

        elif self.path == '/rsvp/existing':
            party_lead = body.get('party_lead', '')
            existing   = get_existing_rsvp(party_lead)
            self.send_response(200)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps({'existing': existing}).encode())

        else:
            self.send_response(404); self.end_headers()

    def do_GET(self):
        if self.path == '/responses':
            data = []
            if os.path.exists(RSVP_FILE):
                with open(RSVP_FILE) as f:
                    data = json.load(f)
            self.send_response(200)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(data).encode())
        else:
            super().do_GET()

    def log_message(self, *a): pass

socketserver.TCPServer.allow_reuse_address = True
with socketserver.TCPServer(('0.0.0.0', 8097), Handler) as httpd:
    print('RSVP server running on :8097')
    httpd.serve_forever()
