#!/usr/bin/env python3
import json
import os
import re
from datetime import datetime
from pathlib import Path
import requests

WORKSPACE = Path('/Users/ahmad/.openclaw/workspace')
CRED = WORKSPACE / 'clickup_credentials.md'
BASE = 'https://api.clickup.com/api/v2'

AGENCY_SPACE_NAME = 'Agency OS (BigALC)'
PERSONAL_SPACE_NAME = 'Personal OS'

AGENCY_LISTS = [
    'Daily Command Center',
    'Clients',
    'Sales CRM',
    'Marketing Engine',
    'Operations',
    'Finance Admin',
    'Knowledge & SOPs',
    'Archive',
]

PERSONAL_LISTS = [
    'Daily Command Center',
    'Life Admin',
    'Health Fitness',
    'Learning Skills',
    'Relationships',
    'Personal Finance',
    'Goals Quarterly',
    'Archive',
]


def load_token():
    env = os.getenv('CLICKUP_API_TOKEN', '').strip()
    if env:
        return env
    txt = CRED.read_text(encoding='utf-8')
    m = re.search(r'\bpk_[A-Za-z0-9_]+\b', txt)
    if not m:
        raise RuntimeError('ClickUp token not found')
    return m.group(0)


class CU:
    def __init__(self, token):
        self.h = {'Authorization': token, 'Content-Type': 'application/json'}

    def req(self, method, path, **kwargs):
        url = f"{BASE}/{path.lstrip('/')}"
        r = requests.request(method, url, headers=self.h, timeout=45, **kwargs)
        if r.status_code >= 400:
            raise RuntimeError(f"{method} {path} -> {r.status_code}: {r.text[:300]}")
        if r.text.strip():
            return r.json()
        return {}

    def teams(self):
        return self.req('GET', 'team').get('teams', [])

    def spaces(self, team_id):
        return self.req('GET', f'team/{team_id}/space').get('spaces', [])

    def update_space(self, space_id, name, color='#4f46e5', private=False, admin_can_manage=True, multiple_assignees=True):
        payload = {
            'name': name,
            'color': color,
            'private': private,
            'admin_can_manage': admin_can_manage,
            'multiple_assignees': multiple_assignees,
            'features': {
                'due_dates': {'enabled': True, 'start_date': True, 'remap_due_dates': True, 'remap_closed_due_date': False},
                'time_tracking': {'enabled': True},
                'tags': {'enabled': True},
                'time_estimates': {'enabled': True},
                'checklists': {'enabled': True},
                'custom_fields': {'enabled': True},
                'remap_dependencies': {'enabled': True},
                'dependency_warning': {'enabled': True},
                'portfolios': {'enabled': True}
            }
        }
        return self.req('PUT', f'space/{space_id}', json=payload)

    def create_space(self, team_id, name):
        payload = {
            'name': name,
            'multiple_assignees': True,
            'features': {
                'due_dates': {'enabled': True, 'start_date': True, 'remap_due_dates': True, 'remap_closed_due_date': False},
                'time_tracking': {'enabled': True},
                'tags': {'enabled': True},
                'time_estimates': {'enabled': True},
                'checklists': {'enabled': True},
                'custom_fields': {'enabled': True},
                'remap_dependencies': {'enabled': True},
                'dependency_warning': {'enabled': True},
                'portfolios': {'enabled': True}
            }
        }
        return self.req('POST', f'team/{team_id}/space', json=payload)

    def folderless_lists(self, space_id):
        return self.req('GET', f'space/{space_id}/list').get('lists', [])

    def create_list(self, space_id, name):
        payload = {'name': name, 'content': '', 'status': None, 'priority': None, 'assignee': None, 'due_date': None}
        return self.req('POST', f'space/{space_id}/list', json=payload)

    def list_tasks(self, list_id):
        return self.req('GET', f'list/{list_id}/task', params={'include_closed': 'true'}).get('tasks', [])

    def create_task(self, list_id, name, description, tags=None):
        payload = {'name': name, 'description': description, 'tags': tags or []}
        return self.req('POST', f'list/{list_id}/task', json=payload)


def choose_space(spaces, preferred_names):
    for name in preferred_names:
        for s in spaces:
            if s.get('name') == name:
                return s
    return None


def ensure_space(cu, team_id, spaces, target_name, fallback_names):
    # 1) existing by exact name
    existing = choose_space(spaces, [target_name])
    if existing:
        return existing, False, False

    # 2) use fallback space as-is (no rename; avoids plan restrictions)
    fallback = choose_space(spaces, fallback_names)
    if fallback:
        return fallback, False, False

    # 3) create new if allowed
    created = cu.create_space(team_id, target_name)
    return created, False, True


def ensure_lists(cu, space_id, required_names):
    current = cu.folderless_lists(space_id)
    by_name = {l['name']: l for l in current}
    created = []
    for n in required_names:
        if n not in by_name:
            nl = cu.create_list(space_id, n)
            created.append(nl)
            by_name[n] = nl
    return by_name, created


def ensure_daily_start_task(cu, list_id, domain):
    tasks = cu.list_tasks(list_id)
    target = '🔥 Start Here — Daily Command Center'
    for t in tasks:
        if t.get('name') == target:
            return t

    if domain == 'agency':
        desc = (
            "Open this first every day.\n\n"
            "1) Pick top 3 priorities for today\n"
            "2) Pull urgent items from Clients / Sales / Marketing / Operations\n"
            "3) Check blocked items and unblock at least 1\n"
            "4) Review meeting follow-ups\n"
            "5) End-of-day: close done items, move leftovers intentionally\n"
        )
    else:
        desc = (
            "Open this first every day.\n\n"
            "1) Pick top 3 personal priorities\n"
            "2) Review health, learning, and life admin commitments\n"
            "3) Clear one pending personal blocker\n"
            "4) Confirm one progress action for long-term goals\n"
            "5) End-of-day reflection and carry-forward\n"
        )

    return cu.create_task(list_id, target, desc, tags=['daily-system', domain])


def main():
    token = load_token()
    cu = CU(token)

    # Safety backup snapshot
    ts = datetime.now().strftime('%Y%m%d_%H%M')
    backup_dir = WORKSPACE / 'clickup_restructure_backup' / ts
    backup_dir.mkdir(parents=True, exist_ok=True)

    teams = cu.teams()
    if not teams:
        raise RuntimeError('No ClickUp teams found')
    team = teams[0]
    team_id = team['id']

    spaces = cu.spaces(team_id)
    snapshot = {'team': team, 'spaces': spaces, 'lists_by_space': {}, 'timestamp': ts}
    for s in spaces:
        try:
            snapshot['lists_by_space'][s['id']] = cu.folderless_lists(s['id'])
        except Exception:
            snapshot['lists_by_space'][s['id']] = []

    (backup_dir / 'account_snapshot.json').write_text(json.dumps(snapshot, indent=2), encoding='utf-8')

    # Build/rename spaces
    spaces = cu.spaces(team_id)
    agency_space, agency_renamed, agency_created = ensure_space(
        cu, team_id, spaces, AGENCY_SPACE_NAME, ['Ops', 'Project Managment', 'Marketing']
    )

    spaces = cu.spaces(team_id)
    # avoid choosing same space id
    remaining = [s for s in spaces if s['id'] != agency_space['id']]
    personal_space, personal_renamed, personal_created = ensure_space(
        cu, team_id, remaining, PERSONAL_SPACE_NAME, ['Tech', 'Google Ads Hub Facebook Group', 'Sales']
    )

    # Ensure lists
    agency_lists, agency_created_lists = ensure_lists(cu, agency_space['id'], AGENCY_LISTS)
    personal_lists, personal_created_lists = ensure_lists(cu, personal_space['id'], PERSONAL_LISTS)

    # Ensure command center tasks
    agency_start = ensure_daily_start_task(cu, agency_lists['Daily Command Center']['id'], 'agency')
    personal_start = ensure_daily_start_task(cu, personal_lists['Daily Command Center']['id'], 'personal')

    report = []
    report.append('# ClickUp Account-Wide Restructure Report')
    report.append(f'- Timestamp: {datetime.now().isoformat(timespec="seconds")}')
    report.append(f'- Team: {team.get("name")} ({team_id})')
    report.append(f'- Backup: {backup_dir}')
    report.append('')
    report.append('## Spaces')
    report.append(f'- Agency space: {agency_space["name"]} ({agency_space["id"]}) | renamed={agency_renamed} created={agency_created}')
    report.append(f'- Personal space: {personal_space["name"]} ({personal_space["id"]}) | renamed={personal_renamed} created={personal_created}')
    report.append('')
    report.append('## Agency Lists')
    for n in AGENCY_LISTS:
        lid = agency_lists[n]['id']
        report.append(f'- {n}: https://app.clickup.com/v/li/{lid}')
    report.append('')
    report.append('## Personal Lists')
    for n in PERSONAL_LISTS:
        lid = personal_lists[n]['id']
        report.append(f'- {n}: https://app.clickup.com/v/li/{lid}')
    report.append('')
    report.append('## Command Center Start Tasks')
    report.append(f'- Agency: https://app.clickup.com/t/{agency_start.get("id")}')
    report.append(f'- Personal: https://app.clickup.com/t/{personal_start.get("id")}')

    out_report = WORKSPACE / 'clickup_account_restructure_report.md'
    out_report.write_text('\n'.join(report), encoding='utf-8')

    print(json.dumps({
        'backup_dir': str(backup_dir),
        'report': str(out_report),
        'agency_space': {'id': agency_space['id'], 'name': agency_space['name']},
        'personal_space': {'id': personal_space['id'], 'name': personal_space['name']},
        'agency_start_task': f"https://app.clickup.com/t/{agency_start.get('id')}",
        'personal_start_task': f"https://app.clickup.com/t/{personal_start.get('id')}"
    }, indent=2))


if __name__ == '__main__':
    main()
