"""
System Sync Router
API endpoints for syncing data between vTiger, e-conomic and Hub

SYNC ARCHITECTURE - Field Ownership:
=====================================

E-CONOMIC owns and syncs:
- economic_customer_number (primary key from e-conomic)
- address, city, postal_code, country (physical address)
- email_domain, website (contact information)
- cvr_number (used for matching only, not overwritten if already set)

vTIGER owns and syncs:
- vtiger_id (primary key from vTiger)
- vtiger_account_no
- Contact records and contact-company relationships

HUB owns (manual or first-sync only):
- name (can be synced initially but not overwritten)
- cvr_number (used for matching, set once)
- Tags, notes, custom fields

SYNC RULES:
===========
1. NEVER overwrite source ID if already set (vtiger_id, economic_customer_number)
2. Matching is source-specific (e-conomic: strict economic_customer_number only)
3. Re-sync is idempotent - can run multiple times safely
4. Contact relationships are REPLACED on sync (not added)
5. Each sync only updates fields it owns
"""

import logging
from fastapi import APIRouter, Depends, HTTPException, Body
from typing import Dict, Any
from app.core.database import execute_query
from app.core.auth_dependencies import require_any_permission
from app.services.vtiger_service import get_vtiger_service
import aiohttp
import re

logger = logging.getLogger(__name__)

router = APIRouter()
sync_admin_access = require_any_permission("users.manage", "system.admin")


def normalize_name(name: str) -> str:
    """Normalize company name for matching"""
    if not name:
        return ""
    # Remove common suffixes and punctuation
    name = re.sub(r'\b(A/S|ApS|I/S|IVS|v/)\b', '', name, flags=re.IGNORECASE)
    name = re.sub(r'[^\w\s]', '', name)  # Remove punctuation
    return name.lower().strip()


def _normalize_sync_value(value: Any) -> str:
    """Normalize values so dry-run change detection is stable across None/empty/whitespace."""
    if value is None:
        return ""
    return str(value).strip()


def _build_customer_change_set(current_values: Dict[str, Any], new_values: Dict[str, Any]) -> Dict[str, Dict[str, str]]:
    """Return only fields that would actually change on update."""
    changes: Dict[str, Dict[str, str]] = {}
    for field, new_value in new_values.items():
        current_value = current_values.get(field)
        if _normalize_sync_value(current_value) != _normalize_sync_value(new_value):
            changes[field] = {
                "from": _normalize_sync_value(current_value),
                "to": _normalize_sync_value(new_value),
            }
    return changes


async def _economic_sync_apply_or_preview(apply_changes: bool) -> Dict[str, Any]:
    """
    Build economic sync plan and optionally apply changes.

    If apply_changes=False the function does a pure dry-run and returns a detailed plan.
    If apply_changes=True it performs the same plan as DB writes.
    """
    from app.services.economic_service import EconomicService

    economic = EconomicService()

    # Preflight check so UI gets a clear reason instead of a silent zero-result dry-run.
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(
                f"{economic.api_url}/self",
                headers=economic._get_headers(),
            ) as preflight_response:
                if preflight_response.status != 200:
                    raw = await preflight_response.text()
                    logger.error("❌ e-conomic preflight failed: %s - %s", preflight_response.status, raw)
                    detail = f"e-conomic forbindelse fejlede ({preflight_response.status})"
                    try:
                        payload = await preflight_response.json(content_type=None)
                        message = payload.get("message") if isinstance(payload, dict) else None
                        code = payload.get("errorCode") if isinstance(payload, dict) else None
                        if code == "AgreementDeregistered":
                            detail = (
                                "e-conomic aftalen er afregistreret (AgreementDeregistered). "
                                "Opret nyt grant token i e-conomic, opdater ECONOMIC_AGREEMENT_GRANT_TOKEN i .env "
                                "og genstart API containeren."
                            )
                        elif code == "InvalidGrantToken":
                            detail = (
                                "e-conomic grant token er ugyldigt (InvalidGrantToken). "
                                "Opdater ECONOMIC_AGREEMENT_GRANT_TOKEN i .env og genstart API containeren."
                            )
                        elif message and code:
                            detail = f"e-conomic forbindelse fejlede: {message} ({code})"
                        elif message:
                            detail = f"e-conomic forbindelse fejlede: {message}"
                    except Exception:
                        pass
                    raise HTTPException(status_code=502, detail=detail)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except HTTPException:
        raise
    except Exception as e:
        logger.error("❌ e-conomic preflight exception: %s", e)
        raise HTTPException(status_code=502, detail="Kunne ikke kontakte e-conomic API")

    # Get all customers from e-conomic (max 1000 per page)
    all_customers = []
    page = 0
    while True:
        customers = await economic.get_customers(page=page, page_size=1000, strict=True)
        if not customers:
            break
        all_customers.extend(customers)
        page += 1
        if len(customers) < 1000:
            break

    economic_customers = all_customers
    logger.info("📥 Fetched %s customers from e-conomic (%s pages)", len(economic_customers), page)

    created_count = 0
    updated_count = 0
    skipped_count = 0
    conflict_count = 0

    would_create: list[Dict[str, Any]] = []
    would_update: list[Dict[str, Any]] = []
    conflicts: list[Dict[str, Any]] = []
    skipped: list[Dict[str, Any]] = []

    for eco_customer in economic_customers:
        customer_number_raw = eco_customer.get('customerNumber')
        customer_number = str(customer_number_raw).strip() if customer_number_raw is not None else None
        cvr = eco_customer.get('corporateIdentificationNumber')
        name = eco_customer.get('name', '').strip()
        address = eco_customer.get('address', '')
        city = eco_customer.get('city', '')
        zip_code = eco_customer.get('zip', '')
        country = eco_customer.get('country', 'DK')
        email = eco_customer.get('email', '')
        website = eco_customer.get('website', '')

        if not customer_number or not name:
            skipped_count += 1
            skipped.append({
                "economic_customer_number": customer_number,
                "name": name or "(mangler navn)",
                "reason": "Manglende kundenummer eller navn"
            })
            continue

        # Clean CVR
        if cvr:
            cvr = re.sub(r'\D', '', str(cvr))[:8]
            if len(cvr) != 8:
                cvr = None

        # Clean country code (max 2 chars for ISO codes)
        if country:
            country = str(country).strip().upper()[:2]
            if not country:
                country = 'DK'
        else:
            country = 'DK'

        email_domain = email.split('@')[-1] if '@' in email else None

        # Strict matching: ONLY match by economic_customer_number
        existing = execute_query(
            """
            SELECT id, name, email_domain, address, city, postal_code, country, website
            FROM customers
            WHERE economic_customer_number = %s
            ORDER BY id
            """,
            (customer_number,)
        )

        if len(existing) > 1:
            conflict_count += 1
            skipped_count += 1
            duplicate_ids = [row['id'] for row in existing]
            conflicts.append({
                "economic_customer_number": customer_number,
                "name": name,
                "duplicate_customer_ids": duplicate_ids,
                "reason": "Flere lokale kunder har samme e-conomic kundenummer"
            })
            logger.error(
                "❌ Konflikt: e-conomic #%s matcher %s lokale kunder (ids: %s) - springer over",
                customer_number,
                len(existing),
                ", ".join(str(i) for i in duplicate_ids)
            )
            continue

        if existing:
            target_customer_id = existing[0]['id']
            current_values = {
                "email_domain": existing[0].get("email_domain"),
                "address": existing[0].get("address"),
                "city": existing[0].get("city"),
                "postal_code": existing[0].get("postal_code"),
                "country": existing[0].get("country"),
                "website": existing[0].get("website"),
            }
            proposed_values = {
                "email_domain": email_domain,
                "address": address,
                "city": city,
                "postal_code": zip_code,
                "country": country,
                "website": website,
            }
            changes = _build_customer_change_set(current_values, proposed_values)

            would_update.append({
                "customer_id": target_customer_id,
                "customer_name": existing[0].get('name'),
                "economic_customer_number": customer_number,
                "current_values": current_values,
                "new_values": proposed_values,
                "changes": changes,
                "has_changes": len(changes) > 0,
            })

            if apply_changes:
                update_query = """
                    UPDATE customers SET
                        economic_customer_number = %s,
                        email_domain = %s,
                        address = %s,
                        city = %s,
                        postal_code = %s,
                        country = %s,
                        website = %s,
                        last_synced_at = NOW()
                    WHERE id = %s
                """
                execute_query(update_query, (
                    customer_number, email_domain, address, city, zip_code, country, website, target_customer_id
                ))
                logger.info(
                    "✏️  Opdateret lokal kunde id=%s: %s (e-conomic #%s, CVR: %s)",
                    target_customer_id,
                    name,
                    customer_number,
                    cvr or 'ingen'
                )

            updated_count += 1
        else:
            would_create.append({
                "name": name,
                "economic_customer_number": customer_number,
                "cvr_number": cvr,
                "email_domain": email_domain,
                "address": address,
                "city": city,
                "postal_code": zip_code,
                "country": country,
                "website": website,
            })

            if apply_changes:
                insert_query = """
                    INSERT INTO customers
                    (name, economic_customer_number, cvr_number, email_domain,
                     address, city, postal_code, country, website, last_synced_at)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, NOW())
                    RETURNING id
                """
                result = execute_query(insert_query, (
                    name, customer_number, cvr, email_domain, address, city, zip_code, country, website
                ))
                if result:
                    logger.info(
                        "✨ Oprettet lokal kunde id=%s: %s (e-conomic #%s, CVR: %s)",
                        result[0]['id'],
                        name,
                        customer_number,
                        cvr or 'ingen'
                    )
                else:
                    skipped_count += 1
                    skipped.append({
                        "economic_customer_number": customer_number,
                        "name": name,
                        "reason": "Insert RETURNING gav tomt resultat"
                    })
                    continue

            created_count += 1

    logger.info(
        "✅ e-conomic %s fuldført: %s oprettet, %s opdateret, %s konflikter, %s sprunget over af %s totalt",
        "sync" if apply_changes else "dry-run",
        created_count,
        updated_count,
        conflict_count,
        skipped_count,
        len(economic_customers)
    )

    return {
        "status": "success",
        "mode": "apply" if apply_changes else "dry_run",
        "created": created_count,
        "updated": updated_count,
        "conflicts": conflict_count,
        "skipped": skipped_count,
        "total_processed": len(economic_customers),
        "contacts": {
            "supported": False,
            "message": "Kontakt-sync fra e-conomic er ikke implementeret endnu i denne pipeline. Dry-run dækker firmaer."
        },
        "preview": {
            "would_create": would_create[:25],
            "would_update": would_update[:25],
            "conflicts": conflicts[:25],
            "skipped": skipped[:25],
            "truncated": {
                "would_create_total": len(would_create),
                "would_update_total": len(would_update),
                "conflicts_total": len(conflicts),
                "skipped_total": len(skipped),
                "limit_per_list": 25
            }
        }
    }


@router.post("/sync/vtiger")
async def sync_from_vtiger(current_user: dict = Depends(sync_admin_access)) -> Dict[str, Any]:
    """
    Link vTiger accounts to existing Hub customers
    Matches by CVR or normalized name, updates vtiger_id
    """
    try:
        logger.info("🔄 Starting vTiger link sync...")
        
        vtiger = get_vtiger_service()
        
        # Fetch ALL accounts - vTiger query API doesn't support LIMIT/OFFSET
        # Instead, use recursive queries based on ID to get all records
        all_accounts = []
        last_id = None
        batch_size = 100  # vTiger typically returns ~100 records per query
        
        while True:
            # Build query with ID filter to paginate
            if last_id is None:
                query = f"SELECT id, accountname, email1, siccode, cf_accounts_cvr, website, bill_city, bill_code, bill_country FROM Accounts ORDER BY id LIMIT {batch_size};"
            else:
                # Get records with ID > last_id to continue pagination
                query = f"SELECT id, accountname, email1, siccode, cf_accounts_cvr, website, bill_city, bill_code, bill_country FROM Accounts WHERE id > '{last_id}' ORDER BY id LIMIT {batch_size};"
            
            batch = await vtiger.query(query)
            
            if not batch or len(batch) == 0:
                break
                
            all_accounts.extend(batch)
            last_id = batch[-1].get('id')  # Track last ID for next query
            logger.info(f"📥 Fetched batch: {len(batch)} accounts (last ID: {last_id}, total: {len(all_accounts)})")
            
            # If we got less than batch_size, we've reached the end
            if len(batch) < batch_size:
                break
        
        logger.info(f"📥 Fetched total of {len(all_accounts)} accounts from vTiger")
        accounts = all_accounts
        
        linked_count = 0
        updated_count = 0
        not_found_count = 0
        
        for account in accounts:
            vtiger_id = account.get('id')
            name = account.get('accountname', '').strip()
            cvr = account.get('cf_accounts_cvr') or account.get('siccode')
            
            if not name or not vtiger_id:
                not_found_count += 1
                continue
            
            # Clean CVR number
            if cvr:
                cvr = re.sub(r'\D', '', str(cvr))[:8]  # Remove non-digits, max 8 chars
                if len(cvr) != 8:
                    cvr = None
            
            # Find existing Hub customer by CVR or normalized name
            existing = None
            match_method = None
            
            if cvr:
                existing = execute_query(
                    "SELECT id, name, vtiger_id FROM customers WHERE cvr_number = %s",
                    (cvr,)
                )
                if existing:
                    match_method = "CVR"
            
            if not existing:
                # Match by normalized name
                normalized = normalize_name(name)
                all_customers = execute_query("SELECT id, name, vtiger_id FROM customers")
                for customer in all_customers:
                    if normalize_name(customer['name']) == normalized:
                        existing = [customer]
                        match_method = "navn"
                        break
            
            if existing:
                # Link vTiger ID to existing customer
                current_vtiger_id = existing[0].get('vtiger_id')
                
                # Check if this vtiger_id is already assigned to another customer
                vtiger_owner = execute_query(
                    "SELECT id, name FROM customers WHERE vtiger_id = %s",
                    (vtiger_id,)
                )
                
                if vtiger_owner and vtiger_owner[0]['id'] != existing[0]['id']:
                    # vTiger ID already belongs to another customer - skip
                    logger.warning(f"⚠️  vTiger #{vtiger_id} allerede tilknyttet '{vtiger_owner[0]['name']}' - springer over '{existing[0]['name']}'")
                    not_found_count += 1
                    continue
                
                if current_vtiger_id is None:
                    # Only set vtiger_id if it's currently NULL
                    execute_query(
                        "UPDATE customers SET vtiger_id = %s, last_synced_at = NOW() WHERE id = %s",
                        (vtiger_id, existing[0]['id'])
                    )
                    linked_count += 1
                    logger.info(f"🔗 Linket: {existing[0]['name']} → vTiger #{vtiger_id} (match: {match_method}, CVR: {cvr or 'ingen'})")
                elif current_vtiger_id != vtiger_id:
                    # SKIP if different vTiger ID - do NOT overwrite existing vtiger_id
                    logger.warning(f"⚠️  Springer over: {existing[0]['name']} har allerede vTiger #{current_vtiger_id}, vil ikke overskrive med #{vtiger_id}")
                    not_found_count += 1
                    continue
                else:
                    # Already linked, just update timestamp
                    execute_query("UPDATE customers SET last_synced_at = NOW() WHERE id = %s", (existing[0]['id'],))
            else:
                not_found_count += 1
                logger.debug(f"⏭️  Ikke fundet i Hub: '{name}' (CVR: {cvr or 'ingen'}, normalized: '{normalize_name(name)}')")
        
        logger.info(f"✅ vTiger link sync fuldført: {linked_count} nye linket, {updated_count} opdateret, {not_found_count} ikke fundet af {len(accounts)} totalt")
        
        return {
            "status": "success",
            "linked": linked_count,
            "updated": updated_count,
            "not_found": not_found_count,
            "total_processed": len(accounts)
        }
        
    except Exception as e:
        logger.error(f"❌ vTiger sync error: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/sync/vtiger-contacts")
async def sync_vtiger_contacts(current_user: dict = Depends(sync_admin_access)) -> Dict[str, Any]:
    """
    SIMPEL TILGANG - Sync contacts from vTiger and link to customers
    Step 1: Fetch all contacts from vTiger
    Step 2: Create/update contact in Hub
    Step 3: Link to customer IF account_id matches customer.vtiger_id
    """
    try:
        logger.info("🔄 Starting vTiger contacts sync (SIMPEL VERSION)...")
        
        vtiger = get_vtiger_service()
        
        # ===== STEP 1: FETCH ALL CONTACTS =====
        logger.info("📥 STEP 1: Fetching contacts from vTiger...")
        all_contacts = []
        last_id = None
        batch_size = 100
        
        while True:
            if last_id is None:
                query = f"SELECT id, firstname, lastname, email, phone, mobile, title, department, account_id FROM Contacts ORDER BY id LIMIT {batch_size};"
            else:
                query = f"SELECT id, firstname, lastname, email, phone, mobile, title, department, account_id FROM Contacts WHERE id > '{last_id}' ORDER BY id LIMIT {batch_size};"
            
            batch = await vtiger.query(query)
            if not batch or len(batch) == 0:
                break
                
            all_contacts.extend(batch)
            last_id = batch[-1].get('id')
            logger.info(f"  → Batch: {len(batch)} contacts (ID: {last_id}, total: {len(all_contacts)})")
            
            if len(batch) < batch_size:
                break
        
        logger.info(f"✅ STEP 1 DONE: {len(all_contacts)} contacts fetched")
        
        # ===== STEP 2 & 3: PROCESS EACH CONTACT =====
        logger.info("🔄 STEP 2 & 3: Creating/updating contacts and linking to customers...")
        
        created_count = 0
        updated_count = 0
        skipped_count = 0
        linked_count = 0
        customers_created_count = 0
        debug_count = 0
        
        for i, contact in enumerate(all_contacts, 1):
            vtiger_id = contact.get('id')
            first_name = (contact.get('firstname') or '').strip()
            last_name = (contact.get('lastname') or '').strip()
            email = contact.get('email')
            account_id = contact.get('account_id')  # This is the vTiger Account ID
            
            # Show progress every 100 contacts
            if i % 100 == 0:
                logger.info(f"  → Progress: {i}/{len(all_contacts)} contacts processed...")
            
            # Must have name
            if not first_name and not last_name:
                skipped_count += 1
                continue
            
            # --- STEP 2A: Check if contact exists ---
            existing = execute_query(
                "SELECT id FROM contacts WHERE vtiger_id = %s",
                (vtiger_id,)
            ) if vtiger_id else None
            
            # --- STEP 2B: Create or update contact ---
            contact_id = None
            
            if existing:
                # UPDATE existing
                execute_query("""
                    UPDATE contacts 
                    SET first_name = %s, last_name = %s, email = %s, 
                        phone = %s, mobile = %s, title = %s, department = %s, 
                        updated_at = NOW()
                    WHERE id = %s
                """, (
                    first_name, last_name, email,
                    contact.get('phone'), contact.get('mobile'),
                    contact.get('title'), contact.get('department'),
                    existing[0]['id']
                ))
                contact_id = existing[0]['id']
                updated_count += 1
            else:
                # CREATE new
                result = execute_query("""
                    INSERT INTO contacts 
                    (first_name, last_name, email, phone, mobile, title, department, vtiger_id)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
                    RETURNING id
                """, (
                    first_name, last_name, email,
                    contact.get('phone'), contact.get('mobile'),
                    contact.get('title'), contact.get('department'),
                    vtiger_id
                ))
                
                if result and len(result) > 0:
                    contact_id = result[0]['id']
                    created_count += 1
                else:
                    skipped_count += 1
                    continue
            
            # --- DEBUG LOGGING FOR FIRST 20 CONTACTS ---
            if debug_count < 20:
                logger.warning(f"🔍 DEBUG {debug_count+1}: Contact '{first_name} {last_name}' (vtiger_id={vtiger_id}, contact_id={contact_id}, account_id={account_id})")
                debug_count += 1
            
            # --- STEP 3: LINK TO CUSTOMER ---
            if not account_id:
                # No account_id means contact is not linked to any account in vTiger
                if debug_count <= 20:
                    logger.warning(f"  ↳ No account_id - cannot link")
                continue
            
            # Find Hub customer with matching vtiger_id
            customer_result = execute_query(
                "SELECT id, name FROM customers WHERE vtiger_id = %s",
                (account_id,)
            )
            
            if not customer_result or len(customer_result) == 0:
                # FALLBACK: Create customer from vTiger account if not found
                try:
                    account_query = f"SELECT id, accountname, email1, siccode, cf_accounts_cvr, website, bill_city, bill_code, bill_country FROM Accounts WHERE id = '{account_id}';"
                    account_data = await vtiger.query(account_query)
                    
                    if account_data and len(account_data) > 0:
                        account = account_data[0]
                        account_name = account.get('accountname', '').strip()
                        cvr = account.get('cf_accounts_cvr') or account.get('siccode')
                        
                        if cvr:
                            cvr = re.sub(r'\D', '', str(cvr))[:8]
                            if len(cvr) != 8:
                                cvr = None
                        
                        # Check if customer already exists by CVR (to avoid duplicates)
                        if cvr:
                            existing_by_cvr = execute_query(
                                "SELECT id, name FROM customers WHERE cvr_number = %s",
                                (cvr,)
                            )
                            if existing_by_cvr:
                                # Found by CVR - update vtiger_id and use this customer
                                execute_query(
                                    "UPDATE customers SET vtiger_id = %s, last_synced_at = NOW() WHERE id = %s",
                                    (account_id, existing_by_cvr[0]['id'])
                                )
                                customer_id = existing_by_cvr[0]['id']
                                customer_name = existing_by_cvr[0]['name']
                                logger.info(f"✅ Matched by CVR and updated vtiger_id: {customer_name} → {account_id}")
                            else:
                                # Create new customer from vTiger
                                country = (account.get('bill_country') or 'DK').strip().upper()[:2]
                                new_customer = execute_query("""
                                    INSERT INTO customers 
                                    (name, cvr_number, email, website, city, postal_code, country, vtiger_id, last_synced_at)
                                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, NOW())
                                    RETURNING id, name
                                """, (
                                    account_name,
                                    cvr,
                                    account.get('email1'),
                                    account.get('website'),
                                    account.get('bill_city'),
                                    account.get('bill_code'),
                                    country,
                                    account_id
                                ))
                                
                                if new_customer:
                                    customer_id = new_customer[0]['id']
                                    customer_name = new_customer[0]['name']
                                    customers_created_count += 1
                                    logger.info(f"✨ Created customer from vTiger: {customer_name} (vtiger_id={account_id})")
                                else:
                                    if debug_count <= 20:
                                        logger.warning(f"  ↳ Failed to create customer from account_id={account_id}")
                                    continue
                        else:
                            # No CVR - create customer anyway (might be foreign company)
                            country = (account.get('bill_country') or 'DK').strip().upper()[:2]
                            new_customer = execute_query("""
                                INSERT INTO customers 
                                (name, email, website, city, postal_code, country, vtiger_id, last_synced_at)
                                VALUES (%s, %s, %s, %s, %s, %s, %s, NOW())
                                RETURNING id, name
                            """, (
                                account_name,
                                account.get('email1'),
                                account.get('website'),
                                account.get('bill_city'),
                                account.get('bill_code'),
                                country,
                                account_id
                            ))
                            
                            if new_customer:
                                customer_id = new_customer[0]['id']
                                customer_name = new_customer[0]['name']
                                customers_created_count += 1
                                logger.info(f"✨ Created customer from vTiger (no CVR): {customer_name} (vtiger_id={account_id})")
                            else:
                                if debug_count <= 20:
                                    logger.warning(f"  ↳ Failed to create customer from account_id={account_id}")
                                continue
                    else:
                        if debug_count <= 20:
                            logger.warning(f"  ↳ Account not found in vTiger: {account_id}")
                        continue
                        
                except Exception as e:
                    logger.error(f"❌ Failed to fetch/create customer from vTiger account {account_id}: {e}")
                    continue
            else:
                customer_id = customer_result[0]['id']
                customer_name = customer_result[0]['name']
            
            # DELETE existing links for this contact (we replace, not append)
            # This ensures re-sync updates links to match current vTiger state
            execute_query(
                "DELETE FROM contact_companies WHERE contact_id = %s",
                (contact_id,)
            )
            
            # CREATE new link from vTiger
            execute_query(
                "INSERT INTO contact_companies (contact_id, customer_id, is_primary) VALUES (%s, %s, false)",
                (contact_id, customer_id)
            )
            linked_count += 1
            
            if linked_count <= 10:  # Log first 10 successful links
                logger.info(f"🔗 LINKED: {first_name} {last_name} → {customer_name}")
        
        logger.info(f"✅ SYNC COMPLETE: created={created_count}, updated={updated_count}, linked={linked_count}, customers_created={customers_created_count}, skipped={skipped_count}, total={len(all_contacts)}")
        
        return {
            "status": "success",
            "created": created_count,
            "updated": updated_count,
            "linked": linked_count,
            "customers_created": customers_created_count,
            "skipped": skipped_count,
            "total_processed": len(all_contacts)
        }
        
    except Exception as e:
        logger.error(f"❌ vTiger contacts sync error: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/sync/economic")
async def sync_from_economic(current_user: dict = Depends(sync_admin_access)) -> Dict[str, Any]:
    """
    Sync customers from e-conomic (PRIMARY SOURCE)
    Creates/updates Hub customers with e-conomic data
    """
    try:
        logger.info("🔄 Starting e-conomic customer sync (PRIMARY SOURCE)...")
        result = await _economic_sync_apply_or_preview(apply_changes=True)
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ e-conomic sync error: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/sync/economic/dry-run")
@router.post("/sync/economic/dryrun")
@router.post("/sync/economic/preview")
async def sync_from_economic_dry_run(current_user: dict = Depends(sync_admin_access)) -> Dict[str, Any]:
    """
    Dry-run for e-conomic customer sync.
    No database writes are performed; returns a preview of intended actions.
    """
    try:
        logger.info("🧪 Starting e-conomic customer sync DRY-RUN preview...")
        result = await _economic_sync_apply_or_preview(apply_changes=False)
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ e-conomic dry-run sync error: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/sync/economic/apply-update")
async def apply_single_economic_update(
    payload: Dict[str, Any] = Body(...),
    current_user: dict = Depends(sync_admin_access)
) -> Dict[str, Any]:
    """
    Apply one selected dry-run customer update with optional field overrides.
    This lets admins adjust values on-the-fly from the preview UI.
    """
    customer_id = payload.get("customer_id")
    economic_customer_number = payload.get("economic_customer_number")
    new_values = payload.get("new_values") or {}
    overrides = payload.get("overrides") or {}

    try:
        customer_id = int(customer_id)
    except (TypeError, ValueError):
        raise HTTPException(status_code=400, detail="Ugyldigt customer_id")

    if not isinstance(new_values, dict):
        raise HTTPException(status_code=400, detail="new_values skal være et objekt")
    if not isinstance(overrides, dict):
        raise HTTPException(status_code=400, detail="overrides skal være et objekt")

    allowed_fields = {"email_domain", "address", "city", "postal_code", "country", "website"}
    invalid_override_fields = [field for field in overrides.keys() if field not in allowed_fields]
    if invalid_override_fields:
        raise HTTPException(
            status_code=400,
            detail=f"Ugyldige override felter: {', '.join(sorted(invalid_override_fields))}"
        )

    customer = execute_query(
        """
        SELECT id, name, economic_customer_number, email_domain, address, city, postal_code, country, website
        FROM customers
        WHERE id = %s
        """,
        (customer_id,)
    )

    if not customer:
        raise HTTPException(status_code=404, detail="Kunde ikke fundet")

    customer = customer[0]

    if economic_customer_number and str(customer.get("economic_customer_number") or "") != str(economic_customer_number):
        raise HTTPException(
            status_code=409,
            detail="Kundens e-conomic nummer matcher ikke preview-data. Kør dry-run igen."
        )

    final_values: Dict[str, Any] = {}
    for field in allowed_fields:
        if field in overrides:
            value = overrides.get(field)
        elif field in new_values:
            value = new_values.get(field)
        else:
            value = customer.get(field)

        normalized = _normalize_sync_value(value)
        if field == "country":
            normalized = (normalized.upper()[:2] or "DK")
        final_values[field] = normalized

    update_query = """
        UPDATE customers SET
            email_domain = %s,
            address = %s,
            city = %s,
            postal_code = %s,
            country = %s,
            website = %s,
            last_synced_at = NOW()
        WHERE id = %s
    """
    execute_query(
        update_query,
        (
            final_values["email_domain"],
            final_values["address"],
            final_values["city"],
            final_values["postal_code"],
            final_values["country"],
            final_values["website"],
            customer_id,
        )
    )

    applied_changes = _build_customer_change_set(
        {
            "email_domain": customer.get("email_domain"),
            "address": customer.get("address"),
            "city": customer.get("city"),
            "postal_code": customer.get("postal_code"),
            "country": customer.get("country"),
            "website": customer.get("website"),
        },
        final_values,
    )

    logger.info(
        "✅ Applied on-the-fly e-conomic update for customer id=%s (%s), changed_fields=%s",
        customer_id,
        customer.get("name"),
        ", ".join(sorted(applied_changes.keys())) or "none",
    )

    return {
        "status": "success",
        "customer_id": customer_id,
        "economic_customer_number": customer.get("economic_customer_number"),
        "applied_changes": applied_changes,
        "final_values": final_values,
    }


@router.post("/sync/cvr-to-economic")
async def sync_cvr_to_economic(current_user: dict = Depends(sync_admin_access)) -> Dict[str, Any]:
    """
    Find customers in Hub with CVR but without e-conomic customer number
    Search e-conomic for matching CVR and update Hub
    """
    try:
        logger.info("🔄 Starting CVR to e-conomic sync...")
        
        from app.services.economic_service import EconomicService
        economic = EconomicService()
        
        # Find customers with CVR but no economic_customer_number
        customers = execute_query("""
            SELECT id, name, cvr_number 
            FROM customers 
            WHERE cvr_number IS NOT NULL 
              AND cvr_number != '' 
              AND economic_customer_number IS NULL
            LIMIT 100
        """)
        
        logger.info(f"📥 Found {len(customers)} customers with CVR but no e-conomic number")
        
        found_count = 0
        linked_count = 0
        
        for customer in customers:
            cvr = customer['cvr_number']
            
            # Search e-conomic for this CVR
            eco_customer = await economic.search_customer_by_cvr(cvr)
            
            if eco_customer:
                customer_number = eco_customer.get('customerNumber')
                if customer_number:
                    # Update Hub customer
                    execute_query(
                        "UPDATE customers SET economic_customer_number = %s, last_synced_at = NOW() WHERE id = %s",
                        (customer_number, customer['id'])
                    )
                    found_count += 1
                    linked_count += 1
                    logger.info(f"✅ Fundet og linket: {customer['name']} (CVR: {cvr}) → e-conomic kunde #{customer_number}")
                else:
                    found_count += 1
                    logger.warning(f"⚠️ Fundet men mangler kundenummer: {customer['name']} (CVR: {cvr})")
        
        logger.info(f"✅ CVR søgning fuldført: {found_count} fundet, {linked_count} linket af {len(customers)} kontrolleret")
        
        return {
            "status": "not_implemented",
            "message": "Requires e-conomic API search by CVR functionality",
            "found": 0,
            "candidates": len(customers)
        }
        
    except Exception as e:
        logger.error(f"❌ CVR to e-conomic sync error: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/sync/diagnostics")
async def sync_diagnostics(current_user: dict = Depends(sync_admin_access)) -> Dict[str, Any]:
    """
    Diagnostics: Check contact linking coverage
    Shows why contacts aren't linking to customers
    """
    try:
        logger.info("🔍 Running sync diagnostics...")
        
        # Check Hub data
        hub_stats = execute_query("""
            SELECT 
                COUNT(*) as total_customers,
                COUNT(vtiger_id) as customers_with_vtiger
            FROM customers
        """)
        
        vtiger_ids_in_hub = execute_query(
            "SELECT vtiger_id FROM customers WHERE vtiger_id IS NOT NULL"
        )
        hub_vtiger_set = set(row['vtiger_id'] for row in vtiger_ids_in_hub)
        
        contact_stats = execute_query("""
            SELECT 
                COUNT(*) as total_contacts,
                COUNT(vtiger_id) as contacts_with_vtiger
            FROM contacts
        """)
        
        link_stats = execute_query("""
            SELECT COUNT(*) as total_links
            FROM contact_companies
        """)
        
        # Fetch sample contacts from vTiger
        vtiger = get_vtiger_service()
        query = "SELECT id, firstname, lastname, account_id FROM Contacts ORDER BY id LIMIT 200;"
        contacts = await vtiger.query(query)
        
        # Analyze
        with_account = [c for c in contacts if c.get('account_id')]
        account_ids = set(c['account_id'] for c in with_account)
        
        matched_accounts = [aid for aid in account_ids if aid in hub_vtiger_set]
        unmatched_accounts = [aid for aid in account_ids if aid not in hub_vtiger_set]
        
        result = {
            "hub": {
                "total_customers": hub_stats[0]['total_customers'],
                "customers_with_vtiger_id": hub_stats[0]['customers_with_vtiger'],
                "unique_vtiger_ids": len(hub_vtiger_set),
                "total_contacts": contact_stats[0]['total_contacts'],
                "contacts_with_vtiger_id": contact_stats[0]['contacts_with_vtiger'],
                "total_links": link_stats[0]['total_links']
            },
            "vtiger_sample": {
                "sample_size": len(contacts),
                "contacts_with_account_id": len(with_account),
                "unique_account_ids": len(account_ids),
                "account_ids_found_in_hub": len(matched_accounts),
                "account_ids_missing_in_hub": len(unmatched_accounts),
                "match_rate_percent": round((len(matched_accounts) / len(account_ids) * 100), 1) if account_ids else 0
            },
            "examples": {
                "matched_account_ids": matched_accounts[:5],
                "unmatched_account_ids": unmatched_accounts[:10]
            },
            "recommendation": ""
        }
        
        # Add recommendation
        match_rate = result['vtiger_sample']['match_rate_percent']
        if match_rate < 50:
            result['recommendation'] = f"⚠️ LOW MATCH RATE ({match_rate}%) - Kør først /sync/vtiger for at linke flere accounts"
        elif match_rate < 90:
            result['recommendation'] = f"⚡ MEDIUM MATCH RATE ({match_rate}%) - Nogen accounts mangler stadig at blive linket"
        else:
            result['recommendation'] = f"✅ HIGH MATCH RATE ({match_rate}%) - De fleste contacts kan linkes"
        
        logger.info(f"✅ Diagnostics complete: {result['recommendation']}")
        
        return result
        
    except Exception as e:
        logger.error(f"❌ Diagnostics error: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))
