"""
Customers Router
API endpoints for customer management
Adapted from OmniSync for BMC Hub
"""

from fastapi import APIRouter, HTTPException, Query
from typing import List, Optional, Dict
from pydantic import BaseModel
import logging
import asyncio
import aiohttp
from urllib.parse import quote

from app.core.database import execute_query, execute_query_single, execute_update, execute_insert
from app.core.config import settings
from app.services.cvr_service import get_cvr_service
from app.services.customer_activity_logger import CustomerActivityLogger
from app.services.customer_consistency import CustomerConsistencyService

logger = logging.getLogger(__name__)

router = APIRouter()


def _ensure_customer_supplier_tag(customer_id: int) -> None:
    """Ensure linked customers are tagged as suppliers."""
    try:
        tag = execute_query_single(
            "SELECT id FROM tags WHERE LOWER(name) = 'supplier' AND type = 'category' LIMIT 1"
        )
        if tag and tag.get("id") is not None:
            tag_id = int(tag["id"])
        else:
            created = execute_query_single(
                """
                INSERT INTO tags (name, type, description, color, is_active)
                VALUES (%s, %s, %s, %s, %s)
                ON CONFLICT (name, type)
                DO UPDATE SET is_active = TRUE, updated_at = CURRENT_TIMESTAMP
                RETURNING id
                """,
                ("Supplier", "category", "Customer also acts as supplier", "#0f4c75", True),
            )
            tag_id = int(created["id"]) if created and created.get("id") is not None else None

        if not tag_id:
            return

        execute_query(
            """
            INSERT INTO entity_tags (entity_type, entity_id, tag_id)
            VALUES (%s, %s, %s)
            ON CONFLICT (entity_type, entity_id, tag_id) DO NOTHING
            """,
            ("customer", customer_id, tag_id),
        )
    except Exception as tag_error:
        logger.warning("⚠️ Could not ensure supplier tag for customer %s: %s", customer_id, tag_error)


# Pydantic Models
class CustomerBase(BaseModel):
    name: str
    cvr_number: Optional[str] = None
    email: Optional[str] = None
    email_domain: Optional[str] = None
    phone: Optional[str] = None
    address: Optional[str] = None
    city: Optional[str] = None
    postal_code: Optional[str] = None
    country: Optional[str] = "DK"
    website: Optional[str] = None
    wiki_slug: Optional[str] = None
    is_active: Optional[bool] = True
    invoice_email: Optional[str] = None
    mobile_phone: Optional[str] = None


class CustomerCreate(CustomerBase):
    pass


class CustomerUpdate(BaseModel):
    name: Optional[str] = None
    cvr_number: Optional[str] = None
    email: Optional[str] = None
    email_domain: Optional[str] = None
    phone: Optional[str] = None
    address: Optional[str] = None
    city: Optional[str] = None
    postal_code: Optional[str] = None
    country: Optional[str] = None
    website: Optional[str] = None
    wiki_slug: Optional[str] = None
    is_active: Optional[bool] = None
    invoice_email: Optional[str] = None
    mobile_phone: Optional[str] = None
    department: Optional[str] = None


class ContactCreate(BaseModel):
    first_name: str
    last_name: str
    email: Optional[str] = None
    phone: Optional[str] = None
    mobile: Optional[str] = None
    title: Optional[str] = None
    department: Optional[str] = None
    is_primary: Optional[bool] = False
    role: Optional[str] = None


@router.get("/customers")
async def list_customers(
    limit: int = Query(default=50, ge=1, le=1000),
    offset: int = Query(default=0, ge=0),
    search: Optional[str] = Query(default=None),
    source: Optional[str] = Query(default=None),  # 'vtiger', 'local', or None
    is_active: Optional[bool] = Query(default=None),
    vip: Optional[bool] = Query(default=None)
):
    """
    List customers with pagination and filtering
    
    Args:
        limit: Maximum number of customers to return
        offset: Number of customers to skip
        search: Search term for name, email, cvr, phone, city
        source: Filter by source ('vtiger' or 'local')
        is_active: Filter by active status
    """
    # Build query with primary contact info
    query = """
        SELECT 
            c.*,
            COUNT(DISTINCT cc.contact_id) as contact_count,
            CONCAT(pc.first_name, ' ', pc.last_name) as contact_name,
            pc.email as contact_email,
            COALESCE(pc.mobile, pc.phone) as contact_phone
        FROM customers c
        LEFT JOIN contact_companies cc ON cc.customer_id = c.id
        LEFT JOIN LATERAL (
            SELECT con.first_name, con.last_name, con.email, con.phone, con.mobile
            FROM contact_companies ccomp
            JOIN contacts con ON ccomp.contact_id = con.id
            WHERE ccomp.customer_id = c.id
            ORDER BY ccomp.is_primary DESC, con.id ASC
            LIMIT 1
        ) pc ON true
        WHERE 1=1
    """
    params = []
    
    # Add search filter
    if search:
        query += """ AND (
            c.name ILIKE %s OR
            c.email ILIKE %s OR
            c.cvr_number ILIKE %s OR
            c.phone ILIKE %s OR
            c.city ILIKE %s
        )"""
        search_term = f"%{search}%"
        params.extend([search_term] * 5)
    
    # Add source filter
    if source == 'vtiger':
        query += " AND c.vtiger_id IS NOT NULL"
    elif source == 'local':
        query += " AND c.vtiger_id IS NULL"
    
    # Add active filter
    if is_active is not None:
        query += " AND c.is_active = %s"
        params.append(is_active)

    # Add VIP filter (customer tagged with "vip")
    if vip is True:
        query += """
            AND EXISTS (
                SELECT 1
                FROM entity_tags et
                JOIN tags t ON t.id = et.tag_id
                WHERE et.entity_type = 'customer'
                  AND et.entity_id = c.id
                  AND LOWER(t.name) = 'vip'
            )
        """
    
    query += """ 
        GROUP BY c.id, pc.first_name, pc.last_name, pc.email, pc.phone, pc.mobile
        ORDER BY c.name 
        LIMIT %s OFFSET %s
    """
    params.extend([limit, offset])
    
    rows = execute_query(query, tuple(params))
    
    # Get total count
    count_query = "SELECT COUNT(*) as total FROM customers WHERE 1=1"
    count_params = []
    
    if search:
        count_query += """ AND (
            name ILIKE %s OR
            email ILIKE %s OR
            cvr_number ILIKE %s OR
            phone ILIKE %s OR
            city ILIKE %s
        )"""
        count_params.extend([search_term] * 5)
    
    if source == 'vtiger':
        count_query += " AND vtiger_id IS NOT NULL"
    elif source == 'local':
        count_query += " AND vtiger_id IS NULL"
    
    if is_active is not None:
        count_query += " AND is_active = %s"
        count_params.append(is_active)

    if vip is True:
        count_query += """
            AND EXISTS (
                SELECT 1
                FROM entity_tags et
                JOIN tags t ON t.id = et.tag_id
                WHERE et.entity_type = 'customer'
                  AND et.entity_id = customers.id
                  AND LOWER(t.name) = 'vip'
            )
        """
    
    count_result = execute_query_single(count_query, tuple(count_params))
    total = count_result['total'] if count_result else 0
    
    return {
        "customers": rows or [],
        "total": total,
        "limit": limit,
        "offset": offset
    }


@router.get("/customers/verify-linking")
async def verify_customer_linking():
    """
    🔍 Verificer kunde-linking på tværs af systemer.
    
    Krydstjek:
    1. tmodule_customers → Hub customers (via hub_customer_id)
    2. Hub customers → e-conomic (via economic_customer_number)
    3. tmodule_customers → e-conomic (via economic_customer_number match)
    """
    try:
        logger.info("🔍 Starting customer linking verification...")
        
        # 1. Tmodule customers overview
        tmodule_stats = execute_query_single("""
            SELECT 
                COUNT(*) as total,
                COUNT(hub_customer_id) as linked_to_hub,
                COUNT(economic_customer_number) as has_economic_number
            FROM tmodule_customers
        """)
        
        # 2. Hub customers overview
        hub_stats = execute_query_single("""
            SELECT 
                COUNT(*) as total,
                COUNT(economic_customer_number) as has_economic_number,
                COUNT(CASE WHEN economic_customer_number IS NOT NULL 
                           AND economic_customer_number::text != '' 
                           THEN 1 END) as valid_economic_number
            FROM customers
        """)
        
        # 3. Find tmodule customers UDEN Hub link
        tmodule_unlinked = execute_query("""
            SELECT id, name, economic_customer_number, email
            FROM tmodule_customers 
            WHERE hub_customer_id IS NULL
            ORDER BY name
            LIMIT 20
        """)
        
        # 4. Find tmodule customers med Hub link MEN Hub customer mangler economic number
        tmodule_linked_but_no_economic = execute_query("""
            SELECT 
                tc.id as tmodule_id,
                tc.name as tmodule_name,
                tc.economic_customer_number as tmodule_economic,
                c.id as hub_id,
                c.name as hub_name,
                c.economic_customer_number as hub_economic
            FROM tmodule_customers tc
            JOIN customers c ON tc.hub_customer_id = c.id
            WHERE c.economic_customer_number IS NULL 
               OR c.economic_customer_number::text = ''
            LIMIT 20
        """)
        
        # 5. Find economic number mismatches
        economic_mismatches = execute_query("""
            SELECT 
                tc.id as tmodule_id,
                tc.name as tmodule_name,
                tc.economic_customer_number as tmodule_economic,
                c.id as hub_id,
                c.name as hub_name,
                c.economic_customer_number as hub_economic
            FROM tmodule_customers tc
            JOIN customers c ON tc.hub_customer_id = c.id
            WHERE tc.economic_customer_number IS NOT NULL
              AND c.economic_customer_number IS NOT NULL
              AND tc.economic_customer_number::text != c.economic_customer_number::text
            LIMIT 20
        """)
        
        # 6. Find Hub customers der kunne matches på navn men ikke er linket
        potential_name_matches = execute_query("""
            SELECT 
                tc.id as tmodule_id,
                tc.name as tmodule_name,
                tc.economic_customer_number as tmodule_economic,
                c.id as hub_id,
                c.name as hub_name,
                c.economic_customer_number as hub_economic
            FROM tmodule_customers tc
            JOIN customers c ON LOWER(TRIM(tc.name)) = LOWER(TRIM(c.name))
            WHERE tc.hub_customer_id IS NULL
            LIMIT 20
        """)
        
        # 7. Beregn health score
        tmodule_link_pct = (tmodule_stats['linked_to_hub'] / tmodule_stats['total'] * 100) if tmodule_stats['total'] > 0 else 0
        hub_economic_pct = (hub_stats['valid_economic_number'] / hub_stats['total'] * 100) if hub_stats['total'] > 0 else 0
        
        health_score = (tmodule_link_pct * 0.6) + (hub_economic_pct * 0.4)
        
        if health_score >= 90:
            health_status = "excellent"
        elif health_score >= 75:
            health_status = "good"
        elif health_score >= 50:
            health_status = "fair"
        else:
            health_status = "poor"
        
        result = {
            "status": "success",
            "health": {
                "score": round(health_score, 1),
                "status": health_status,
                "description": f"{round(tmodule_link_pct, 1)}% tmodule linked, {round(hub_economic_pct, 1)}% hub has economic numbers"
            },
            "tmodule_customers": {
                "total": tmodule_stats['total'],
                "linked_to_hub": tmodule_stats['linked_to_hub'],
                "has_economic_number": tmodule_stats['has_economic_number'],
                "link_percentage": round(tmodule_link_pct, 1)
            },
            "hub_customers": {
                "total": hub_stats['total'],
                "has_economic_number": hub_stats['valid_economic_number'],
                "economic_percentage": round(hub_economic_pct, 1)
            },
            "issues": {
                "tmodule_unlinked_count": len(tmodule_unlinked),
                "tmodule_unlinked_sample": tmodule_unlinked[:5],
                "hub_missing_economic_count": len(tmodule_linked_but_no_economic),
                "hub_missing_economic_sample": tmodule_linked_but_no_economic[:5],
                "economic_mismatches_count": len(economic_mismatches),
                "economic_mismatches_sample": economic_mismatches[:5],
                "potential_name_matches_count": len(potential_name_matches),
                "potential_name_matches_sample": potential_name_matches[:5]
            },
            "recommendations": []
        }
        
        # Generer anbefalinger
        if len(tmodule_unlinked) > 0:
            result["recommendations"].append({
                "issue": "unlinked_tmodule_customers",
                "count": len(tmodule_unlinked),
                "action": "POST /api/v1/timetracking/sync/relink-customers",
                "description": "Kør re-linking for at matche på economic_customer_number eller navn"
            })
        
        if len(tmodule_linked_but_no_economic) > 0:
            result["recommendations"].append({
                "issue": "hub_customers_missing_economic_number",
                "count": len(tmodule_linked_but_no_economic),
                "action": "POST /api/v1/customers/sync-economic-from-simplycrm",
                "description": "Sync e-conomic numre fra Simply-CRM"
            })
        
        if len(economic_mismatches) > 0:
            result["recommendations"].append({
                "issue": "economic_number_mismatches",
                "count": len(economic_mismatches),
                "action": "Manual review required",
                "description": "Forskellige e-conomic numre i tmodule vs hub - tjek data manuelt"
            })
        
        if len(potential_name_matches) > 0:
            result["recommendations"].append({
                "issue": "potential_name_matches",
                "count": len(potential_name_matches),
                "action": "POST /api/v1/timetracking/sync/relink-customers",
                "description": "Disse kunder kunne linkes på navn"
            })
        
        logger.info(f"✅ Verification complete - Health: {health_status} ({health_score:.1f}%)")
        return result
        
    except Exception as e:
        logger.error(f"❌ Verification failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/customers/{customer_id}")
async def get_customer(customer_id: int):
    """Get single customer by ID with contact count and vTiger BMC Låst status"""
    # Get customer
    customer = execute_query_single(
        "SELECT * FROM customers WHERE id = %s",
        (customer_id,))
    
    if not customer:
        raise HTTPException(status_code=404, detail="Customer not found")
    
    # Get contact count
    contact_count_result = execute_query_single(
        "SELECT COUNT(*) as count FROM contact_companies WHERE customer_id = %s",
        (customer_id,))
    
    contact_count = contact_count_result['count'] if contact_count_result else 0
    
    # Get BMC Låst from vTiger if customer has vtiger_id
    bmc_locked = False
    if customer.get('vtiger_id'):
        try:
            from app.services.vtiger_service import get_vtiger_service
            vtiger = get_vtiger_service()
            account = await vtiger.get_account(customer['vtiger_id'])
            if account:
                # cf_accounts_bmclst is the BMC Låst field (checkbox: 1 = locked, 0 = not locked)
                bmc_locked = account.get('cf_accounts_bmclst') == '1'
        except Exception as e:
            logger.error(f"❌ Error fetching BMC Låst status: {e}")
            
    # Check for ACTIVE bankruptcy alerts
    bankruptcy_alert = execute_query_single(
        """
        SELECT id, subject, received_date 
        FROM email_messages 
        WHERE customer_id = %s 
        AND classification = 'bankruptcy' 
        AND status NOT IN ('processed', 'archived')
        ORDER BY received_date DESC
        LIMIT 1
        """,
        (customer_id,)
    )
    
    return {
        **customer,
        'contact_count': contact_count,
        'bmc_locked': bmc_locked,
        'bankruptcy_alert': bankruptcy_alert
    }



@router.get("/customers/{customer_id}/utility-company")
async def get_customer_utility_company(customer_id: int):
    """Lookup the netselskab for a customer's address via the Elnet API"""
    customer = execute_query_single(
        "SELECT address, city, postal_code FROM customers WHERE id = %s",
        (customer_id,)
    )

    if not customer:
        raise HTTPException(status_code=404, detail="Customer not found")

    address = customer.get('address')
    if not address:
        raise HTTPException(status_code=400, detail="Kunde har ikke en adresse")

    components = [address.strip()]
    city_parts = []
    if customer.get('postal_code'):
        city_parts.append(customer['postal_code'].strip())
    if customer.get('city'):
        city_parts.append(customer['city'].strip())
    if city_parts:
        components.append(' '.join(city_parts))

    search_address = ", ".join([comp for comp in components if comp])
    if not search_address:
        raise HTTPException(status_code=400, detail="Ugyldig adressedata")

    base_url = settings.ELNET_API_BASE_URL.rstrip('/')
    lookup_url = f"{base_url}/supplierlookup/{quote(search_address, safe='')}"
    timeout_seconds = settings.ELNET_TIMEOUT_SECONDS

    try:
        timeout = aiohttp.ClientTimeout(total=timeout_seconds)
        async with aiohttp.ClientSession(timeout=timeout) as session:
            async with session.get(lookup_url) as response:
                if response.status == 404:
                    return {
                        "customer_id": customer_id,
                        "address": search_address,
                        "found": False,
                        "message": "Ingen netselskab matchede adressen"
                    }

                if response.status != 200:
                    detail = await response.text()
                    logger.warning(
                        "⚠️ Elnet returned %s for %s (%s)",
                        response.status,
                        customer_id,
                        detail[:200]
                    )
                    raise HTTPException(status_code=502, detail="Fejl fra netselskabs-API")

                payload = await response.json()
    except asyncio.TimeoutError as exc:
        logger.error("❌ Elnet request timed out for customer %s: %s", customer_id, exc)
        raise HTTPException(status_code=504, detail="Timeout ved forespørgsel til netselskabet")
    except aiohttp.ClientError as exc:
        logger.error("❌ Elnet request failed for customer %s: %s", customer_id, exc)
        raise HTTPException(status_code=502, detail="Kunne ikke kontakte netselskabets API")
    except Exception as exc:
        logger.error("❌ Unexpected error fetching netselskab for %s: %s", customer_id, exc)
        raise HTTPException(status_code=500, detail="Fejl ved forespørgsel til netselskabet")

    supplier = {
        "def": payload.get("def"),
        "name": payload.get("name"),
        "phone": payload.get("phone"),
        "website": payload.get("website")
    }

    return {
        "customer_id": customer_id,
        "address": search_address,
        "found": bool(payload and payload.get("name")),
        "supplier": supplier
    }


@router.get("/customers/{customer_id}/vendors")
async def list_customer_vendors(customer_id: int):
    """List vendors linked to a customer."""
    customer = execute_query_single("SELECT id FROM customers WHERE id = %s", (customer_id,))
    if not customer:
        raise HTTPException(status_code=404, detail="Customer not found")

    rows = execute_query(
        """
        SELECT
            l.id,
            l.customer_id,
            l.vendor_id,
            l.relationship_type,
            l.created_at,
            l.updated_at,
            v.name AS vendor_name,
            v.email AS vendor_email,
            v.cvr_number AS vendor_cvr
        FROM customer_vendor_links l
        JOIN vendors v ON v.id = l.vendor_id
        WHERE l.customer_id = %s
        ORDER BY v.name ASC, l.id ASC
        """,
        (customer_id,),
    ) or []
    return rows


@router.post("/customers/{customer_id}/vendors/{vendor_id}")
async def link_customer_to_vendor(customer_id: int, vendor_id: int, relationship_type: str = Query("supplier")):
    """Create or update a customer-vendor link."""
    customer = execute_query_single("SELECT id FROM customers WHERE id = %s", (customer_id,))
    if not customer:
        raise HTTPException(status_code=404, detail="Customer not found")

    vendor = execute_query_single("SELECT id FROM vendors WHERE id = %s", (vendor_id,))
    if not vendor:
        raise HTTPException(status_code=404, detail="Vendor not found")

    rel = str(relationship_type or "supplier").strip().lower()
    if rel not in {"supplier", "reseller", "partner"}:
        raise HTTPException(status_code=400, detail="relationship_type must be supplier, reseller, or partner")

    row = execute_query_single(
        """
        INSERT INTO customer_vendor_links (customer_id, vendor_id, relationship_type)
        VALUES (%s, %s, %s)
        ON CONFLICT (customer_id, vendor_id)
        DO UPDATE SET
            relationship_type = EXCLUDED.relationship_type,
            updated_at = CURRENT_TIMESTAMP
        RETURNING id, customer_id, vendor_id, relationship_type, created_at, updated_at
        """,
        (customer_id, vendor_id, rel),
    )
    _ensure_customer_supplier_tag(int(customer_id))
    return row


@router.delete("/customers/{customer_id}/vendors/{vendor_id}")
async def unlink_customer_from_vendor(customer_id: int, vendor_id: int):
    """Remove customer-vendor link."""
    deleted = execute_update(
        "DELETE FROM customer_vendor_links WHERE customer_id = %s AND vendor_id = %s",
        (customer_id, vendor_id),
    )
    if not deleted:
        raise HTTPException(status_code=404, detail="Link not found")
    return {"success": True, "customer_id": customer_id, "vendor_id": vendor_id}

@router.post("/customers")
async def create_customer(customer: CustomerCreate):
    """Create a new customer"""
    try:
        customer_id = execute_insert(
            """INSERT INTO customers 
               (name, cvr_number, email, email_domain, phone, address, city, postal_code, 
                country, website, is_active, invoice_email, mobile_phone)
               VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
               RETURNING id""",
            (
                customer.name,
                customer.cvr_number,
                customer.email,
                customer.email_domain,
                customer.phone,
                customer.address,
                customer.city,
                customer.postal_code,
                customer.country,
                customer.website,
                customer.is_active,
                customer.invoice_email,
                customer.mobile_phone
            )
        )
        
        logger.info(f"✅ Created customer {customer_id}: {customer.name}")
        
        # Log activity
        CustomerActivityLogger.log_created(customer_id, customer.name)
        
        # Fetch and return created customer
        created = execute_query_single(
            "SELECT * FROM customers WHERE id = %s",
            (customer_id,))
        return created
        
    except Exception as e:
        logger.error(f"❌ Failed to create customer: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/customers/{customer_id}")
async def update_customer(customer_id: int, update: CustomerUpdate):
    """Update customer information"""
    # Verify customer exists
    existing = execute_query_single(
        "SELECT id, name FROM customers WHERE id = %s",
        (customer_id,))
    if not existing:
        raise HTTPException(status_code=404, detail="Customer not found")
    
    # Build dynamic UPDATE query
    updates = []
    params = []
    
    update_dict = update.dict(exclude_unset=True)
    fields_changed = list(update_dict.keys())
    
    for field, value in update_dict.items():
        updates.append(f"{field} = %s")
        params.append(value)
    
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")
    
    params.append(customer_id)
    
    query = f"UPDATE customers SET {', '.join(updates)}, updated_at = CURRENT_TIMESTAMP WHERE id = %s"
    
    try:
        execute_update(query, tuple(params))
        logger.info(f"✅ Updated customer {customer_id}")
        
        # Log activity
        CustomerActivityLogger.log_updated(customer_id, existing['name'], fields_changed)
        
        # Fetch and return updated customer
        updated = execute_query_single(
            "SELECT * FROM customers WHERE id = %s",
            (customer_id,))
        return updated
    except Exception as e:
        logger.error(f"❌ Failed to update customer {customer_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.patch("/customers/{customer_id}")
async def patch_customer(customer_id: int, update: CustomerUpdate):
    """Partially update customer information (same as PUT)"""
    return await update_customer(customer_id, update)


@router.get("/customers/{customer_id}/data-consistency")
async def check_customer_data_consistency(customer_id: int):
    """
    🔍 Check data consistency across Hub, vTiger, and e-conomic
    
    Returns discrepancies found between the three systems
    """
    try:
        from app.core.config import settings
        
        if not settings.AUTO_CHECK_CONSISTENCY:
            return {
                "enabled": False,
                "message": "Data consistency checking is disabled"
            }
        
        consistency_service = CustomerConsistencyService()
        
        # Fetch data from all systems
        all_data = await consistency_service.fetch_all_data(customer_id)
        
        # Compare data
        discrepancies = consistency_service.compare_data(all_data)
        
        # Count actual discrepancies
        discrepancy_count = sum(
            1 for field_data in discrepancies.values() 
            if field_data['discrepancy']
        )
        
        return {
            "enabled": True,
            "customer_id": customer_id,
            "discrepancy_count": discrepancy_count,
            "discrepancies": discrepancies,
            "systems_available": {
                "hub": True,
                "vtiger": all_data.get('vtiger') is not None,
                "economic": all_data.get('economic') is not None
            }
        }
        
    except Exception as e:
        logger.error(f"❌ Failed to check consistency for customer {customer_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/customers/{customer_id}/sync-field")
async def sync_customer_field(
    customer_id: int,
    field_name: str = Query(..., description="Hub field name to sync"),
    source_system: str = Query(..., description="Source system: hub, vtiger, or economic"),
    source_value: str = Query(..., description="The correct value to sync")
):
    """
    🔄 Sync a single field across all systems
    
    Takes the correct value from one system and updates the others
    """
    try:
        from app.core.config import settings
        
        # Validate source system
        if source_system not in ['hub', 'vtiger', 'economic']:
            raise HTTPException(
                status_code=400, 
                detail=f"Invalid source_system: {source_system}. Must be hub, vtiger, or economic"
            )
        
        consistency_service = CustomerConsistencyService()
        
        # Perform sync
        results = await consistency_service.sync_field(
            customer_id=customer_id,
            field_name=field_name,
            source_system=source_system,
            source_value=source_value
        )
        
        return {
            "success": True,
            "customer_id": customer_id,
            "field_name": field_name,
            "source_system": source_system,
            "source_value": source_value,
            "sync_results": results
        }
        
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"❌ Failed to sync field {field_name} for customer {customer_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/customers/sync-economic-from-simplycrm")
async def sync_economic_numbers_from_simplycrm():
    """
    🔗 Sync e-conomic customer numbers fra Simply-CRM til Hub customers.
    
    Henter cf_854 (economic_customer_number) fra Simply-CRM accounts og 
    opdaterer matching Hub customers baseret på navn.
    """
    try:
        from app.services.simplycrm_service import SimplyCRMService
        
        logger.info("🚀 Starting e-conomic number sync from Simply-CRM...")
        
        stats = {
            "simplycrm_accounts": 0,
            "accounts_with_economic_number": 0,
            "hub_customers_updated": 0,
            "hub_customers_not_found": 0,
            "errors": 0
        }
        
        async with SimplyCRMService() as simplycrm:
            # Hent alle accounts fra Simply-CRM
            logger.info("📥 Fetching accounts from Simply-CRM...")
            
            # Først: Tjek hvilke felter der er tilgængelige
            try:
                test_query = "SELECT * FROM Accounts LIMIT 1;"
                test_result = await simplycrm.query(test_query)
                if test_result:
                    logger.info(f"📋 Available fields: {list(test_result[0].keys())}")
            except Exception as e:
                logger.warning(f"⚠️ Could not fetch sample fields: {e}")
            
            # Query med standard felter + economic_acc_number
            query = "SELECT id, accountname, economic_acc_number FROM Accounts LIMIT 5000;"
            accounts = await simplycrm.query(query)
            
            stats["simplycrm_accounts"] = len(accounts)
            logger.info(f"✅ Found {len(accounts)} accounts in Simply-CRM")
            
            if not accounts:
                return {
                    "status": "success",
                    "message": "No accounts found in Simply-CRM",
                    "stats": stats
                }
            
            # Filter accounts med economic customer number
            accounts_with_economic = []
            for acc in accounts:
                economic_number = acc.get('economic_acc_number')
                
                if economic_number and str(economic_number).strip() not in ['', '0', 'null', 'NULL']:
                    accounts_with_economic.append({
                        'accountname': acc.get('accountname'),
                        'economic_number': str(economic_number).strip()
                    })
            
            stats["accounts_with_economic_number"] = len(accounts_with_economic)
            logger.info(f"✅ {len(accounts_with_economic)} accounts have e-conomic customer numbers")
            
            # Map company name → economic_customer_number
            name_to_economic = {}
            for acc_data in accounts_with_economic:
                company_name = acc_data['accountname'].strip()
                economic_number = acc_data['economic_number']
                
                if company_name and economic_number:
                    # Normalize navn til lowercase for matching
                    name_key = company_name.lower()
                    name_to_economic[name_key] = {
                        'original_name': company_name,
                        'economic_customer_number': economic_number
                    }
            
            logger.info(f"📊 Mapped {len(name_to_economic)} unique company names")
            
            # Hent alle Hub customers
            hub_customers = execute_query("SELECT id, name FROM customers")
            logger.info(f"📊 Found {len(hub_customers)} customers in Hub")
            
            # Build set af eksisterende kunde-navne (normalized)
            existing_customer_names = {c['name'].strip().lower() for c in hub_customers}
            
            # Find customers der mangler i Hub
            missing_customers = []
            for name_key, data in name_to_economic.items():
                if name_key not in existing_customer_names:
                    missing_customers.append(data)
            
            logger.info(f"📊 Found {len(missing_customers)} customers missing in Hub")
            
            # Opret manglende customers
            for missing in missing_customers:
                try:
                    execute_query(
                        """INSERT INTO customers (name, economic_customer_number, created_at, updated_at)
                           VALUES (%s, %s, NOW(), NOW())""",
                        (missing['original_name'], missing['economic_customer_number'])
                    )
                    logger.info(f"➕ Created customer: {missing['original_name']} → e-conomic #{missing['economic_customer_number']}")
                    stats["hub_customers_created"] = stats.get("hub_customers_created", 0) + 1
                except Exception as create_error:
                    logger.error(f"❌ Failed to create customer {missing['original_name']}: {create_error}")
                    stats["errors"] += 1
            
            # Match og opdater eksisterende
            for customer in hub_customers:
                customer_name_key = customer['name'].strip().lower()
                
                if customer_name_key in name_to_economic:
                    economic_data = name_to_economic[customer_name_key]
                    economic_number = economic_data['economic_customer_number']
                    
                    try:
                        execute_query(
                            """UPDATE customers 
                               SET economic_customer_number = %s, 
                                   last_synced_at = NOW() 
                               WHERE id = %s""",
                            (economic_number, customer['id'])
                        )
                        
                        logger.info(f"✅ Updated {customer['name']} → e-conomic #{economic_number}")
                        stats["hub_customers_updated"] += 1
                        
                    except Exception as update_error:
                        logger.error(f"❌ Failed to update customer {customer['id']}: {update_error}")
                        stats["errors"] += 1
                else:
                    stats["hub_customers_not_found"] += 1
            
            logger.info(f"✅ Sync complete: {stats}")
            
            # Auto-link tmodule_customers after sync
            try:
                logger.info("🔗 Running auto-link for timetracking customers...")
                link_results = execute_query("SELECT * FROM link_tmodule_customers_to_hub()")
                logger.info(f"✅ Linked {len(link_results)} timetracking customers")
                stats["tmodule_customers_linked"] = len(link_results)
            except Exception as link_error:
                logger.warning(f"⚠️ Auto-linking failed (non-critical): {link_error}")
            
            return {
                "status": "success",
                "message": f"Synced {stats['hub_customers_updated']} existing customers and created {stats.get('hub_customers_created', 0)} new customers from Simply-CRM",
                "stats": stats
            }
    
    except Exception as e:
        logger.error(f"❌ Simply-CRM sync failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/customers/{customer_id}/link-economic")
async def link_economic_customer(customer_id: int, link_request: dict):
    """Manually link customer to e-conomic customer number"""
    try:
        economic_customer_number = link_request.get('economic_customer_number')
        
        if not economic_customer_number:
            raise HTTPException(status_code=400, detail="economic_customer_number required")
        
        # Get customer
        customer = execute_query_single(
            "SELECT id, name FROM customers WHERE id = %s",
            (customer_id,))
        
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")
        
        # Update economic customer number
        execute_query(
            "UPDATE customers SET economic_customer_number = %s, last_synced_at = NOW() WHERE id = %s",
            (economic_customer_number, customer_id)
        )
        
        logger.info(f"✅ Linked customer {customer_id} ({customer['name']}) to e-conomic #{economic_customer_number}")
        
        return {
            "status": "success",
            "message": f"Kunde linket til e-conomic kundenr. {economic_customer_number}",
            "customer_id": customer_id,
            "economic_customer_number": economic_customer_number
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Failed to link customer {customer_id} to e-conomic: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/customers/{customer_id}/search-economic")
async def search_economic_for_customer(customer_id: int, query: Optional[str] = None):
    """Search e-conomic for matching customers by name"""
    try:
        from app.services.economic_service import EconomicService
        
        # Get customer
        customer = execute_query_single(
            "SELECT id, name FROM customers WHERE id = %s",
            (customer_id,))
        
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")
        
        # Use provided query or customer name
        search_query = query or customer['name']
        
        # Search in e-conomic
        economic = EconomicService()
        results = await economic.search_customer_by_name(search_query)
        
        return {
            "status": "success",
            "customer_id": customer_id,
            "customer_name": customer['name'],
            "search_query": search_query,
            "results": [
                {
                    "customerNumber": r.get('customerNumber'),
                    "name": r.get('name'),
                    "corporateIdentificationNumber": r.get('corporateIdentificationNumber'),
                    "email": r.get('email'),
                    "city": r.get('city')
                }
                for r in results
            ],
            "count": len(results)
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Failed to search e-conomic for customer {customer_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/customers/{customer_id}/subscriptions/lock")
async def lock_customer_subscriptions(customer_id: int, lock_request: dict):
    """Lock/unlock subscriptions for customer in local DB - BMC Låst status controlled in vTiger"""
    try:
        locked = lock_request.get('locked', False)
        
        # Get customer
        customer = execute_query_single(
            "SELECT id, name FROM customers WHERE id = %s",
            (customer_id,))
        
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")
        
        # Update local database only
        execute_update(
            "UPDATE customers SET subscriptions_locked = %s WHERE id = %s",
            (locked, customer_id)
        )
        logger.info(f"✅ Updated local subscriptions_locked={locked} for customer {customer_id}")
        
        return {
            "status": "success",
            "message": f"Abonnementer er nu {'låst' if locked else 'låst op'} i BMC Hub",
            "customer_id": customer_id,
            "note": "BMC Låst status i vTiger skal sættes manuelt i vTiger"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error locking subscriptions: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/customers/{customer_id}/contacts")
async def get_customer_contacts(customer_id: int):
    """Get all contacts for a specific customer"""
    rows = execute_query("""
        SELECT 
            c.*,
            cc.is_primary,
            cc.role,
            cc.notes
        FROM contacts c
        JOIN contact_companies cc ON c.id = cc.contact_id
        WHERE cc.customer_id = %s AND c.is_active = TRUE
        ORDER BY cc.is_primary DESC, c.first_name, c.last_name
    """, (customer_id,))
    
    return rows or []


@router.get("/customers/{customer_id}/kontakt")
async def get_customer_kontakt_history(customer_id: int, limit: int = Query(default=300, ge=1, le=2000)):
    """Get unified contact communication history (calls + SMS) for all company contacts."""
    customer = execute_query_single("SELECT id FROM customers WHERE id = %s", (customer_id,))
    if not customer:
        raise HTTPException(status_code=404, detail="Customer not found")

    sms_table_exists = execute_query_single("SELECT to_regclass('public.sms_messages') AS name")
    has_sms_table = bool(sms_table_exists and sms_table_exists.get("name"))

    if has_sms_table:
        query = """
            SELECT * FROM (
                SELECT
                    'call' AS type,
                    t.id::text AS event_id,
                    t.started_at AS happened_at,
                    t.direction,
                    COALESCE(
                        NULLIF(TRIM(t.ekstern_nummer), ''),
                        NULLIF(TRIM(t.raw_payload->>'caller'), ''),
                        NULLIF(TRIM(t.raw_payload->>'callee'), '')
                    ) AS number,
                    NULL::text AS message,
                    t.duration_sec,
                    COALESCE(u.full_name, u.username) AS user_name,
                    c.id AS contact_id,
                    TRIM(CONCAT(COALESCE(c.first_name, ''), ' ', COALESCE(c.last_name, ''))) AS contact_name,
                    NULL::text AS sms_status
                FROM telefoni_opkald t
                JOIN contacts c ON c.id = t.kontakt_id
                JOIN contact_companies cc ON cc.contact_id = c.id AND cc.customer_id = %s
                LEFT JOIN users u ON u.user_id = t.bruger_id

                UNION ALL

                SELECT
                    'sms' AS type,
                    s.id::text AS event_id,
                    s.created_at AS happened_at,
                    NULL::text AS direction,
                    s.recipient AS number,
                    s.message,
                    NULL::int AS duration_sec,
                    COALESCE(u.full_name, u.username) AS user_name,
                    c.id AS contact_id,
                    TRIM(CONCAT(COALESCE(c.first_name, ''), ' ', COALESCE(c.last_name, ''))) AS contact_name,
                    s.status AS sms_status
                FROM sms_messages s
                JOIN contacts c ON c.id = s.kontakt_id
                JOIN contact_companies cc ON cc.contact_id = c.id AND cc.customer_id = %s
                LEFT JOIN users u ON u.user_id = s.bruger_id
            ) x
            ORDER BY x.happened_at DESC NULLS LAST
            LIMIT %s
        """
        rows = execute_query(query, (customer_id, customer_id, limit))
    else:
        query = """
            SELECT
                'call' AS type,
                t.id::text AS event_id,
                t.started_at AS happened_at,
                t.direction,
                COALESCE(
                    NULLIF(TRIM(t.ekstern_nummer), ''),
                    NULLIF(TRIM(t.raw_payload->>'caller'), ''),
                    NULLIF(TRIM(t.raw_payload->>'callee'), '')
                ) AS number,
                NULL::text AS message,
                t.duration_sec,
                COALESCE(u.full_name, u.username) AS user_name,
                c.id AS contact_id,
                TRIM(CONCAT(COALESCE(c.first_name, ''), ' ', COALESCE(c.last_name, ''))) AS contact_name,
                NULL::text AS sms_status
            FROM telefoni_opkald t
            JOIN contacts c ON c.id = t.kontakt_id
            JOIN contact_companies cc ON cc.contact_id = c.id AND cc.customer_id = %s
            LEFT JOIN users u ON u.user_id = t.bruger_id
            ORDER BY t.started_at DESC NULLS LAST
            LIMIT %s
        """
        rows = execute_query(query, (customer_id, limit))

    return {"items": rows or []}


@router.post("/customers/{customer_id}/contacts")
async def create_customer_contact(customer_id: int, contact: ContactCreate):
    """Create a new contact for a customer"""
    # Verify customer exists
    customer = execute_query(
        "SELECT id FROM customers WHERE id = %s",
        (customer_id,))
    if not customer:
        raise HTTPException(status_code=404, detail="Customer not found")
    
    try:
        normalized_email = (contact.email or "").strip().lower() or None
        existing_contact = None

        # Prefer exact email match scoped to this customer, then global email match.
        if normalized_email:
            existing_contact = execute_query_single(
                """
                SELECT c.*
                FROM contacts c
                JOIN contact_companies cc ON cc.contact_id = c.id
                WHERE cc.customer_id = %s
                  AND LOWER(COALESCE(c.email, '')) = %s
                ORDER BY c.id ASC
                LIMIT 1
                """,
                (customer_id, normalized_email),
            )
            if not existing_contact:
                existing_contact = execute_query_single(
                    """
                    SELECT c.*
                    FROM contacts c
                    WHERE LOWER(COALESCE(c.email, '')) = %s
                    ORDER BY c.id ASC
                    LIMIT 1
                    """,
                    (normalized_email,),
                )

        # Fallback dedupe by full name within same customer when email is missing.
        if not existing_contact and not normalized_email:
            existing_contact = execute_query_single(
                """
                SELECT c.*
                FROM contacts c
                JOIN contact_companies cc ON cc.contact_id = c.id
                WHERE cc.customer_id = %s
                  AND LOWER(COALESCE(c.first_name, '')) = LOWER(%s)
                  AND LOWER(COALESCE(c.last_name, '')) = LOWER(%s)
                ORDER BY c.id ASC
                LIMIT 1
                """,
                (customer_id, contact.first_name, contact.last_name),
            )

        if existing_contact:
            contact_id = int(existing_contact["id"])
            execute_update(
                """
                INSERT INTO contact_companies (contact_id, customer_id, is_primary, role)
                VALUES (%s, %s, %s, %s)
                ON CONFLICT (contact_id, customer_id)
                DO UPDATE SET
                    is_primary = contact_companies.is_primary OR EXCLUDED.is_primary,
                    role = COALESCE(contact_companies.role, EXCLUDED.role)
                """,
                (contact_id, customer_id, bool(contact.is_primary), contact.role),
            )

            logger.info("✅ Reused contact %s for customer %s", contact_id, customer_id)
            return execute_query_single("SELECT * FROM contacts WHERE id = %s", (contact_id,))

        # Create contact when no reusable match exists.
        contact_id = execute_insert(
            """INSERT INTO contacts 
               (first_name, last_name, email, phone, mobile, title, department)
               VALUES (%s, %s, %s, %s, %s, %s, %s)
               RETURNING id""",
            (
                contact.first_name,
                contact.last_name,
                normalized_email,
                contact.phone,
                contact.mobile,
                contact.title,
                contact.department
            )
        )
        
        # Link contact to customer
        execute_update(
            """INSERT INTO contact_companies 
               (contact_id, customer_id, is_primary, role)
               VALUES (%s, %s, %s, %s)
               ON CONFLICT (contact_id, customer_id) DO NOTHING""",
            (contact_id, customer_id, bool(contact.is_primary), contact.role)
        )
        
        logger.info(f"✅ Created contact {contact_id} for customer {customer_id}")
        
        # Log activity
        contact_name = f"{contact.first_name} {contact.last_name}".strip()
        CustomerActivityLogger.log_contact_added(customer_id, contact_name)
        
        # Fetch and return created contact
        created = execute_query_single(
            "SELECT * FROM contacts WHERE id = %s",
            (contact_id,))
        return created
        
    except Exception as e:
        logger.error(f"❌ Failed to create contact: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/cvr/{cvr_number}")
async def lookup_cvr(cvr_number: str):
    """Lookup company information by CVR number"""
    cvr_service = get_cvr_service()
    
    result = await cvr_service.lookup_by_cvr(cvr_number)
    
    if not result:
        raise HTTPException(status_code=404, detail="CVR number not found")
    
    return result


@router.get("/customers/{customer_id}/subscriptions")
async def get_customer_subscriptions(customer_id: int):
    """
    Get subscriptions and sales orders for a customer
    Returns data from vTiger:
    1. Recurring Sales Orders (enable_recurring = 1)
    2. Sales Orders with recurring_frequency (open status)
    3. Recent Invoices for context
    """
    from app.services.vtiger_service import get_vtiger_service
    
    # Get customer with vTiger ID
    customer = execute_query_single(
        "SELECT id, name, vtiger_id FROM customers WHERE id = %s",
        (customer_id,))
    
    if not customer:
        raise HTTPException(status_code=404, detail="Customer not found")
    
    vtiger_id = customer.get('vtiger_id')
    
    if not vtiger_id:
        logger.warning(f"⚠️ Customer {customer_id} has no vTiger ID")
        return {
            "status": "no_vtiger_link",
            "message": "Kunde er ikke synkroniseret med vTiger",
            "recurring_orders": [],
            "sales_orders": [],
            "invoices": []
        }
    
    try:
        vtiger = get_vtiger_service()
        
        # Fetch all sales orders
        logger.info(f"🔍 Fetching sales orders for vTiger account {vtiger_id}")
        all_orders = await vtiger.get_customer_sales_orders(vtiger_id)
        
        # Fetch subscriptions from vTiger
        logger.info(f"🔍 Fetching subscriptions for vTiger account {vtiger_id}")
        subscriptions = await vtiger.get_customer_subscriptions(vtiger_id)
        
        # Filter sales orders into categories
        recurring_orders = []
        frequency_orders = []
        all_open_orders = []
        
        for order in all_orders:
            # Skip closed/cancelled orders
            status = order.get('sostatus', '').lower()
            if status in ['closed', 'cancelled']:
                continue
            
            all_open_orders.append(order)
            
            # Check if recurring is enabled
            enable_recurring = order.get('enable_recurring')
            recurring_frequency = order.get('recurring_frequency', '').strip()
            
            if enable_recurring == '1' or enable_recurring == 1:
                recurring_orders.append(order)
            elif recurring_frequency:
                frequency_orders.append(order)
        
        # Filter subscriptions by status
        active_subscriptions = []
        expired_subscriptions = []
        
        for sub in subscriptions:
            status = sub.get('sub_status', '').lower()
            if status in ['cancelled', 'expired']:
                expired_subscriptions.append(sub)
            else:
                active_subscriptions.append(sub)
        
        # Fetch Simply-CRM sales orders (open orders from old system)
        # NOTE: Simply-CRM has DIFFERENT IDs than vTiger Cloud! Must match by name or CVR.
        simplycrm_sales_orders = []
        try:
            from app.services.simplycrm_service import SimplyCRMService
            async with SimplyCRMService() as simplycrm:
                # First, find the Simply-CRM account by name
                customer_name = customer.get('name', '').strip()
                if customer_name:
                    # Search for account in Simply-CRM by name
                    account_query = f"SELECT id FROM Accounts WHERE accountname='{customer_name}';"
                    simplycrm_accounts = await simplycrm.query(account_query)
                    
                    if simplycrm_accounts and len(simplycrm_accounts) > 0:
                        simplycrm_account_id = simplycrm_accounts[0].get('id')
                        logger.info(f"🔍 Found Simply-CRM account: {simplycrm_account_id} for '{customer_name}'")
                        
                        # Query open sales orders from Simply-CRM using the correct ID
                        # Note: Simply-CRM returns one row per line item, so we need to group them
                        query = f"SELECT * FROM SalesOrder WHERE account_id='{simplycrm_account_id}';"
                        all_simplycrm_orders = await simplycrm.query(query)
                        logger.info(f"🔍 Simply-CRM raw query returned {len(all_simplycrm_orders or [])} orders for account {simplycrm_account_id}")
                        
                        # Group line items by order ID
                        # Filter: Only include orders with recurring_frequency (otherwise not subscription)
                        orders_dict = {}
                        filtered_closed = 0
                        filtered_no_freq = 0
                        for row in (all_simplycrm_orders or []):
                            status = row.get('sostatus', '').lower()
                            if status in ['closed', 'cancelled']:
                                filtered_closed += 1
                                logger.debug(f"  ⏭️ Skipping closed order: {row.get('subject', 'N/A')} ({status})")
                                continue
                            
                            # MUST have recurring_frequency to be a subscription
                            recurring_frequency = row.get('recurring_frequency', '').strip()
                            if not recurring_frequency:
                                filtered_no_freq += 1
                                logger.debug(f"  ⏭️ Skipping order without frequency: {row.get('subject', 'N/A')}")
                                continue
                            
                            logger.info(f"  ✅ Including order: {row.get('subject', 'N/A')} - {recurring_frequency} ({status})")
                            
                            order_id = row.get('id')
                            if order_id not in orders_dict:
                                # First occurrence - create order object
                                orders_dict[order_id] = dict(row)
                                orders_dict[order_id]['lineItems'] = []
                            
                            # Add line item if productid exists
                            if row.get('productid'):
                                # Fetch product name
                                product_name = 'Unknown Product'
                                try:
                                    product_query = f"SELECT productname FROM Products WHERE id='{row.get('productid')}';"
                                    product_result = await simplycrm.query(product_query)
                                    if product_result and len(product_result) > 0:
                                        product_name = product_result[0].get('productname', product_name)
                                except:
                                    pass
                                
                                orders_dict[order_id]['lineItems'].append({
                                    'productid': row.get('productid'),
                                    'product_name': product_name,
                                    'quantity': row.get('quantity'),
                                    'listprice': row.get('listprice'),
                                    'netprice': float(row.get('quantity', 0)) * float(row.get('listprice', 0)),
                                    'comment': row.get('comment', '')
                                })
                        
                        simplycrm_sales_orders = list(orders_dict.values())
                        logger.info(f"📥 Found {len(simplycrm_sales_orders)} unique recurring orders in Simply-CRM (filtered out: {filtered_closed} closed, {filtered_no_freq} without frequency)")
                    else:
                        logger.info(f"ℹ️ No Simply-CRM account found for '{customer_name}'")
        except Exception as e:
            logger.warning(f"⚠️ Could not fetch Simply-CRM sales orders: {e}")
        
        # Fetch BMC Office subscriptions from local database
        bmc_office_query = """
            SELECT * FROM bmc_office_subscription_totals
            WHERE customer_id = %s AND active = true
            ORDER BY start_date DESC
        """
        bmc_office_subs = execute_query(bmc_office_query, (customer_id,)) or []
        
        logger.info(f"✅ Found {len(recurring_orders)} recurring orders, {len(frequency_orders)} frequency orders, {len(all_open_orders)} vTiger orders, {len(simplycrm_sales_orders)} Simply-CRM orders, {len(active_subscriptions)} active subscriptions, {len(bmc_office_subs)} BMC Office subscriptions")
        
        return {
            "status": "success",
            "customer_id": customer_id,
            "customer_name": customer['name'],
            "vtiger_id": vtiger_id,
            "recurring_orders": recurring_orders,
            "sales_orders": simplycrm_sales_orders,  # Open sales orders from Simply-CRM
            "subscriptions": active_subscriptions,  # Active subscriptions from vTiger Subscriptions module
            "expired_subscriptions": expired_subscriptions,
            "bmc_office_subscriptions": bmc_office_subs,  # Local BMC Office subscriptions
            "last_updated": "real-time"
        }
        
    except Exception as e:
        logger.error(f"❌ Error fetching subscriptions: {e}")
        raise HTTPException(status_code=500, detail=f"Failed to fetch subscriptions: {str(e)}")


class SubscriptionCreate(BaseModel):
    subject: str
    account_id: str  # vTiger account ID
    startdate: str  # YYYY-MM-DD
    enddate: Optional[str] = None  # YYYY-MM-DD
    generateinvoiceevery: str  # "Monthly", "Quarterly", "Yearly"
    subscriptionstatus: Optional[str] = "Active"
    products: List[Dict]  # [{"productid": "id", "quantity": 1, "listprice": 100}]


class SubscriptionUpdate(BaseModel):
    subject: Optional[str] = None
    startdate: Optional[str] = None
    enddate: Optional[str] = None
    generateinvoiceevery: Optional[str] = None
    subscriptionstatus: Optional[str] = None
    products: Optional[List[Dict]] = None


@router.post("/customers/{customer_id}/subscriptions")
async def create_subscription(customer_id: int, subscription: SubscriptionCreate):
    """Create new subscription in vTiger"""
    try:
        # Get customer's vTiger ID
        customer = execute_query(
            "SELECT vtiger_id FROM customers WHERE id = %s",
            (customer_id,))
        
        if not customer or not customer.get('vtiger_id'):
            raise HTTPException(status_code=404, detail="Customer not linked to vTiger")
        
        # Create subscription in vTiger
        from app.services.vtiger_service import VTigerService
        async with VTigerService() as vtiger:
            result = await vtiger.create_subscription(
                account_id=customer['vtiger_id'],
                subject=subscription.subject,
                startdate=subscription.startdate,
                enddate=subscription.enddate,
                generateinvoiceevery=subscription.generateinvoiceevery,
                subscriptionstatus=subscription.subscriptionstatus,
                products=subscription.products
            )
        
        # Log activity
        subscription_name = subscription.subject or 'Nyt abonnement'
        CustomerActivityLogger.log_subscription_created(customer_id, subscription_name)
            
        logger.info(f"✅ Created subscription {result.get('id')} for customer {customer_id}")
        return {"status": "success", "subscription": result}
        
    except Exception as e:
        logger.error(f"❌ Error creating subscription: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/subscriptions/{subscription_id}")
async def get_subscription_details(subscription_id: str):
    """Get full subscription details with line items from vTiger"""
    try:
        from app.services.vtiger_service import get_vtiger_service
        vtiger = get_vtiger_service()
        
        subscription = await vtiger.get_subscription(subscription_id)
        
        if not subscription:
            raise HTTPException(status_code=404, detail="Subscription not found")
        
        return {"status": "success", "subscription": subscription}
        
    except Exception as e:
        logger.error(f"❌ Error fetching subscription: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/subscriptions/{subscription_id}")
async def update_subscription(subscription_id: str, subscription: SubscriptionUpdate):
    """Update subscription in vTiger including line items/prices"""
    try:
        from app.services.vtiger_service import get_vtiger_service
        vtiger = get_vtiger_service()
        
        # Extract products/line items if provided
        update_dict = subscription.dict(exclude_unset=True)
        line_items = update_dict.pop('products', None)
        
        result = await vtiger.update_subscription(
            subscription_id=subscription_id,
            updates=update_dict,
            line_items=line_items
        )
        
        # Log activity if we can find customer_id
        if result and result.get('account_id'):
            customer = execute_query_single(
                "SELECT id, name FROM customers WHERE vtiger_id = %s",
                (result['account_id'],))
            if customer:
                subscription_name = result.get('subject', subscription_id)
                CustomerActivityLogger.log_subscription_updated(customer['id'], subscription_name)
        
        logger.info(f"✅ Updated subscription {subscription_id}")
        return {"status": "success", "subscription": result}
        
    except Exception as e:
        logger.error(f"❌ Error updating subscription: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/subscriptions/{subscription_id}")
async def delete_subscription(subscription_id: str, customer_id: int = None):
    """Delete (deactivate) subscription in vTiger - respects customer lock status"""
    try:
        # Check if subscriptions are locked for this customer (if customer_id provided)
        if customer_id:
            customer = execute_query_single(
                "SELECT subscriptions_locked FROM customers WHERE id = %s",
                (customer_id,))
            if customer and customer.get('subscriptions_locked'):
                raise HTTPException(
                    status_code=403, 
                    detail="Abonnementer er låst for denne kunde. Kan kun redigeres direkte i vTiger."
                )
        
        from app.services.vtiger_service import get_vtiger_service
        vtiger = get_vtiger_service()
        
        # Set status to Cancelled instead of deleting
        result = await vtiger.update_subscription(
            subscription_id=subscription_id,
            updates={"subscriptionstatus": "Cancelled"},
            line_items=None
        )
        
        # Log activity
        if customer_id:
            subscription_name = result.get('subject', subscription_id) if result else subscription_id
            CustomerActivityLogger.log_subscription_deleted(customer_id, subscription_name)
        
        logger.info(f"✅ Cancelled subscription {subscription_id}")
        return {"status": "success", "message": "Subscription cancelled"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error deleting subscription: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# Subscription Internal Comment Endpoints
class SubscriptionComment(BaseModel):
    comment: str


@router.post("/customers/{customer_id}/subscription-comment")
async def save_subscription_comment(customer_id: int, data: SubscriptionComment):
    """Save internal comment about customer subscriptions"""
    try:
        # Check if customer exists
        customer = execute_query_single(
            "SELECT id FROM customers WHERE id = %s",
            (customer_id,)
        )
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")
        
        # Delete existing comment if any and insert new one in a single query
        result = execute_query(
            """
            WITH deleted AS (
                DELETE FROM customer_notes 
                WHERE customer_id = %s AND note_type = 'subscription_comment'
            )
            INSERT INTO customer_notes (customer_id, note_type, note, created_by, created_at)
            VALUES (%s, 'subscription_comment', %s, 'System', NOW())
            RETURNING id, note, created_by, created_at
            """,
            (customer_id, customer_id, data.comment)
        )
        
        if not result or len(result) == 0:
            raise Exception("Failed to insert comment")
        
        row = result[0]
        logger.info(f"✅ Saved subscription comment for customer {customer_id}")
        return {
            "id": row['id'],
            "comment": row['note'],
            "created_by": row['created_by'],
            "created_at": row['created_at'].isoformat()
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error saving subscription comment: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/customers/{customer_id}/subscription-comment")
async def get_subscription_comment(customer_id: int):
    """Get internal comment about customer subscriptions"""
    try:
        result = execute_query_single(
            """
            SELECT id, note, created_by, created_at
            FROM customer_notes
            WHERE customer_id = %s AND note_type = 'subscription_comment'
            ORDER BY created_at DESC
            LIMIT 1
            """,
            (customer_id,)
        )
        
        if not result:
            raise HTTPException(status_code=404, detail="No comment found")
        
        return {
            "id": result['id'],
            "comment": result['note'],
            "created_by": result['created_by'],
            "created_at": result['created_at'].isoformat()
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error fetching subscription comment: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/customers/{customer_id}/subscriptions/billing-matrix")
async def get_subscription_billing_matrix(
    customer_id: int,
    months: int = Query(default=12, ge=1, le=60, description="Number of months to show")
):
    """
    Get subscription billing matrix showing monthly invoiced amounts per product
    
    Rows: Products from e-conomic invoices
    Columns: Months
    Cells: Amount, status (paid/invoiced/missing), invoice reference
    
    Data source: e-conomic sales invoices only
    """
    try:
        # Verify customer exists
        customer = execute_query_single(
            "SELECT id, economic_customer_number FROM customers WHERE id = %s",
            (customer_id,)
        )
        
        if not customer:
            raise HTTPException(status_code=404, detail=f"Customer {customer_id} not found")
        
        if not customer.get('economic_customer_number'):
            logger.warning(f"⚠️ Customer {customer_id} has no e-conomic number")
            return {
                "customer_id": customer_id,
                "error": "Customer not linked to e-conomic",
                "products": []
            }
        
        # Generate matrix
        from app.services.subscription_matrix import get_subscription_matrix_service
        matrix_service = get_subscription_matrix_service()
        matrix = await matrix_service.generate_billing_matrix(customer_id, months)
        
        logger.info(f"✅ Generated billing matrix for customer {customer_id}")
        return matrix
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error generating billing matrix: {e}")
        raise HTTPException(status_code=500, detail=str(e))

