#!/usr/bin/env python3
"""
Bardach Contact Delete: Delete remaining Temp contacts.
Treats 404 as success (contact already gone).
Merges were already completed successfully (70/70).
"""

import json
import subprocess
import time
import sys
from datetime import datetime

sys.stdout.reconfigure(line_buffering=True)
sys.stderr.reconfigure(line_buffering=True)

TENANT_ID = "dd4a82e8-85a3-44ac-8800-07945ab4d95f"
CLIENT_ID = "fabb3421-8b34-484b-bc17-e46de9703418"
CLIENT_SECRET = "~QJ8Q~NyQSs4OcGqHZyPrA2CVnq9KBfKiimntbMO"
SCOPE = "https://graph.microsoft.com/.default"
USER = "barbara@bardach.net"
BASE_URL = f"https://graph.microsoft.com/v1.0/users/{USER}/contacts"
DATA_FILE = "D:/ClaudeTools/temp/bardach_temp_vs_main.json"
THROTTLE_DELAY = 0.25  # slightly faster since deletes are simple


def get_token():
    url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token"
    cmd = [
        "curl", "-s", "-X", "POST", url,
        "-H", "Content-Type: application/x-www-form-urlencoded",
        "-d", f"client_id={CLIENT_ID}&scope={SCOPE}&client_secret={CLIENT_SECRET}&grant_type=client_credentials"
    ]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
    data = json.loads(result.stdout)
    if "access_token" not in data:
        print(f"[ERROR] Token failed: {data}")
        sys.exit(1)
    print(f"[OK] Token acquired at {datetime.now().strftime('%H:%M:%S')}")
    return data["access_token"]


def api_delete(token, contact_id):
    """DELETE a contact. Returns status code as string."""
    url = f"{BASE_URL}/{contact_id}"
    cmd = [
        "curl", "-s", "-o", "/dev/null", "-w", "%{http_code}",
        "-X", "DELETE", url,
        "-H", f"Authorization: Bearer {token}"
    ]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
    return result.stdout.strip()


def api_get(token, url):
    cmd = [
        "curl", "-s", "-X", "GET", url,
        "-H", f"Authorization: Bearer {token}",
        "-H", "Content-Type: application/json"
    ]
    result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
    return json.loads(result.stdout)


# Load data
with open(DATA_FILE, "r", encoding="utf-8") as f:
    data = json.load(f)

matches = data["matches_with_extras"]
exact_matches = data.get("exact_matches", [])

all_temp_ids = []
for m in matches:
    all_temp_ids.append((m["temp_id"], m["displayName"]))
for m in exact_matches:
    all_temp_ids.append((m["temp_id"], m["displayName"]))

print(f"[INFO] Total Temp contacts to delete: {len(all_temp_ids)}")

token = get_token()
deleted_ok = 0
already_gone = 0
real_errors = 0
error_details = []

for i, (tid, name) in enumerate(all_temp_ids):
    if i > 0 and i % 500 == 0:
        token = get_token()
    if i > 0 and i % 200 == 0:
        print(f"  [INFO] Progress {i}/{len(all_temp_ids)}: {deleted_ok} deleted, {already_gone} already gone, {real_errors} errors")

    code = api_delete(token, tid)
    time.sleep(THROTTLE_DELAY)

    if code in ("204", "200"):
        deleted_ok += 1
    elif code == "404":
        already_gone += 1
    else:
        real_errors += 1
        if real_errors <= 10:
            print(f"  [ERROR] {name}: HTTP {code}")
        error_details.append({"name": name, "code": code, "temp_id": tid})

print(f"\n[OK] Delete complete:")
print(f"  Deleted now:    {deleted_ok}")
print(f"  Already gone:   {already_gone}")
print(f"  Errors:         {real_errors}")

# Verification
print("\n" + "=" * 70)
print("VERIFICATION")
print("=" * 70)

token = get_token()

# Check Temp folder
folders_url = f"https://graph.microsoft.com/v1.0/users/{USER}/contactFolders?$filter=displayName eq 'Temp'"
folders_resp = api_get(token, folders_url)
time.sleep(0.5)

if "value" in folders_resp and folders_resp["value"]:
    temp_folder_id = folders_resp["value"][0]["id"]
    count_url = f"https://graph.microsoft.com/v1.0/users/{USER}/contactFolders/{temp_folder_id}/contacts?$top=1&$select=displayName&$count=true"
    count_resp = api_get(token, count_url)
    remaining = len(count_resp.get("value", []))
    odata_count = count_resp.get("@odata.count", "N/A")
    has_more = "@odata.nextLink" in count_resp
    print(f"  Temp folder: odata.count={odata_count}, first page={remaining}, has_more={has_more}")
    if remaining > 0:
        print(f"  First remaining: {count_resp['value'][0].get('displayName', '?')}")
else:
    print(f"  Temp folder: not found or empty")

# Check Main contacts
main_count_url = f"{BASE_URL}?$top=1&$select=displayName&$count=true"
main_resp = api_get(token, main_count_url)
main_odata = main_resp.get("@odata.count", "N/A")
print(f"  Main contacts: odata.count={main_odata}")

# Save results
results = {
    "timestamp": datetime.now().isoformat(),
    "merge_step": "Completed previously: 70/70 patches successful",
    "deletes": {
        "total_attempted": len(all_temp_ids),
        "deleted_now": deleted_ok,
        "already_gone": already_gone,
        "errors": real_errors,
        "error_samples": error_details[:20],
    },
    "verification": {
        "temp_odata_count": str(odata_count) if 'odata_count' in dir() else "N/A",
        "main_odata_count": str(main_odata),
    }
}

with open("D:/ClaudeTools/temp/bardach_merge_results.json", "w", encoding="utf-8") as f:
    json.dump(results, f, indent=2, default=str)

print(f"\n[OK] Results saved to bardach_merge_results.json")
