"""
Contact API Router
Handles contact CRUD operations with multi-company support
"""

from fastapi import APIRouter, HTTPException, Query
from typing import Optional, List
from app.core.database import execute_query, execute_insert, execute_update
from app.core.contact_utils import get_contact_customer_ids, get_primary_customer_id
from app.customers.backend.router import (
    get_customer_subscriptions,
    lock_customer_subscriptions,
    save_subscription_comment,
    get_subscription_comment,
    get_subscription_billing_matrix,
    SubscriptionComment,
)
import logging

logger = logging.getLogger(__name__)
router = APIRouter()


@router.get("/contacts-debug", response_model=dict)
async def debug_contacts():
    """
    Debug endpoint: Check contact-company links
    """
    try:
        # Count links
        links = execute_query("SELECT COUNT(*) as total FROM contact_companies")
        
        # Get sample with links
        sample = execute_query("""
            SELECT 
                c.id, c.first_name, c.last_name,
                COUNT(cc.customer_id) as company_count,
                ARRAY_AGG(cu.name) as company_names
            FROM contacts c
            LEFT JOIN contact_companies cc ON c.id = cc.contact_id
            LEFT JOIN customers cu ON cc.customer_id = cu.id
            GROUP BY c.id, c.first_name, c.last_name
            HAVING COUNT(cc.customer_id) > 0
            LIMIT 10
        """)
        
        # Test the actual query used in get_contacts
        test_query = """
            SELECT 
                c.id, c.first_name, c.last_name,
                COUNT(DISTINCT cc.customer_id) as company_count,
                ARRAY_AGG(DISTINCT cu.name ORDER BY cu.name) FILTER (WHERE cu.name IS NOT NULL) as company_names
            FROM contacts c
            LEFT JOIN contact_companies cc ON c.id = cc.contact_id
            LEFT JOIN customers cu ON cc.customer_id = cu.id
            GROUP BY c.id, c.first_name, c.last_name
            ORDER BY c.last_name, c.first_name
            LIMIT 10
        """
        test_result = execute_query(test_query)
        
        return {
            "total_links": links[0]['total'] if links else 0,
            "sample_contacts_with_companies": sample or [],
            "test_query_result": test_result or [],
            "note": "If company_count is 0, the JOIN might not be working"
        }
        
    except Exception as e:
        logger.error(f"Debug failed: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/contacts", response_model=dict)
async def get_contacts(
    search: Optional[str] = None,
    customer_id: Optional[int] = None,
    is_active: Optional[bool] = None,
    limit: int = Query(default=20, le=100),
    offset: int = Query(default=0, ge=0)
):
    """
    Get all contacts with optional filtering, search, and pagination
    """
    try:
        # Build WHERE clauses
        where_clauses = []
        params = []
        
        if search:
            where_clauses.append(
                """
                (
                    c.first_name ILIKE %s
                    OR c.last_name ILIKE %s
                    OR c.email ILIKE %s
                    OR c.phone ILIKE %s
                    OR c.mobile ILIKE %s
                    OR EXISTS (
                        SELECT 1
                        FROM contact_companies cc2
                        JOIN customers cu2 ON cu2.id = cc2.customer_id
                        WHERE cc2.contact_id = c.id
                          AND cu2.name ILIKE %s
                    )
                )
                """
            )
            like = f"%{search}%"
            params.extend([like, like, like, like, like, like])
        
        if is_active is not None:
            where_clauses.append("c.is_active = %s")
            params.append(is_active)
        
        if customer_id is not None:
            where_clauses.append("EXISTS (SELECT 1 FROM contact_companies cc WHERE cc.contact_id = c.id AND cc.customer_id = %s)")
            params.append(customer_id)
        
        where_sql = "WHERE " + " AND ".join(where_clauses) if where_clauses else ""
        
        # Count total
        count_query = f"""
            SELECT COUNT(DISTINCT c.id)
            FROM contacts c
            {where_sql}
        """
        count_result = execute_query_single(count_query, tuple(params))
        total = count_result['count'] if count_result else 0
        
        # Get contacts with company count
        query = f"""
            SELECT 
                c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
                c.title, c.department, c.is_active, c.vtiger_id,
                c.created_at, c.updated_at,
                COUNT(DISTINCT cc.customer_id) as company_count,
                ARRAY_AGG(DISTINCT cu.name ORDER BY cu.name) FILTER (WHERE cu.name IS NOT NULL) as company_names
            FROM contacts c
            LEFT JOIN contact_companies cc ON c.id = cc.contact_id
            LEFT JOIN customers cu ON cc.customer_id = cu.id
            {where_sql}
            GROUP BY c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
                     c.title, c.department, c.is_active, c.vtiger_id, c.created_at, c.updated_at
            ORDER BY c.last_name, c.first_name
            LIMIT %s OFFSET %s
        """
        params.extend([limit, offset])
        
        contacts = execute_query(query, tuple(params))  # Returns all rows
        
        return {
            "contacts": contacts or [],
            "total": total,
            "limit": limit,
            "offset": offset
        }
        
    except Exception as e:
        logger.error(f"Failed to get contacts: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/contacts/{contact_id}", response_model=dict)
async def get_contact(contact_id: int):
    """
    Get a single contact with all linked companies
    """
    try:
        # Get contact
        contact_query = """
            SELECT id, first_name, last_name, email, phone, mobile,
                   title, department, is_active, vtiger_id,
                   created_at, updated_at
            FROM contacts
            WHERE id = %s
        """
        contact_result = execute_query(contact_query, (contact_id,))
        
        if not contact_result:
            raise HTTPException(status_code=404, detail="Contact not found")
        
        contact = contact_result[0]
        
        # Get linked companies
        companies_query = """
            SELECT 
                cu.id, cu.name, 
                cc.is_primary, cc.role, cc.notes
            FROM contact_companies cc
            JOIN customers cu ON cc.customer_id = cu.id
            WHERE cc.contact_id = %s
            ORDER BY cc.is_primary DESC, cu.name
        """
        companies = execute_query(companies_query, (contact_id,))
        
        contact['companies'] = companies or []
        return contact
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to get contact {contact_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# POST/PUT/DELETE endpoints temporarily disabled - need proper models
# @router.post("/contacts", response_model=dict)
# async def create_contact(contact: ContactCreate):
#     """
#     Create a new contact and link to companies
#     """
    try:
        # Insert contact
        insert_query = """
            INSERT INTO contacts (first_name, last_name, email, phone, mobile, title, department, is_active)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
        """
        contact_id = execute_insert(
            insert_query,
            (contact.first_name, contact.last_name, contact.email, contact.phone,
             contact.mobile, contact.title, contact.department, contact.is_active)
        )
        
        # Link to companies
        if contact.company_ids:
            for idx, customer_id in enumerate(contact.company_ids):
                is_primary = idx == 0 and contact.is_primary
                link_query = """
                    INSERT INTO contact_companies (contact_id, customer_id, is_primary, role, notes)
                    VALUES (%s, %s, %s, %s, %s)
                """
                execute_insert(
                    link_query,
                    (contact_id, customer_id, is_primary, contact.role, contact.notes)
                )
        
        # Return created contact
        return await get_contact(contact_id)
        
    except Exception as e:
        logger.error(f"Failed to create contact: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/contacts/{contact_id}", response_model=dict)
async def update_contact(contact_id: int, contact: ContactUpdate):
    """
    Update a contact
    """
    try:
        # Check if contact exists
        existing = execute_query("SELECT id FROM contacts WHERE id = %s", (contact_id,))
        if not existing:
            raise HTTPException(status_code=404, detail="Contact not found")
        
        # Build update query
        update_fields = []
        params = []
        
        if contact.first_name is not None:
            update_fields.append("first_name = %s")
            params.append(contact.first_name)
        
        if contact.last_name is not None:
            update_fields.append("last_name = %s")
            params.append(contact.last_name)
        
        if contact.email is not None:
            update_fields.append("email = %s")
            params.append(contact.email)
        
        if contact.phone is not None:
            update_fields.append("phone = %s")
            params.append(contact.phone)
        
        if contact.mobile is not None:
            update_fields.append("mobile = %s")
            params.append(contact.mobile)
        
        if contact.title is not None:
            update_fields.append("title = %s")
            params.append(contact.title)
        
        if contact.department is not None:
            update_fields.append("department = %s")
            params.append(contact.department)
        
        if contact.is_active is not None:
            update_fields.append("is_active = %s")
            params.append(contact.is_active)
        
        if not update_fields:
            return await get_contact(contact_id)
        
        update_query = f"""
            UPDATE contacts
            SET {', '.join(update_fields)}, updated_at = CURRENT_TIMESTAMP
            WHERE id = %s
        """
        params.append(contact_id)
        
        execute_update(update_query, tuple(params))
        
        return await get_contact(contact_id)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to update contact {contact_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/contacts/{contact_id}")
async def delete_contact(contact_id: int):
    """
    Delete a contact (cascade deletes company links)
    """
    try:
        result = execute_update("DELETE FROM contacts WHERE id = %s", (contact_id,))
        if result == 0:
            raise HTTPException(status_code=404, detail="Contact not found")
        
        return {"message": "Contact deleted successfully"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to delete contact {contact_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/contacts/{contact_id}/companies")
async def link_contact_to_company(contact_id: int, link: ContactCompanyLink):
    """
    Link a contact to a company
    """
    try:
        # Check if contact exists
        contact = execute_query_single("SELECT id FROM contacts WHERE id = %s", (contact_id,))
        if not contact:
            raise HTTPException(status_code=404, detail="Contact not found")
        
        # Check if company exists
        customer = execute_query_single("SELECT id FROM customers WHERE id = %s", (link.customer_id,))
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")
        
        # Insert link (ON CONFLICT updates)
        query = """
            INSERT INTO contact_companies (contact_id, customer_id, is_primary, role, notes)
            VALUES (%s, %s, %s, %s, %s)
            ON CONFLICT (contact_id, customer_id) 
            DO UPDATE SET is_primary = EXCLUDED.is_primary, role = EXCLUDED.role, notes = EXCLUDED.notes
        """
        execute_insert(query, (contact_id, link.customer_id, link.is_primary, link.role, link.notes))
        
        return {"message": "Contact linked to company successfully"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to link contact to company: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/contacts/{contact_id}/companies/{customer_id}")
async def unlink_contact_from_company(contact_id: int, customer_id: int):
    """
    Unlink a contact from a company
    """
    try:
        result = execute_update(
            "DELETE FROM contact_companies WHERE contact_id = %s AND customer_id = %s",
            (contact_id, customer_id)
        )
        
        if result == 0:
            raise HTTPException(status_code=404, detail="Link not found")
        
        return {"message": "Contact unlinked from company successfully"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to unlink contact from company: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/contacts/{contact_id}/related-contacts", response_model=dict)
async def get_related_contacts(contact_id: int):
    """
    Get contacts from the same companies as the contact (excluding itself).
    """
    try:
        customer_ids = get_contact_customer_ids(contact_id)
        if not customer_ids:
            return {"contacts": []}

        placeholders = ",".join(["%s"] * len(customer_ids))
        query = f"""
            SELECT
                c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
                c.title, c.department, c.is_active, c.vtiger_id,
                c.created_at, c.updated_at,
                ARRAY_AGG(DISTINCT cu.name ORDER BY cu.name) FILTER (WHERE cu.name IS NOT NULL) as company_names
            FROM contacts c
            JOIN contact_companies cc ON c.id = cc.contact_id
            JOIN customers cu ON cc.customer_id = cu.id
            WHERE cc.customer_id IN ({placeholders}) AND c.id <> %s
            GROUP BY c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
                     c.title, c.department, c.is_active, c.vtiger_id, c.created_at, c.updated_at
            ORDER BY c.last_name, c.first_name
        """
        params = tuple(customer_ids + [contact_id])
        results = execute_query(query, params) or []
        return {"contacts": results}

    except Exception as e:
        logger.error(f"Failed to get related contacts for {contact_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/contacts/{contact_id}/subscriptions")
async def get_contact_subscriptions(contact_id: int):
    customer_id = get_primary_customer_id(contact_id)
    if not customer_id:
        return {
            "status": "no_linked_customer",
            "message": "Kontakt er ikke tilknyttet et firma",
            "recurring_orders": [],
            "sales_orders": [],
            "subscriptions": [],
            "expired_subscriptions": [],
            "bmc_office_subscriptions": [],
        }
    return await get_customer_subscriptions(customer_id)


@router.post("/contacts/{contact_id}/subscriptions/lock")
async def lock_contact_subscriptions(contact_id: int, lock_request: dict):
    customer_id = get_primary_customer_id(contact_id)
    if not customer_id:
        raise HTTPException(status_code=404, detail="Kontakt har ingen tilknyttet kunde")
    return await lock_customer_subscriptions(customer_id, lock_request)


@router.post("/contacts/{contact_id}/subscription-comment")
async def save_contact_subscription_comment(contact_id: int, data: SubscriptionComment):
    customer_id = get_primary_customer_id(contact_id)
    if not customer_id:
        raise HTTPException(status_code=404, detail="Kontakt har ingen tilknyttet kunde")
    return await save_subscription_comment(customer_id, data)


@router.get("/contacts/{contact_id}/subscription-comment")
async def get_contact_subscription_comment(contact_id: int):
    customer_id = get_primary_customer_id(contact_id)
    if not customer_id:
        raise HTTPException(status_code=404, detail="Kontakt har ingen tilknyttet kunde")
    return await get_subscription_comment(customer_id)


@router.get("/contacts/{contact_id}/subscriptions/billing-matrix")
async def get_contact_subscription_billing_matrix(
    contact_id: int,
    months: int = Query(default=12, ge=1, le=60, description="Number of months to show"),
):
    customer_id = get_primary_customer_id(contact_id)
    if not customer_id:
        raise HTTPException(status_code=404, detail="Kontakt har ingen tilknyttet kunde")
    return await get_subscription_billing_matrix(customer_id, months)
