"""Analyze Temp vs Contacts folders for merge strategy."""
import subprocess, json, sys

TENANT_ID = "dd4a82e8-85a3-44ac-8800-07945ab4d95f"
CLAUDE_APP = "fabb3421-8b34-484b-bc17-e46de9703418"
CLAUDE_SECRET = "~QJ8Q~NyQSs4OcGqHZyPrA2CVnq9KBfKiimntbMO"
USER = "barbara@bardach.net"

# All contact fields we want to preserve
SELECT_FIELDS = (
    "id,displayName,givenName,surname,middleName,nickName,"
    "emailAddresses,homePhones,businessPhones,"
    "companyName,jobTitle,department,"
    "homeAddress,businessAddress,otherAddress,"
    "birthday,personalNotes,"
    "categories,title,generation,imAddresses,"
    "parentFolderId"
)

def get_token():
    r = subprocess.run([
        'curl', '-s', '-X', 'POST',
        f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token',
        '-d', f'client_id={CLAUDE_APP}&client_secret={CLAUDE_SECRET}&scope=https://graph.microsoft.com/.default&grant_type=client_credentials'
    ], capture_output=True, text=True)
    return json.loads(r.stdout)['access_token']

def pull_contacts(token, folder_id=None, folder_name="default"):
    if folder_id:
        base = f"https://graph.microsoft.com/v1.0/users/{USER}/contactFolders/{folder_id}/contacts"
    else:
        base = f"https://graph.microsoft.com/v1.0/users/{USER}/contacts"

    url = f"{base}?$top=100&$select={SELECT_FIELDS}"
    all_contacts = []
    page = 0

    while url:
        page += 1
        r = subprocess.run(['curl', '-s', '-H', f'Authorization: Bearer {token}', url],
                          capture_output=True, text=True)
        data = json.loads(r.stdout)

        if 'error' in data:
            print(f"  Error: {data['error'].get('message','')[:200]}")
            break

        items = data.get('value', [])
        all_contacts.extend(items)
        url = data.get('@odata.nextLink')

        if page % 10 == 0:
            print(f"  {folder_name}: page {page}, {len(all_contacts)} contacts...")

        if not items:
            break

    print(f"  {folder_name}: {len(all_contacts)} total")
    return all_contacts

token = get_token()
print("[OK] Token acquired\n")

# Get folder IDs
print("Getting contact folders...")
r = subprocess.run(['curl', '-s', '-H', f'Authorization: Bearer {token}',
    f'https://graph.microsoft.com/v1.0/users/{USER}/contactFolders?$select=displayName,id'],
    capture_output=True, text=True)
folders = json.loads(r.stdout).get('value', [])
temp_id = None
contacts_id = None
for f in folders:
    print(f"  {f['displayName']}: {f['id'][:40]}...")
    if f['displayName'] == 'Temp':
        temp_id = f['id']
    elif f['displayName'] == 'Contacts':
        contacts_id = f['id']

if not temp_id:
    print("[ERROR] Temp folder not found!")
    sys.exit(1)

# Pull both folders
print("\nPulling Contacts folder...")
main_contacts = pull_contacts(token, contacts_id, "Contacts")

print("\nPulling Temp folder...")
temp_contacts = pull_contacts(token, temp_id, "Temp")

# Save raw data
with open('D:/ClaudeTools/temp/bardach_main_contacts.json', 'w') as f:
    json.dump(main_contacts, f, indent=2)
with open('D:/ClaudeTools/temp/bardach_temp_contacts.json', 'w') as f:
    json.dump(temp_contacts, f, indent=2)
print(f"\nSaved raw data files")

# Build matching keys
def make_key(c):
    """Create a matching key from name."""
    name = (c.get('displayName') or '').strip().lower()
    return name

def make_email_keys(c):
    """Get all email addresses as keys."""
    return set(e.get('address', '').strip().lower()
               for e in c.get('emailAddresses', [])
               if e.get('address'))

# Index main contacts
main_by_name = {}
main_by_email = {}
for c in main_contacts:
    key = make_key(c)
    if key:
        main_by_name.setdefault(key, []).append(c)
    for email in make_email_keys(c):
        main_by_email.setdefault(email, []).append(c)

# Categorize temp contacts
matched_by_name = []
matched_by_email = []
unmatched = []
blank = []

for c in temp_contacts:
    key = make_key(c)
    emails = make_email_keys(c)

    if not key and not emails:
        blank.append(c)
        continue

    if key and key in main_by_name:
        matched_by_name.append((c, main_by_name[key]))
        continue

    email_match = None
    for email in emails:
        if email in main_by_email:
            email_match = main_by_email[email]
            break

    if email_match:
        matched_by_email.append((c, email_match))
    else:
        unmatched.append(c)

print(f"\n{'='*60}")
print(f"MERGE ANALYSIS")
print(f"{'='*60}")
print(f"Main Contacts folder: {len(main_contacts)}")
print(f"Temp folder (iCloud): {len(temp_contacts)}")
print(f"")
print(f"Matched by name:      {len(matched_by_name)}")
print(f"Matched by email:     {len(matched_by_email)}")
print(f"Unmatched (new):      {len(unmatched)}")
print(f"Blank (no name/email):{len(blank)}")
print(f"Total categorized:    {len(matched_by_name)+len(matched_by_email)+len(unmatched)+len(blank)}")

# Analyze what fields the temp contacts have that main doesn't
print(f"\n{'='*60}")
print(f"FIELD ANALYSIS - What Temp contacts add")
print(f"{'='*60}")

fields_to_check = ['personalNotes', 'companyName', 'jobTitle', 'birthday',
                    'homeAddress', 'businessAddress', 'homePhones', 'businessPhones',
                    'nickName', 'categories']

for field in fields_to_check:
    temp_has = sum(1 for c in temp_contacts if c.get(field) and
                   (isinstance(c[field], str) and c[field].strip() or
                    isinstance(c[field], list) and len(c[field]) > 0 or
                    isinstance(c[field], dict) and any(v for v in c[field].values())))
    main_has = sum(1 for c in main_contacts if c.get(field) and
                   (isinstance(c[field], str) and c[field].strip() or
                    isinstance(c[field], list) and len(c[field]) > 0 or
                    isinstance(c[field], dict) and any(v for v in c[field].values())))
    print(f"  {field:25s}: Temp={temp_has:5d}  Main={main_has:5d}")

# For matched contacts, how many have notes in temp but not in main?
notes_to_merge = 0
for temp_c, main_matches in matched_by_name + matched_by_email:
    temp_notes = (temp_c.get('personalNotes') or '').strip()
    if temp_notes:
        main_notes = (main_matches[0].get('personalNotes') or '').strip()
        if not main_notes:
            notes_to_merge += 1

print(f"\n  Matched contacts where Temp has notes but Main doesn't: {notes_to_merge}")

# Sample unmatched
print(f"\n{'='*60}")
print(f"SAMPLE UNMATCHED (first 30 - these would be ADDED to main)")
print(f"{'='*60}")
for c in unmatched[:30]:
    name = c.get('displayName', '(no name)')
    emails = ', '.join(e.get('address','') for e in c.get('emailAddresses',[]))
    company = c.get('companyName', '')
    detail = emails or company or ''
    print(f"  {name}" + (f" - {detail}" if detail else ""))
if len(unmatched) > 30:
    print(f"  ... and {len(unmatched)-30} more")

# Sample blank
if blank:
    print(f"\n{'='*60}")
    print(f"BLANK CONTACTS ({len(blank)} - no displayName or email)")
    print(f"{'='*60}")
    for c in blank[:10]:
        # Show whatever fields they have
        non_empty = {k: v for k, v in c.items()
                     if v and k not in ('id', 'parentFolderId', '@odata.etag', 'changeKey',
                                        'createdDateTime', 'lastModifiedDateTime', 'categories',
                                        'flag', 'emailAddresses', 'homePhones', 'businessPhones',
                                        'imAddresses')
                     and not k.startswith('@')}
        print(f"  Fields: {list(non_empty.keys())}")
