"""
Contact API Router - Simplified (Read-Only)
Only GET endpoints for now
"""

from fastapi import APIRouter, HTTPException, Query, Body, status
from typing import Optional
from pydantic import BaseModel, Field
from app.core.database import execute_query, execute_insert
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()


class ContactCreate(BaseModel):
    """Schema for creating a contact"""
    first_name: str
    last_name: str = ""
    email: Optional[str] = None
    phone: Optional[str] = None
    title: Optional[str] = None
    company_id: Optional[int] = None


class ContactUpdate(BaseModel):
    """Schema for updating a contact"""
    first_name: Optional[str] = None
    last_name: Optional[str] = None
    email: Optional[str] = None
    phone: Optional[str] = None
    mobile: Optional[str] = None
    title: Optional[str] = None
    department: Optional[str] = None
    is_active: Optional[bool] = None


class ContactCompanyLink(BaseModel):
    customer_id: int
    is_primary: bool = True
    role: Optional[str] = None



@router.get("/contacts-debug")
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")
async def get_contacts(
    search: Optional[str] = None,
    customer_id: Optional[int] = None,
    is_active: Optional[bool] = None,
    limit: int = Query(default=100, le=1000),
    offset: int = Query(default=0, ge=0)
):
    """Get all contacts with optional filtering"""
    try:
        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 c.user_company 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, 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 (distinct id for consistency with optional filters/joins)
        count_query = f"SELECT COUNT(DISTINCT c.id) as count FROM contacts c {where_sql}"
        count_result = execute_query(count_query, tuple(params))
        total = count_result[0]['count'] if count_result else 0
        
        # Step 1: Fetch contacts only (stable pagination)
        contacts_query = f"""
            SELECT 
                c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile,
                c.title, c.department, c.user_company, c.is_active, c.created_at, c.updated_at
            FROM contacts c
            {where_sql}
            ORDER BY c.last_name, c.first_name, c.id
            LIMIT %s OFFSET %s
        """
        contacts_params = list(params)
        contacts_params.extend([limit, offset])
        contacts = execute_query(contacts_query, tuple(contacts_params)) or []

        # Step 2: Enrich page contacts with aggregated company info
        if contacts:
            contact_ids = [row["id"] for row in contacts]
            placeholders = ",".join(["%s"] * len(contact_ids))
            companies_query = f"""
                SELECT
                    cc.contact_id,
                    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 contact_companies cc
                LEFT JOIN customers cu ON cc.customer_id = cu.id
                WHERE cc.contact_id IN ({placeholders})
                GROUP BY cc.contact_id
            """
            company_rows = execute_query(companies_query, tuple(contact_ids)) or []
            company_map = {row["contact_id"]: row for row in company_rows}

            for contact in contacts:
                info = company_map.get(contact["id"])
                contact["company_count"] = int(info["company_count"]) if info and info.get("company_count") is not None else 0
                contact["company_names"] = info.get("company_names") if info and info.get("company_names") else []
        
        return {
            "total": total,
            "contacts": contacts,
            "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.post("/contacts", status_code=status.HTTP_201_CREATED)
async def create_contact(contact: ContactCreate):
    """
    Create a new basic contact
    """
    try:
        # Check if email exists
        if contact.email:
            existing = execute_query(
                "SELECT id FROM contacts WHERE email = %s", 
                (contact.email,)
            )
            if existing:
                # Return existing contact if found? Or error?
                # For now, let's error to be safe, or just return it?
                # User prompted "Smart Create", implies if it exists, use it?
                # But safer to say "Email already exists"
                pass 
                
        insert_query = """
            INSERT INTO contacts (first_name, last_name, email, phone, title, is_active)
            VALUES (%s, %s, %s, %s, %s, true)
            RETURNING id
        """
        
        contact_id = execute_insert(
            insert_query,
            (contact.first_name, contact.last_name, contact.email, contact.phone, contact.title)
        )
        
        # Link to company if provided
        if contact.company_id:
            try:
                link_query = """
                    INSERT INTO contact_companies (contact_id, customer_id, is_primary, role)
                    VALUES (%s, %s, true, 'primary')
                    ON CONFLICT (contact_id, customer_id)
                    DO UPDATE SET is_primary = EXCLUDED.is_primary, role = EXCLUDED.role
                    RETURNING id
                """
                execute_insert(link_query, (contact_id, contact.company_id))
            except Exception as e:
                logger.error(f"Failed to link new contact {contact_id} to company {contact.company_id}: {e}")
                # Don't fail the whole request, just log it
        
        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.get("/contacts/{contact_id}")
async def get_contact(contact_id: int):
    """Get a single contact by ID with linked companies"""
    try:
        # Get contact info
        query = """
            SELECT 
                id, first_name, last_name, email, phone, mobile,
                title, department, is_active, user_company, vtiger_id,
                created_at, updated_at
            FROM contacts
            WHERE id = %s
        """
        contacts = execute_query(query, (contact_id,))
        
        if not contacts:
            raise HTTPException(status_code=404, detail="Contact not found")
        
        contact = contacts[0]
        
        # Get linked companies
        companies_query = """
            SELECT 
                cu.id, cu.name, cu.cvr_number,
                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))


@router.put("/contacts/{contact_id}")
async def update_contact(contact_id: int, contact_data: ContactUpdate):
    """Update a contact"""
    try:
        # Ensure contact exists
        contact = execute_query("SELECT id FROM contacts WHERE id = %s", (contact_id,))
        if not contact:
            raise HTTPException(status_code=404, detail="Contact not found")
        
        # Build update query dynamically
        update_fields = []
        params = []
        
        for field, value in contact_data.model_dump(exclude_unset=True).items():
            update_fields.append(f"{field} = %s")
            params.append(value)
        
        if not update_fields:
            # No fields to update
            return await get_contact(contact_id)
        
        params.append(contact_id)
        
        update_query = f"""
            UPDATE contacts
            SET {', '.join(update_fields)}, updated_at = NOW()
            WHERE id = %s
            RETURNING id
        """
        
        execute_query(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.post("/contacts/{contact_id}/companies")
async def link_contact_to_company(contact_id: int, link: ContactCompanyLink):
    """Link a contact to a company"""
    try:
        # Ensure contact exists
        contact = execute_query("SELECT id FROM contacts WHERE id = %s", (contact_id,))
        if not contact:
            raise HTTPException(status_code=404, detail="Contact not found")

        # Ensure customer exists
        customer = execute_query("SELECT id FROM customers WHERE id = %s", (link.customer_id,))
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")

        query = """
            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 = EXCLUDED.is_primary, role = EXCLUDED.role
            RETURNING id
        """
        execute_insert(query, (contact_id, link.customer_id, link.is_primary, link.role))

        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.post("/contacts/admin/backfill-company-links")
async def backfill_contact_company_links(dry_run: bool = Query(default=True)):
    """
    Backfill missing contact_companies links by matching contacts.user_company to customers.name.

    - Uses case-insensitive trimmed exact name matching
    - Picks lowest customer ID if duplicate customer names exist
    - Idempotent: will not create duplicate links
    """
    try:
        # Contacts that have a company name on the contact row.
        contacts_with_company = execute_query_single(
            """
            SELECT COUNT(*)::int AS count
            FROM contacts c
            WHERE c.user_company IS NOT NULL
              AND TRIM(c.user_company) <> ''
            """
        )

        # Contacts where the company name can be matched to a customer record.
        matchable = execute_query_single(
            """
            WITH company_match AS (
                SELECT LOWER(TRIM(name)) AS norm_name, MIN(id) AS customer_id
                FROM customers
                GROUP BY LOWER(TRIM(name))
            )
            SELECT COUNT(DISTINCT c.id)::int AS count
            FROM contacts c
            JOIN company_match cm ON LOWER(TRIM(c.user_company)) = cm.norm_name
            WHERE c.user_company IS NOT NULL
              AND TRIM(c.user_company) <> ''
            """
        )

        # Contacts with no links at all (often the primary symptom).
        unlinked = execute_query_single(
            """
            SELECT COUNT(*)::int AS count
            FROM contacts c
            WHERE c.user_company IS NOT NULL
              AND TRIM(c.user_company) <> ''
              AND NOT EXISTS (
                  SELECT 1 FROM contact_companies cc WHERE cc.contact_id = c.id
              )
            """
        )

        if dry_run:
            return {
                "dry_run": True,
                "contacts_with_user_company": (contacts_with_company or {}).get("count", 0),
                "matchable_contacts": (matchable or {}).get("count", 0),
                "unlinked_contacts": (unlinked or {}).get("count", 0),
                "message": "Dry run complete. Re-run with dry_run=false to insert links.",
            }

        inserted = execute_query(
            """
            WITH company_match AS (
                SELECT LOWER(TRIM(name)) AS norm_name, MIN(id) AS customer_id
                FROM customers
                GROUP BY LOWER(TRIM(name))
            ),
            candidates AS (
                SELECT
                    c.id AS contact_id,
                    cm.customer_id,
                    CASE
                        WHEN EXISTS (
                            SELECT 1 FROM contact_companies cc1
                            WHERE cc1.contact_id = c.id
                        ) THEN FALSE
                        ELSE TRUE
                    END AS is_primary
                FROM contacts c
                JOIN company_match cm ON LOWER(TRIM(c.user_company)) = cm.norm_name
                WHERE c.user_company IS NOT NULL
                  AND TRIM(c.user_company) <> ''
            )
            INSERT INTO contact_companies (contact_id, customer_id, is_primary, role)
            SELECT contact_id, customer_id, is_primary, 'inferred_user_company'
            FROM candidates c
            WHERE NOT EXISTS (
                SELECT 1
                FROM contact_companies cc
                WHERE cc.contact_id = c.contact_id
                  AND cc.customer_id = c.customer_id
            )
            RETURNING contact_id, customer_id, is_primary
            """
        )

        inserted_count = len(inserted or [])
        logger.info("✅ Contact-company backfill inserted %s link(s)", inserted_count)

        return {
            "dry_run": False,
            "inserted": inserted_count,
            "sample": (inserted or [])[:20],
            "message": "Backfill completed",
        }
    except Exception as e:
        logger.error("Failed backfill_contact_company_links: %s", e, exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/contacts/{contact_id}/related-contacts")
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}/cases")
async def get_contact_cases(contact_id: int):
    """Get cases linked directly to a contact and cases from the contact's primary company."""
    try:
        contact_row = execute_query(
            """
            SELECT
                c.id,
                (
                    SELECT cu.id
                    FROM contact_companies cc
                    JOIN customers cu ON cu.id = cc.customer_id
                    WHERE cc.contact_id = c.id
                    ORDER BY cc.is_primary DESC NULLS LAST, cc.id ASC
                    LIMIT 1
                ) AS company_id,
                (
                    SELECT cu.name
                    FROM contact_companies cc
                    JOIN customers cu ON cu.id = cc.customer_id
                    WHERE cc.contact_id = c.id
                    ORDER BY cc.is_primary DESC NULLS LAST, cc.id ASC
                    LIMIT 1
                ) AS company_name
            FROM contacts c
            WHERE c.id = %s
            """,
            (contact_id,),
        )

        if not contact_row:
            raise HTTPException(status_code=404, detail="Contact not found")

        company_id = contact_row[0].get("company_id")

        contact_cases = execute_query(
            """
            SELECT
                s.id,
                s.titel,
                s.status,
                s.customer_id,
                cu.name AS customer_name,
                s.created_at,
                s.updated_at
            FROM sag_sager s
            INNER JOIN sag_kontakter sk ON s.id = sk.sag_id
            LEFT JOIN customers cu ON cu.id = s.customer_id
            WHERE sk.contact_id = %s
              AND s.deleted_at IS NULL
              AND sk.deleted_at IS NULL
            ORDER BY COALESCE(s.updated_at, s.created_at) DESC
            LIMIT 10
            """,
            (contact_id,),
        ) or []

        company_cases = []
        if company_id:
            company_cases = execute_query(
                """
                SELECT
                    s.id,
                    s.titel,
                    s.status,
                    s.customer_id,
                    cu.name AS customer_name,
                    s.created_at,
                    s.updated_at
                FROM sag_sager s
                LEFT JOIN customers cu ON cu.id = s.customer_id
                WHERE s.customer_id = %s
                  AND s.deleted_at IS NULL
                ORDER BY COALESCE(s.updated_at, s.created_at) DESC
                LIMIT 10
                """,
                (company_id,),
            ) or []

        return {
            "contact": {
                "id": contact_row[0]["id"],
                "company_id": company_id,
                "company_name": contact_row[0].get("company_name"),
            },
            "contact_cases": contact_cases,
            "company_cases": company_cases,
        }

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


@router.get("/contacts/{contact_id}/case-context")
async def get_contact_case_context(contact_id: int):
    """Get case suggestions for a contact: contact cases, company cases and related contacts."""
    try:
        contact_rows = execute_query(
            """
            SELECT
                c.id,
                c.first_name,
                c.last_name,
                c.email,
                c.phone,
                c.mobile,
                c.title,
                c.department,
                c.is_active,
                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
            LEFT JOIN contact_companies cc ON c.id = cc.contact_id
            LEFT JOIN customers cu ON cc.customer_id = cu.id
            WHERE 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.created_at, c.updated_at
            """,
            (contact_id,),
        ) or []
        if not contact_rows:
            return {"contact_cases": [], "company_cases": [], "related_contacts": []}

        customer_ids = get_contact_customer_ids(contact_id)
        placeholders = ",".join(["%s"] * len(customer_ids)) if customer_ids else ""

        contact_cases = execute_query(
            """
            SELECT
                s.id,
                s.titel,
                s.status,
                s.customer_id,
                cu.name AS customer_name,
                s.created_at,
                s.updated_at
            FROM sag_sager s
            INNER JOIN sag_kontakter sk ON s.id = sk.sag_id
            LEFT JOIN customers cu ON cu.id = s.customer_id
            WHERE sk.contact_id = %s
              AND s.deleted_at IS NULL
              AND sk.deleted_at IS NULL
            ORDER BY COALESCE(s.updated_at, s.created_at) DESC
            LIMIT 10
            """,
            (contact_id,),
        ) or []

        company_cases = []
        related_contacts = []
        if customer_ids:
            company_cases = execute_query(
                f"""
                SELECT
                    s.id,
                    s.titel,
                    s.status,
                    s.customer_id,
                    cu.name AS customer_name,
                    s.created_at,
                    s.updated_at
                FROM sag_sager s
                LEFT JOIN customers cu ON cu.id = s.customer_id
                WHERE s.customer_id IN ({placeholders})
                  AND s.deleted_at IS NULL
                ORDER BY COALESCE(s.updated_at, s.created_at) DESC
                LIMIT 10
                """,
                tuple(customer_ids),
            ) or []

            related_contacts = execute_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.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
                  AND c.is_active = TRUE
                GROUP BY c.id, c.first_name, c.last_name, c.email, c.phone, c.mobile, c.title, c.department, c.is_active, c.created_at, c.updated_at
                ORDER BY c.last_name, c.first_name
                LIMIT 10
                """,
                tuple(customer_ids + [contact_id]),
            ) or []

        return {
            "contact_cases": contact_cases,
            "company_cases": company_cases,
            "related_contacts": related_contacts,
        }
    except Exception as e:
        logger.error(f"Failed to get case context for contact {contact_id}: {e}", exc_info=True)
        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)


@router.get("/contacts/{contact_id}/kontakt")
async def get_contact_kontakt_history(contact_id: int, limit: int = Query(default=200, ge=1, le=1000)):
    try:
        exists = execute_query("SELECT id FROM contacts WHERE id = %s", (contact_id,))
        if not exists:
            raise HTTPException(status_code=404, detail="Contact not found")

        query = """
            SELECT * FROM (
                SELECT
                    'call' AS type,
                    t.id::text AS event_id,
                    t.started_at AS happened_at,
                    t.direction,
                    t.ekstern_nummer AS number,
                    NULL::text AS message,
                    t.duration_sec,
                    COALESCE(u.full_name, u.username) AS user_name,
                    NULL::text AS sms_status
                FROM telefoni_opkald t
                LEFT JOIN users u ON u.user_id = t.bruger_id
                WHERE t.kontakt_id = %s

                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,
                    s.status AS sms_status
                FROM sms_messages s
                LEFT JOIN users u ON u.user_id = s.bruger_id
                WHERE s.kontakt_id = %s
            ) z
            ORDER BY z.happened_at DESC NULLS LAST
            LIMIT %s
        """

        rows = execute_query(query, (contact_id, contact_id, limit)) or []
        return {"items": rows}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to fetch kontakt history for contact {contact_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))
