"""Search for deleted contacts using Graph search and extended properties."""
import subprocess, json, sys

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

def curl(method, url, token, body=None):
    cmd = ['curl', '-s', '-X', method, '-H', f'Authorization: Bearer {token}',
           '-H', 'Content-Type: application/json']
    if body:
        cmd.extend(['-d', json.dumps(body)])
    cmd.append(url)
    result = subprocess.run(cmd, capture_output=True, text=True)
    try:
        return json.loads(result.stdout) if result.stdout.strip() else {}
    except json.JSONDecodeError:
        return {'_raw': result.stdout[:500]}

# Get token
token_cmd = 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)
token = json.loads(token_cmd.stdout)['access_token']
print("[OK] Token acquired")

# Method 1: Use the search API (POST to /search/query at root level)
print("\n[METHOD 1] Graph Search API for contacts...")
search_body = {
    "requests": [{
        "entityTypes": ["contact"],
        "query": {"queryString": "*"},
        "from": 0,
        "size": 25
    }]
}
result = curl('POST', 'https://graph.microsoft.com/v1.0/search/query', token, search_body)
if 'error' in result:
    print(f"  {result['error'].get('code')}: {result['error'].get('message','')[:300]}")
elif result.get('value'):
    for resp in result['value']:
        for hc in resp.get('hitsContainers', []):
            total = hc.get('total', 0)
            more = hc.get('moreResultsAvailable', False)
            print(f"  Found {total} contacts (more available: {more})")
else:
    print(f"  Response: {json.dumps(result)[:300]}")

# Method 2: Enumerate Deleted Items looking for items with specific properties
# The Graph messages endpoint in deleted items will include contact items in some cases
# Let's get the deleted items folder children (subfolders) that might be contacts
print("\n[METHOD 2] Deleted Items sub-folders...")
result2 = curl('GET',
    f'https://graph.microsoft.com/v1.0/users/{USER}/mailFolders/deleteditems/childFolders?$top=50&$select=displayName,totalItemCount,childFolderCount',
    token)
if result2.get('value'):
    for f in result2['value']:
        print(f"  {f.get('displayName','?')}: {f.get('totalItemCount','?')} items")
elif 'error' in result2:
    print(f"  {result2['error'].get('code')}: {result2['error'].get('message','')[:200]}")

# Method 3: Use beta to get contacts with explicit parentFolderId
# Actually, let's just scan all items in deleted items to count contacts vs mail
print("\n[METHOD 3] Scanning Deleted Items for item types...")
# Get count of items in deleted items
folder_info = curl('GET',
    f'https://graph.microsoft.com/v1.0/users/{USER}/mailFolders/deleteditems?$select=totalItemCount,childFolderCount',
    token)
total = folder_info.get('totalItemCount', 0)
print(f"  Total items in Deleted Items: {total}")
print(f"  Child folders: {folder_info.get('childFolderCount', 0)}")

# Method 4: Use the beta endpoint to get items with extended properties
# This lets us see the PR_MESSAGE_CLASS to identify contacts
print("\n[METHOD 4] Sampling Deleted Items with message class property...")
sample_url = (
    f"https://graph.microsoft.com/beta/users/{USER}/mailFolders/deleteditems/messages"
    f"?$top=100&$select=subject,lastModifiedDateTime"
    f"&$expand=singleValueExtendedProperties($filter=id%20eq%20'String%200x001A')"
    f"&$orderby=lastModifiedDateTime%20desc"
)
result4 = curl('GET', sample_url, token)
if result4.get('value'):
    items = result4['value']
    contact_count = 0
    mail_count = 0
    other_count = 0
    contact_names = []

    for item in items:
        props = item.get('singleValueExtendedProperties', [])
        msg_class = None
        for p in props:
            if p.get('id') == 'String 0x001A':
                msg_class = p.get('value', '')
                break

        if msg_class and 'IPM.Contact' in msg_class:
            contact_count += 1
            contact_names.append(item.get('subject', '(no name)'))
        elif msg_class and 'IPM.Note' in msg_class:
            mail_count += 1
        else:
            other_count += 1

    print(f"  In sample of {len(items)} most recent deleted items:")
    print(f"    Contacts (IPM.Contact): {contact_count}")
    print(f"    Mail (IPM.Note): {mail_count}")
    print(f"    Other: {other_count}")

    if contact_names:
        print(f"\n  Deleted contact names found:")
        for name in contact_names[:20]:
            print(f"    - {name}")

    # If we found contacts, let's page through ALL deleted items to count total contacts
    if contact_count > 0:
        print(f"\n[STEP 5] Full scan of Deleted Items for contacts...")
        all_contacts = []
        all_contact_names = []
        scan_url = (
            f"https://graph.microsoft.com/beta/users/{USER}/mailFolders/deleteditems/messages"
            f"?$top=200&$select=subject,lastModifiedDateTime"
            f"&$expand=singleValueExtendedProperties($filter=id%20eq%20'String%200x001A')"
        )
        page = 0
        total_scanned = 0

        while scan_url and page < 200:  # Safety limit
            page += 1
            data = curl('GET', scan_url, token)
            if 'error' in data:
                print(f"  Error on page {page}: {data['error'].get('message','')[:200]}")
                break
            items = data.get('value', [])
            if not items:
                break
            total_scanned += len(items)

            for item in items:
                props = item.get('singleValueExtendedProperties', [])
                for p in props:
                    if p.get('id') == 'String 0x001A' and 'IPM.Contact' in p.get('value', ''):
                        all_contacts.append(item)
                        all_contact_names.append(item.get('subject', '(no name)'))
                        break

            scan_url = data.get('@odata.nextLink')
            if page % 10 == 0:
                print(f"  Page {page}: scanned {total_scanned}, found {len(all_contacts)} contacts...")

        print(f"\n[FINAL RESULT]")
        print(f"  Total items scanned: {total_scanned}")
        print(f"  Deleted contacts found: {len(all_contacts)}")

        if all_contact_names:
            # Save full list
            with open('D:/ClaudeTools/temp/bardach_deleted_contacts.json', 'w') as f:
                json.dump(all_contacts, f, indent=2)
            print(f"  Full list saved to D:/ClaudeTools/temp/bardach_deleted_contacts.json")
            print(f"\n  Sample of deleted contact names:")
            for name in all_contact_names[:30]:
                print(f"    - {name}")
            if len(all_contact_names) > 30:
                print(f"    ... and {len(all_contact_names) - 30} more")

elif 'error' in result4:
    print(f"  {result4['error'].get('code')}: {result4['error'].get('message','')[:300]}")
else:
    print(f"  Empty response")
