#!/usr/bin/env python3
"""Fast duplicate removal using concurrent requests"""

import os
import sys
import requests
from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor, as_completed

NOTION_KEY = open(os.path.expanduser("~/.config/notion/api_key")).read().strip()
PEOPLE_DB = "142acbed-9e19-48e0-911f-2fc6513b564d"

headers = {
    "Authorization": f"Bearer {NOTION_KEY}",
    "Notion-Version": "2022-06-28",
    "Content-Type": "application/json"
}

def get_all_contacts():
    contacts = []
    next_cursor = None
    
    while True:
        payload = {"page_size": 100}
        if next_cursor:
            payload["start_cursor"] = next_cursor
            
        resp = requests.post(
            f"https://api.notion.com/v1/databases/{PEOPLE_DB}/query",
            headers=headers,
            json=payload
        )
        data = resp.json()
        
        for result in data.get("results", []):
            try:
                name = result["properties"]["Name"]["title"][0]["plain_text"]
            except (KeyError, IndexError):
                name = "unnamed"
            contacts.append({
                "id": result["id"],
                "name": name.strip().lower()
            })
        
        print(f"Fetched {len(contacts)}...", flush=True)
        
        if not data.get("has_more"):
            break
        next_cursor = data.get("next_cursor")
    
    return contacts

def find_duplicates(contacts):
    by_name = defaultdict(list)
    for c in contacts:
        by_name[c["name"]].append(c["id"])
    return {name: ids for name, ids in by_name.items() if len(ids) > 1}

def archive_page(page_id):
    try:
        resp = requests.patch(
            f"https://api.notion.com/v1/pages/{page_id}",
            headers=headers,
            json={"archived": True},
            timeout=30
        )
        return resp.status_code == 200
    except:
        return False

def archive_duplicates_parallel(duplicates, max_workers=10):
    to_archive = []
    for name, ids in duplicates.items():
        to_archive.extend(ids[1:])  # Keep first, archive rest
    
    print(f"Archiving {len(to_archive)} duplicates with {max_workers} workers...", flush=True)
    
    archived = 0
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = {executor.submit(archive_page, pid): pid for pid in to_archive}
        for i, future in enumerate(as_completed(futures)):
            if future.result():
                archived += 1
            if (i + 1) % 100 == 0:
                print(f"Progress: {i+1}/{len(to_archive)} ({archived} archived)", flush=True)
    
    return archived

if __name__ == "__main__":
    print("Fetching contacts...", flush=True)
    contacts = get_all_contacts()
    print(f"Total: {len(contacts)}", flush=True)
    
    print("Finding duplicates...", flush=True)
    duplicates = find_duplicates(contacts)
    total_dupes = sum(len(ids) - 1 for ids in duplicates.values())
    print(f"Found {total_dupes} duplicates to remove", flush=True)
    
    if "--delete" in sys.argv:
        archived = archive_duplicates_parallel(duplicates)
        print(f"\n✓ Archived {archived} duplicates", flush=True)
        print(f"Remaining contacts: ~{len(contacts) - archived}", flush=True)
    else:
        print("\nRun with --delete to archive", flush=True)
