"""
Phase 3 standalone: Import legacy invoice.notes as Comments on Sales Invoice.
Runs from any host that can reach BOTH:
  - Legacy MariaDB (legacy-db)
  - ERPNext API (erp.gigafibre.ca)

Usage:
  python import_invoice_notes.py
"""
import pymysql
import requests
import json
import time
import sys
import os
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1)

# ── Config ──
LEGACY_HOST = "legacy-db"
LEGACY_USER = "facturation"
LEGACY_PASS = "***LEGACY-DB-PW-REDACTED***"
LEGACY_DB   = "gestionclient"

ERP_URL  = "https://erp.gigafibre.ca"
ERP_KEY  = os.environ.get("ERP_API_KEY", "")
ERP_SECRET = os.environ.get("ERP_API_SECRET", "")

DRY_RUN = False

# ── Connect to legacy DB ──
print("Connecting to legacy MariaDB...")
legacy = pymysql.connect(
    host=LEGACY_HOST, user=LEGACY_USER, password=LEGACY_PASS,
    database=LEGACY_DB, cursorclass=pymysql.cursors.DictCursor
)

with legacy.cursor() as cur:
    cur.execute("""
        SELECT id, notes, account_id, FROM_UNIXTIME(date_orig) as date_created
        FROM invoice
        WHERE notes IS NOT NULL AND notes != '' AND TRIM(notes) != ''
        ORDER BY id
    """)
    noted_invoices = cur.fetchall()
legacy.close()
print(f"  Legacy invoices with notes: {len(noted_invoices)}")

# ── ERPNext session ──
sess = requests.Session()
if ERP_KEY and ERP_SECRET:
    sess.headers['Authorization'] = f'token {ERP_KEY}:{ERP_SECRET}'
else:
    # Try cookie auth — login
    erp_user = os.environ.get("ERP_USER", "Administrator")
    erp_pass = os.environ.get("ERP_PASS", "")
    if not erp_pass:
        print("ERROR: Set ERP_API_KEY+ERP_API_SECRET or ERP_USER+ERP_PASS env vars")
        sys.exit(1)
    r = sess.post(f"{ERP_URL}/api/method/login", data={"usr": erp_user, "pwd": erp_pass})
    if r.status_code != 200:
        print(f"Login failed: {r.status_code} {r.text[:200]}")
        sys.exit(1)
    print(f"  Logged in as {erp_user}")

# ── Get existing SINVs ──
print("  Fetching existing Sales Invoices...")
existing_sinv = set()
offset = 0
while True:
    r = sess.get(f"{ERP_URL}/api/resource/Sales Invoice", params={
        'fields': '["name"]', 'limit_page_length': 10000, 'limit_start': offset,
    })
    data = r.json().get('data', [])
    if not data:
        break
    for d in data:
        existing_sinv.add(d['name'])
    offset += len(data)
print(f"  Existing SINVs: {len(existing_sinv)}")

# ── Get existing Comments on invoices ──
print("  Fetching existing Comments on Sales Invoices...")
existing_comments = set()
offset = 0
while True:
    r = sess.get(f"{ERP_URL}/api/resource/Comment", params={
        'fields': '["reference_name"]',
        'filters': json.dumps({"reference_doctype": "Sales Invoice", "comment_type": "Comment"}),
        'limit_page_length': 10000, 'limit_start': offset,
    })
    data = r.json().get('data', [])
    if not data:
        break
    for d in data:
        existing_comments.add(d['reference_name'])
    offset += len(data)
print(f"  Existing Comments on invoices: {len(existing_comments)}")

# ── Build batch ──
batch = []
skipped = 0
for inv in noted_invoices:
    sinv_name = f"SINV-{inv['id']}"
    if sinv_name not in existing_sinv:
        skipped += 1
        continue
    if sinv_name in existing_comments:
        skipped += 1
        continue
    notes = inv['notes'].strip()
    if not notes:
        continue
    batch.append({
        'sinv': sinv_name,
        'content': notes,
        'creation': str(inv['date_created']) if inv['date_created'] else None,
    })

print(f"  Notes to import: {len(batch)}, skipped: {skipped}")

if DRY_RUN:
    print("  ** DRY RUN — no changes **")
    sys.exit(0)

# ── Import via API ──
t0 = time.time()
imported = 0
errors = 0
for i, note in enumerate(batch):
    payload = {
        'doctype': 'Comment',
        'comment_type': 'Comment',
        'reference_doctype': 'Sales Invoice',
        'reference_name': note['sinv'],
        'content': note['content'],
        'comment_by': 'Système legacy',
    }
    try:
        r = sess.post(f"{ERP_URL}/api/resource/Comment", json=payload)
        if r.status_code in (200, 201):
            imported += 1
        else:
            errors += 1
            if errors <= 5:
                print(f"    ERR {note['sinv']}: {r.status_code} {r.text[:100]}")
    except Exception as e:
        errors += 1
        if errors <= 5:
            print(f"    EXCEPTION {note['sinv']}: {e}")

    if (i + 1) % 500 == 0:
        elapsed = time.time() - t0
        rate = (i + 1) / elapsed
        print(f"  Progress: {i+1}/{len(batch)} ({rate:.0f}/s) imported={imported} errors={errors}")

elapsed = time.time() - t0
print(f"\n  DONE: {imported} imported, {errors} errors [{elapsed:.0f}s]")
