"""
Main API Router for Time Tracking Module
=========================================

Samler alle endpoints for modulet.
Isoleret routing uden påvirkning af existing Hub endpoints.
"""

import logging
from typing import Optional, List, Dict, Any

from fastapi import APIRouter, HTTPException, Depends, Body
from fastapi.responses import JSONResponse

from app.core.database import execute_query, execute_update, execute_query_single
from app.timetracking.backend.models import (
    TModuleSyncStats,
    TModuleApprovalStats,
    TModuleWizardNextEntry,
    TModuleWizardProgress,
    TModuleTimeApproval,
    TModuleTimeWithContext,
    TModuleOrder,
    TModuleOrderWithLines,
    TModuleEconomicExportRequest,
    TModuleEconomicExportResult,
    TModuleMetadata,
    TModuleUninstallRequest,
    TModuleUninstallResult,
    TModuleBulkRateUpdate
)
from app.timetracking.backend.vtiger_sync import vtiger_service
from app.timetracking.backend.wizard import wizard
from app.timetracking.backend.order_service import order_service
from app.timetracking.backend.economic_export import economic_service
from app.timetracking.backend.audit import audit

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/timetracking")


# ============================================================================
# SYNC ENDPOINTS
# ============================================================================

@router.post("/sync", response_model=TModuleSyncStats, tags=["Sync"])
async def sync_from_vtiger(
    user_id: Optional[int] = None,
    fetch_comments: bool = False
):
    """
    🔍 Synkroniser data fra vTiger (READ-ONLY).
    
    Henter:
    - Accounts (kunder)
    - HelpDesk (cases)
    - ModComments (tidsregistreringer)
    
    Gemmes i tmodule_* tabeller (isoleret).
    
    Args:
        user_id: ID på bruger der kører sync
        fetch_comments: Hent også interne kommentarer (langsomt - ~0.4s pr case)
    """
    try:
        logger.info("🚀 Starting vTiger sync...")
        result = await vtiger_service.full_sync(user_id=user_id, fetch_comments=fetch_comments)
        
        # Auto-link customers after sync to update links based on fresh vTiger data
        logger.info("🔗 Auto-linking customers after sync...")
        try:
            link_query = "SELECT * FROM link_tmodule_customers_to_hub()"
            link_results = execute_query(link_query)
            logger.info(f"✅ Linked {len(link_results)} customers automatically")
        except Exception as link_error:
            logger.warning(f"⚠️ Customer linking failed (non-critical): {link_error}")
        
        return result
    except Exception as e:
        logger.error(f"❌ Sync failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/sync/case/{case_id}/comments", tags=["Sync"])
async def sync_case_comments(case_id: int):
    """
    🔍 Synkroniser kommentarer for en specifik case fra vTiger.
    
    Bruges til on-demand opdatering når man ser på en case i wizard.
    """
    try:
        # Hent case fra database
        case = execute_query_single(
            "SELECT vtiger_id FROM tmodule_cases WHERE id = %s",
            (case_id,))
        
        if not case:
            raise HTTPException(status_code=404, detail="Case not found")
        
        # Sync comments
        result = await vtiger_service.sync_case_comments(case['vtiger_id'])
        
        if not result['success']:
            raise HTTPException(status_code=500, detail=result.get('error', 'Failed to sync comments'))
        
        return result
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Failed to sync comments for case {case_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/sync/test-connection", tags=["Sync"])
async def test_vtiger_connection():
    """Test forbindelse til vTiger"""
    try:
        is_connected = await vtiger_service.test_connection()
        return {
            "connected": is_connected,
            "service": "vTiger CRM",
            "read_only": vtiger_service.read_only,
            "dry_run": vtiger_service.dry_run
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/sync/manual-link-customer", tags=["Sync"])
async def manual_link_customer(tmodule_customer_id: int, hub_customer_id: int):
    """
    🔗 Manually link en tmodule_customer til en Hub customer.
    
    Brug dette når auto-linking fejler pga. navn-forskelle eller andre edge cases.
    """
    try:
        logger.info(f"🔗 Manual linking tmodule {tmodule_customer_id} → Hub {hub_customer_id}")
        
        # Get Hub customer's economic number
        hub_query = "SELECT economic_customer_number FROM customers WHERE id = %s"
        hub_result = execute_query(hub_query, (hub_customer_id,))
        
        if not hub_result:
            raise HTTPException(status_code=404, detail=f"Hub customer {hub_customer_id} not found")
        
        economic_number = hub_result[0]['economic_customer_number']
        
        # Update tmodule_customer
        update_query = """
            UPDATE tmodule_customers 
            SET hub_customer_id = %s,
                economic_customer_number = %s,
                updated_at = NOW()
            WHERE id = %s
            RETURNING id, name, hub_customer_id, economic_customer_number
        """
        
        result = execute_query(update_query, (hub_customer_id, economic_number, tmodule_customer_id))
        
        if not result:
            raise HTTPException(status_code=404, detail=f"tmodule_customer {tmodule_customer_id} not found")
        
        logger.info(f"✅ Manual link complete: {result[0]}")
        
        return {
            "success": True,
            "linked_customer": result[0]
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Manual linking failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/sync/relink-customers", tags=["Sync"])
async def relink_customers():
    """
    🔗 Re-link alle tmodule_customers til Hub customers.
    
    Bruger linking funktion der prioriterer:
    1. economic_customer_number match (mest præcis)
    2. Navn match (fallback)
    
    Kør efter vTiger sync for at opdatere kunde-links baseret på
    nyeste data fra vTiger (cf_854 economic numbers).
    """
    try:
        logger.info("🔗 Starting customer re-linking...")
        
        # Call database function
        query = "SELECT * FROM link_tmodule_customers_to_hub()"
        results = execute_query(query)
        
        # Count by action type
        stats = {
            "economic_matches": 0,
            "name_matches": 0,
            "total_linked": len(results)
        }
        
        for result in results:
            if result['action'] == 'economic_number_match':
                stats["economic_matches"] += 1
            elif result['action'] == 'name_match':
                stats["name_matches"] += 1
        
        logger.info(f"✅ Customer linking complete: {stats}")
        
        return {
            "success": True,
            "stats": stats,
            "linked_customers": results
        }
        
    except Exception as e:
        logger.error(f"❌ Customer linking failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/debug/raw-stats", tags=["Debug"])
async def get_debug_raw_stats():
    """
    🔍 DEBUG: Vis rå statistik fra databasen uden filtering.
    
    Bruges til at diagnosticere hvorfor timelogs ikke vises.
    """
    try:
        # Total counts without any filtering
        total_query = """
            SELECT 
                (SELECT COUNT(*) FROM tmodule_customers) as total_customers,
                (SELECT COUNT(*) FROM tmodule_cases) as total_cases,
                (SELECT COUNT(*) FROM tmodule_times) as total_times,
                (SELECT COUNT(*) FROM tmodule_times WHERE billable = true) as billable_times,
                (SELECT COUNT(*) FROM tmodule_times WHERE status = 'pending') as pending_times,
                (SELECT COUNT(*) FROM tmodule_times WHERE vtiger_data->>'cf_timelog_invoiced' = '0') as not_invoiced_times,
                (SELECT COUNT(*) FROM tmodule_times WHERE vtiger_data->>'cf_timelog_invoiced' IS NULL) as null_invoiced_times,
                (SELECT COUNT(*) FROM tmodule_times WHERE billable = true AND status = 'pending') as billable_pending,
                (SELECT COUNT(*) FROM tmodule_times WHERE billable = true AND status = 'pending' AND vtiger_data->>'cf_timelog_invoiced' = '0') as filtered_pending
        """
        totals = execute_query_single(total_query)
        
        # Sample timelogs to see actual data
        sample_query = """
            SELECT 
                id, vtiger_id, description, worked_date, original_hours, 
                status, billable,
                vtiger_data->>'cf_timelog_invoiced' as cf_timelog_invoiced,
                vtiger_data->>'isbillable' as is_billable_field,
                customer_id, case_id
            FROM tmodule_times 
            ORDER BY worked_date DESC
            LIMIT 10
        """
        samples = execute_query(sample_query)
        
        # Check what invoice statuses actually exist
        invoice_status_query = """
            SELECT 
                vtiger_data->>'cf_timelog_invoiced' as invoice_status,
                COUNT(*) as count
            FROM tmodule_times
            GROUP BY vtiger_data->>'cf_timelog_invoiced'
            ORDER BY count DESC
        """
        invoice_statuses = execute_query(invoice_status_query)
        
        return {
            "totals": totals,
            "sample_timelogs": samples,
            "invoice_statuses": invoice_statuses,
            "explanation": {
                "issue": "If not_invoiced_times is 0 but total_times > 0, then the cf_timelog_invoiced field is not '0' in vTiger",
                "solution": "The SQL views filter on cf_timelog_invoiced = '0' but vTiger might use different values",
                "check": "Look at invoice_statuses to see what values actually exist"
            }
        }
    except Exception as e:
        logger.error(f"❌ Debug query failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ============================================================================
# WIZARD / APPROVAL ENDPOINTS
# ============================================================================

@router.get("/wizard/stats", response_model=List[TModuleApprovalStats], tags=["Wizard"])
async def get_all_customer_stats():
    """Hent approval statistik for alle kunder"""
    try:
        return wizard.get_all_customers_stats()
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/wizard/next", response_model=TModuleWizardNextEntry, tags=["Wizard"])
async def get_next_pending_entry(
    customer_id: Optional[int] = None,
    exclude_time_card: bool = True
):
    """
    Hent næste pending tidsregistrering til godkendelse.
    
    Query params:
    - customer_id: Filtrer til specifik kunde (optional)
    - exclude_time_card: Ekskluder klippekort-kunder (default: true)
    """
    try:
        return wizard.get_next_pending_entry(
            customer_id=customer_id,
            exclude_time_card=exclude_time_card
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/wizard/approve/{time_id}", response_model=TModuleTimeWithContext, tags=["Wizard"])
async def approve_time_entry(
    time_id: int,
    request: Dict[str, Any] = Body(...),
    user_id: Optional[int] = None
):
    """
    Godkend en tidsregistrering.
    
    Path params:
    - time_id: ID på tidsregistreringen
    
    Body:
    - billable_hours: Timer efter godkendelse (optional)
    - hourly_rate: Timepris i DKK (optional)
    - is_travel: True hvis kørsel (optional)
    - approval_note: Godkendelsesnote (optional)
    - rounding_method: "up", "down", "nearest" (optional)
    """
    try:
        from app.core.config import settings
        from decimal import Decimal
        
        # Hent timelog
        query = """
            SELECT t.*, c.title as case_title, c.status as case_status,
                   cust.name as customer_name, cust.hourly_rate as customer_rate
            FROM tmodule_times t
            JOIN tmodule_cases c ON t.case_id = c.id
            JOIN tmodule_customers cust ON t.customer_id = cust.id
            WHERE t.id = %s
        """
        entry = execute_query_single(query, (time_id,))
        
        if not entry:
            raise HTTPException(status_code=404, detail="Time entry not found")
        
        # Beregn approved_hours
        billable_hours = request.get('billable_hours')
        rounding_method = request.get('rounding_method')
        
        if billable_hours is None:
            approved_hours = Decimal(str(entry['original_hours']))
            
            # Auto-afrund hvis enabled
            if settings.TIMETRACKING_AUTO_ROUND:
                increment = Decimal(str(settings.TIMETRACKING_ROUND_INCREMENT))
                method = rounding_method or settings.TIMETRACKING_ROUND_METHOD
                
                if method == "up":
                    approved_hours = (approved_hours / increment).quantize(Decimal('1'), rounding='ROUND_UP') * increment
                elif method == "down":
                    approved_hours = (approved_hours / increment).quantize(Decimal('1'), rounding='ROUND_DOWN') * increment
                else:
                    approved_hours = (approved_hours / increment).quantize(Decimal('1'), rounding='ROUND_HALF_UP') * increment
                
                rounded_to = increment
            else:
                rounded_to = None
        else:
            approved_hours = Decimal(str(billable_hours))
            rounded_to = None
        
        # Opdater med hourly_rate hvis angivet
        hourly_rate = request.get('hourly_rate')
        if hourly_rate is not None:
            execute_update(
                "UPDATE tmodule_times SET hourly_rate = %s WHERE id = %s",
                (Decimal(str(hourly_rate)), time_id)
            )
        
        # Godkend med alle felter
        logger.info(f"🔍 Creating approval for time_id={time_id}: approved_hours={approved_hours}, rounded_to={rounded_to}, is_travel={request.get('is_travel', False)}")
        
        approval = TModuleTimeApproval(
            time_id=time_id,
            approved_hours=approved_hours,
            rounded_to=rounded_to,
            approval_note=request.get('approval_note'),
            billable=True,  # Default til fakturerbar
            is_travel=request.get('is_travel', False)
        )
        
        logger.info(f"✅ Approval object created successfully")
        return wizard.approve_time_entry(approval, user_id=user_id)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error approving entry {time_id}: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/wizard/reject/{time_id}", response_model=TModuleTimeWithContext, tags=["Wizard"])
async def reject_time_entry(
    time_id: int,
    reason: Optional[str] = None,
    user_id: Optional[int] = None
):
    """Afvis en tidsregistrering"""
    try:
        return wizard.reject_time_entry(time_id, reason=reason, user_id=user_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/wizard/reset/{time_id}", response_model=TModuleTimeWithContext, tags=["Wizard"])
async def reset_to_pending(
    time_id: int,
    reason: Optional[str] = None,
    user_id: Optional[int] = None
):
    """
    Nulstil en godkendt/afvist tidsregistrering tilbage til pending.
    
    Query params:
    - reason: Årsag til nulstilling (optional)
    - user_id: ID på brugeren der nulstiller (optional)
    """
    try:
        return wizard.reset_to_pending(time_id, reason=reason, user_id=user_id)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Reset failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/wizard/case/{case_id}/entries", response_model=List[TModuleTimeWithContext], tags=["Wizard"])
async def get_case_entries(
    case_id: int,
    exclude_time_card: bool = True
):
    """
    Hent alle pending timelogs for en case.
    
    Bruges til at vise alle tidsregistreringer i samme case grupperet.
    """
    try:
        return wizard.get_case_entries(case_id, exclude_time_card=exclude_time_card)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/wizard/case/{case_id}/details", tags=["Wizard"])
async def get_case_details(case_id: int):
    """
    Hent komplet case information inkl. alle timelogs og kommentarer.
    
    Returnerer:
    - case_id, case_title, case_description, case_status
    - timelogs: ALLE tidsregistreringer (pending, approved, rejected)
    - case_comments: Kommentarer fra vTiger
    """
    try:
        return wizard.get_case_details(case_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/wizard/case/{case_id}/approve-all", tags=["Wizard"])
async def approve_all_case_entries(
    case_id: int,
    user_id: Optional[int] = None,
    exclude_time_card: bool = True
):
    """
    Bulk-godkend alle pending timelogs for en case.
    
    Afr under automatisk efter configured settings.
    """
    try:
        return wizard.approve_case_entries(
            case_id=case_id,
            user_id=user_id,
            exclude_time_card=exclude_time_card
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/wizard/progress/{customer_id}", response_model=TModuleWizardProgress, tags=["Wizard"])
async def get_customer_progress(customer_id: int):
    """Hent wizard progress for en kunde"""
    try:
        return wizard.get_customer_progress(customer_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# ============================================================================
# ORDER ENDPOINTS
# ============================================================================

@router.post("/orders/generate/{customer_id}", response_model=TModuleOrderWithLines, tags=["Orders"])
async def generate_order(customer_id: int, user_id: Optional[int] = None):
    """
    Generer ordre for alle godkendte tider for en kunde.
    
    Aggregerer:
    - Alle godkendte tidsregistreringer
    - Grupperet efter case
    - Beregner totals med moms
    
    Markerer tidsregistreringer som 'billed'.
    """
    try:
        return order_service.generate_order_for_customer(customer_id, user_id=user_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/orders", response_model=List[TModuleOrder], tags=["Orders"])
async def list_orders(
    customer_id: Optional[int] = None,
    status: Optional[str] = None,
    limit: int = 100
):
    """
    List ordrer med filtrering.
    
    Query params:
    - customer_id: Filtrer til specifik kunde
    - status: Filtrer på status (draft, exported, sent, cancelled)
    - limit: Max antal resultater (default: 100)
    """
    try:
        return order_service.list_orders(
            customer_id=customer_id,
            status=status,
            limit=limit
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/orders/{order_id}", response_model=TModuleOrderWithLines, tags=["Orders"])
async def get_order(order_id: int):
    """Hent ordre med linjer"""
    try:
        return order_service.get_order_with_lines(order_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/orders/{order_id}/cancel", response_model=TModuleOrder, tags=["Orders"])
async def cancel_order(
    order_id: int,
    reason: Optional[str] = None,
    user_id: Optional[int] = None
):
    """
    Annuller en ordre.
    
    Kun muligt for draft orders (ikke exported).
    Resetter tidsregistreringer tilbage til 'approved'.
    """
    try:
        return order_service.cancel_order(order_id, reason=reason, user_id=user_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/orders/{order_id}/unlock", tags=["Orders"])
async def unlock_order(
    order_id: int,
    admin_code: str,
    user_id: Optional[int] = None
):
    """
    🔓 Lås en eksporteret ordre op for ændringer (ADMIN ONLY).
    
    Kræver:
    1. Korrekt admin unlock code (fra TIMETRACKING_ADMIN_UNLOCK_CODE)
    2. Ordren skal være slettet fra e-conomic først
    
    Query params:
    - admin_code: Admin unlock kode
    """
    try:
        from app.core.config import settings
        
        # Verify admin code
        if not settings.TIMETRACKING_ADMIN_UNLOCK_CODE:
            raise HTTPException(
                status_code=500,
                detail="Admin unlock code ikke konfigureret i systemet"
            )
        
        if admin_code != settings.TIMETRACKING_ADMIN_UNLOCK_CODE:
            logger.warning(f"⚠️ Ugyldig unlock code forsøg for ordre {order_id}")
            raise HTTPException(status_code=403, detail="Ugyldig admin kode")
        
        # Get order
        order = order_service.get_order_with_lines(order_id)
        
        if order.status != 'exported':
            raise HTTPException(
                status_code=400,
                detail="Kun eksporterede ordrer kan låses op"
            )
        
        if not order.economic_draft_id:
            raise HTTPException(
                status_code=400,
                detail="Ordre har ingen e-conomic ID"
            )
        
        # Check if order still exists in e-conomic
        try:
            draft_exists = await economic_service.check_draft_exists(order.economic_draft_id)
            
            if draft_exists:
                raise HTTPException(
                    status_code=400,
                    detail=f"⚠️ Ordren findes stadig i e-conomic (Draft #{order.economic_draft_id}). Slet den i e-conomic først!"
                )
        except Exception as e:
            logger.error(f"❌ Kunne ikke tjekke e-conomic status: {e}")
            raise HTTPException(
                status_code=500,
                detail=f"Kunne ikke verificere e-conomic status: {str(e)}"
            )
        
        # Unlock order - set status back to draft
        update_query = """
            UPDATE tmodule_orders
            SET status = 'draft',
                economic_draft_id = NULL,
                exported_at = NULL
            WHERE id = %s
            RETURNING *
        """
        
        result = execute_query_single(update_query, (order_id,))
        
        # Log unlock
        audit.log_event(
            event_type="order_unlocked",
            entity_type="order",
            entity_id=order_id,
            user_id=user_id,
            details={
                "previous_economic_id": order.economic_draft_id,
                "unlocked_by_admin": True
            }
        )
        
        logger.info(f"🔓 Order {order_id} unlocked by admin (user {user_id})")
        
        return {
            "success": True,
            "message": "Ordre låst op - kan nu redigeres eller slettes",
            "order_id": order_id
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Unlock failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ============================================================================
# e-conomic EXPORT ENDPOINTS
# ============================================================================

@router.post("/export", response_model=TModuleEconomicExportResult, tags=["Export"])
async def export_to_economic(
    request: TModuleEconomicExportRequest,
    user_id: Optional[int] = None
):
    """
    🚨 Eksporter ordre til e-conomic som draft order.
    
    SAFETY FLAGS:
    - TIMETRACKING_ECONOMIC_READ_ONLY (default: True)
    - TIMETRACKING_ECONOMIC_DRY_RUN (default: True)
    
    Hvis begge er enabled, køres kun dry-run simulation.
    
    Body:
    - order_id: ID på ordren
    - force: Re-eksporter selvom allerede eksporteret (default: false)
    """
    try:
        return await economic_service.export_order(request, user_id=user_id)
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/export/test-connection", tags=["Export"])
async def test_economic_connection():
    """Test forbindelse til e-conomic"""
    try:
        is_connected = await economic_service.test_connection()
        return {
            "connected": is_connected,
            "service": "e-conomic",
            "read_only": economic_service.read_only,
            "dry_run": economic_service.dry_run,
            "export_type": economic_service.export_type
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# ============================================================================
# MODULE METADATA & ADMIN ENDPOINTS
# ============================================================================

@router.get("/metadata", response_model=TModuleMetadata, tags=["Admin"])
async def get_module_metadata():
    """Hent modul metadata"""
    try:
        result = execute_query_single(
            "SELECT * FROM tmodule_metadata ORDER BY id DESC LIMIT 1")
        
        if not result:
            raise HTTPException(status_code=404, detail="Module metadata not found")
        
        return TModuleMetadata(**result)
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/health", tags=["Admin"])
async def module_health():
    """Module health check"""
    try:
        # Check database tables exist
        tables_query = """
            SELECT COUNT(*) as count FROM information_schema.tables 
            WHERE table_name LIKE 'tmodule_%'
        """
        result = execute_query_single(tables_query)
        table_count = result['count'] if result else 0
        
        # Get stats - count each table separately
        try:
            stats = {
                "customers": 0,
                "cases": 0,
                "times": 0,
                "orders": 0
            }
            
            for table_name in ["customers", "cases", "times", "orders"]:
                count_result = execute_query_single(
                    f"SELECT COUNT(*) as count FROM tmodule_{table_name}")
                stats[table_name] = count_result['count'] if count_result else 0
                
        except Exception as e:
            stats = {"error": str(e)}
        
        return {
            "status": "healthy" if table_count >= 6 else "degraded",
            "module": "Time Tracking & Billing",
            "version": "1.0.0",
            "tables": table_count,
            "statistics": stats,
            "safety": {
                "vtiger_read_only": vtiger_service.read_only,
                "vtiger_dry_run": vtiger_service.dry_run,
                "economic_read_only": economic_service.read_only,
                "economic_dry_run": economic_service.dry_run
            }
        }
    except Exception as e:
        logger.error(f"Health check error: {e}")
        return JSONResponse(
            status_code=500,
            content={"status": "error", "message": str(e)}
        )


@router.get("/config", tags=["Admin"])
async def get_config():
    """Hent modul konfiguration"""
    from app.core.config import settings
    
    return {
        "default_hourly_rate": float(settings.TIMETRACKING_DEFAULT_HOURLY_RATE),
        "auto_round": settings.TIMETRACKING_AUTO_ROUND,
        "round_increment": float(settings.TIMETRACKING_ROUND_INCREMENT),
        "round_method": settings.TIMETRACKING_ROUND_METHOD,
        "vtiger_read_only": settings.TIMETRACKING_VTIGER_READ_ONLY,
        "vtiger_dry_run": settings.TIMETRACKING_VTIGER_DRY_RUN,
        "economic_read_only": settings.TIMETRACKING_ECONOMIC_READ_ONLY,
        "economic_dry_run": settings.TIMETRACKING_ECONOMIC_DRY_RUN
    }


# ============================================================================
# CUSTOMER MANAGEMENT ENDPOINTS
# ============================================================================

@router.patch("/customers/{customer_id}/hourly-rate", tags=["Customers"])
async def update_customer_hourly_rate(customer_id: int, hourly_rate: float, user_id: Optional[int] = None):
    """
    Opdater timepris for en kunde.
    
    Args:
        customer_id: Kunde ID
        hourly_rate: Ny timepris i DKK (f.eks. 850.00)
    """
    try:
        from decimal import Decimal
        
        # Validate rate
        if hourly_rate < 0:
            raise HTTPException(status_code=400, detail="Hourly rate must be positive")
        
        rate_decimal = Decimal(str(hourly_rate))
        
        # Update customer hourly rate
        execute_update(
            "UPDATE tmodule_customers SET hourly_rate = %s, updated_at = CURRENT_TIMESTAMP WHERE id = %s",
            (rate_decimal, customer_id)
        )
        
        # Audit log
        audit.log_event(
            entity_type="customer",
            entity_id=str(customer_id),
            event_type="hourly_rate_updated",
            details={"hourly_rate": float(hourly_rate)},
            user_id=user_id
        )
        
        # Return updated customer
        customer = execute_query_single(
            "SELECT id, name, hourly_rate FROM tmodule_customers WHERE id = %s",
            (customer_id,))
        
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")
        
        return {
            "customer_id": customer_id,
            "name": customer['name'],
            "hourly_rate": float(customer['hourly_rate']) if customer['hourly_rate'] else None,
            "updated": True
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error updating hourly rate: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/customers/bulk-update-rate", tags=["Customers"])
async def bulk_update_customer_hourly_rates(
    request: TModuleBulkRateUpdate,
    user_id: Optional[int] = None
):
    """
    Opdater timepris for flere kunder på én gang.
    
    Request body:
        customer_ids: Liste af kunde-ID'er
        hourly_rate: Ny timepris i DKK (f.eks. 850.00)
    
    Returns:
        Antal opdaterede kunder
    """
    try:
        # Validate inputs (already validated by Pydantic)
        customer_ids = request.customer_ids
        rate_decimal = request.hourly_rate
        
        # Update all selected customers
        execute_update(
            "UPDATE tmodule_customers SET hourly_rate = %s, updated_at = CURRENT_TIMESTAMP WHERE id = ANY(%s)",
            (rate_decimal, customer_ids)
        )
        
        # Count affected rows
        updated_count = len(customer_ids)
        
        # Audit log for each customer
        for customer_id in customer_ids:
            audit.log_event(
                entity_type="customer",
                entity_id=str(customer_id),
                event_type="hourly_rate_updated",
                details={"hourly_rate": float(rate_decimal), "bulk_update": True},
                user_id=user_id
            )
        
        logger.info(f"✅ Bulk updated hourly rate for {updated_count} customers to {rate_decimal} DKK")
        
        return {
            "updated": updated_count,
            "hourly_rate": float(rate_decimal)
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error in bulk hourly rate update: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.patch("/customers/{customer_id}/time-card", tags=["Customers"])
async def toggle_customer_time_card(customer_id: int, enabled: bool, user_id: Optional[int] = None):
    """
    Skift klippekort-status for kunde.
    
    Klippekort-kunder faktureres eksternt og skal kunne skjules i godkendelsesflow.
    """
    try:
        # Update customer time card flag
        execute_update(
            "UPDATE tmodule_customers SET uses_time_card = %s, updated_at = CURRENT_TIMESTAMP WHERE id = %s",
            (enabled, customer_id)
        )
        
        # Audit log
        audit.log_event(
            entity_type="customer",
            entity_id=str(customer_id),
            event_type="time_card_toggled",
            details={"enabled": enabled},
            user_id=user_id
        )
        
        # Return updated customer
        customer = execute_query_single(
            "SELECT * FROM tmodule_customers WHERE id = %s",
            (customer_id,))
        
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")
        
        return {
            "customer_id": customer_id,
            "name": customer['name'],
            "uses_time_card": customer['uses_time_card'],
            "updated": True
        }
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error toggling time card: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/customers", tags=["Customers"])
async def list_customers(
    include_time_card: bool = True,
    only_with_entries: bool = False
):
    """
    List kunder med filtrering.
    
    Query params:
    - include_time_card: Inkluder klippekort-kunder (default: true)
    - only_with_entries: Kun kunder med pending tidsregistreringer (default: false)
    """
    try:
        if only_with_entries:
            # Use view that includes entry counts
            query = """
                SELECT customer_id, customer_name, customer_vtiger_id, uses_time_card,
                       total_entries, pending_count
                FROM tmodule_approval_stats
                WHERE total_entries > 0
            """
            
            if not include_time_card:
                query += " AND uses_time_card = false"
            
            query += " ORDER BY customer_name"
            
            customers = execute_query_single(query)
        else:
            # Simple customer list
            query = "SELECT * FROM tmodule_customers"
            
            if not include_time_card:
                query += " WHERE uses_time_card = false"
            
            query += " ORDER BY name"
            
            customers = execute_query(query)
        
        return {"customers": customers, "total": len(customers)}
            
    except Exception as e:
        logger.error(f"❌ Error listing customers: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/customers/{customer_id}/times", tags=["Customers"])
async def get_customer_time_entries(customer_id: int, status: Optional[str] = None):
    """
    Hent alle tidsregistreringer for en kunde.
    
    Path params:
    - customer_id: Kunde ID
    
    Query params:
    - status: Filtrer på status (pending, approved, rejected, billed)
    """
    try:
        query = """
            SELECT t.*,
                   COALESCE(c.vtiger_data->>'case_no', c.title)::VARCHAR(500) AS case_title,
                   c.vtiger_id AS case_vtiger_id,
                   c.description AS case_description,
                   cust.name AS customer_name
            FROM tmodule_times t
            LEFT JOIN tmodule_cases c ON t.case_id = c.id
            LEFT JOIN tmodule_customers cust ON t.customer_id = cust.id
            WHERE t.customer_id = %s
        """
        
        params = [customer_id]
        
        if status:
            query += " AND t.status = %s"
            params.append(status)
        
        query += " ORDER BY t.worked_date DESC, t.id DESC"
        
        times = execute_query(query, tuple(params))
        
        return {"times": times, "total": len(times)}
    
    except Exception as e:
        logger.error(f"Error fetching customer time entries: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/times/{time_id}", tags=["Times"])
async def get_time_entry(time_id: int):
    """
    Hent en specifik tidsregistrering.
    
    Path params:
    - time_id: Time entry ID
    """
    try:
        query = """
            SELECT t.*,
                   COALESCE(c.vtiger_data->>'case_no', c.title)::VARCHAR(500) AS case_title,
                   c.vtiger_id AS case_vtiger_id,
                   c.description AS case_description,
                   cust.name AS customer_name
            FROM tmodule_times t
            LEFT JOIN tmodule_cases c ON t.case_id = c.id
            LEFT JOIN tmodule_customers cust ON t.customer_id = cust.id
            WHERE t.id = %s
        """
        
        time_entry = execute_query_single(query, (time_id,))
        
        if not time_entry:
            raise HTTPException(status_code=404, detail="Time entry not found")
        
        return time_entry
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error fetching time entry {time_id}: {e}")
        raise HTTPException(status_code=500, detail=str(e))
        
    except Exception as e:
        logger.error(f"❌ Error getting customer time entries: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/admin/uninstall", response_model=TModuleUninstallResult, tags=["Admin"])
async def uninstall_module(
    request: TModuleUninstallRequest,
    user_id: Optional[int] = None
):
    """
    🚨 SLET MODULET FULDSTÆNDIGT.
    
    ADVARSEL: Dette sletter ALLE data i modulet!
    Kan ikke fortrydes.
    
    Body:
    - confirm: SKAL være true
    - delete_all_data: SKAL være true
    """
    try:
        # Validate request (Pydantic validators already check this)
        if not request.confirm or not request.delete_all_data:
            raise HTTPException(
                status_code=400,
                detail="You must confirm uninstall and data deletion"
            )
        
        logger.warning(f"⚠️ UNINSTALLING TIME TRACKING MODULE (user_id: {user_id})")
        
        # Log uninstall
        audit.log_module_uninstalled(user_id=user_id)
        
        # Execute DROP script
        uninstall_script = """
        DROP VIEW IF EXISTS tmodule_order_details CASCADE;
        DROP VIEW IF EXISTS tmodule_next_pending CASCADE;
        DROP VIEW IF EXISTS tmodule_approval_stats CASCADE;
        
        DROP TRIGGER IF EXISTS tmodule_orders_generate_number ON tmodule_orders;
        DROP TRIGGER IF EXISTS tmodule_orders_update ON tmodule_orders;
        DROP TRIGGER IF EXISTS tmodule_times_update ON tmodule_times;
        DROP TRIGGER IF EXISTS tmodule_cases_update ON tmodule_cases;
        DROP TRIGGER IF EXISTS tmodule_customers_update ON tmodule_customers;
        
        DROP FUNCTION IF EXISTS tmodule_generate_order_number() CASCADE;
        DROP FUNCTION IF EXISTS tmodule_update_timestamp() CASCADE;
        
        DROP TABLE IF EXISTS tmodule_sync_log CASCADE;
        DROP TABLE IF EXISTS tmodule_order_lines CASCADE;
        DROP TABLE IF EXISTS tmodule_orders CASCADE;
        DROP TABLE IF EXISTS tmodule_times CASCADE;
        DROP TABLE IF EXISTS tmodule_cases CASCADE;
        DROP TABLE IF EXISTS tmodule_customers CASCADE;
        DROP TABLE IF EXISTS tmodule_metadata CASCADE;
        """
        
        # Count rows before deletion
        try:
            count_query = """
                SELECT 
                    (SELECT COUNT(*) FROM tmodule_customers) +
                    (SELECT COUNT(*) FROM tmodule_cases) +
                    (SELECT COUNT(*) FROM tmodule_times) +
                    (SELECT COUNT(*) FROM tmodule_orders) +
                    (SELECT COUNT(*) FROM tmodule_order_lines) +
                    (SELECT COUNT(*) FROM tmodule_sync_log) as total
            """
            count_result = execute_query(count_query)
            total_rows = count_result['total'] if count_result else 0
        except:
            total_rows = 0
        
        # Execute uninstall (split into separate statements)
        from app.core.database import get_db_connection
        import psycopg2
        
        conn = get_db_connection()
        cursor = conn.cursor()
        
        dropped_items = {
            "views": [],
            "triggers": [],
            "functions": [],
            "tables": []
        }
        
        try:
            # Drop views
            for view in ["tmodule_order_details", "tmodule_next_pending", "tmodule_approval_stats"]:
                cursor.execute(f"DROP VIEW IF EXISTS {view} CASCADE")
                dropped_items["views"].append(view)
            
            # Drop triggers
            triggers = [
                ("tmodule_orders_generate_number", "tmodule_orders"),
                ("tmodule_orders_update", "tmodule_orders"),
                ("tmodule_times_update", "tmodule_times"),
                ("tmodule_cases_update", "tmodule_cases"),
                ("tmodule_customers_update", "tmodule_customers")
            ]
            for trigger_name, table_name in triggers:
                cursor.execute(f"DROP TRIGGER IF EXISTS {trigger_name} ON {table_name}")
                dropped_items["triggers"].append(trigger_name)
            
            # Drop functions
            for func in ["tmodule_generate_order_number", "tmodule_update_timestamp"]:
                cursor.execute(f"DROP FUNCTION IF EXISTS {func}() CASCADE")
                dropped_items["functions"].append(func)
            
            # Drop tables
            for table in [
                "tmodule_sync_log",
                "tmodule_order_lines",
                "tmodule_orders",
                "tmodule_times",
                "tmodule_cases",
                "tmodule_customers",
                "tmodule_metadata"
            ]:
                cursor.execute(f"DROP TABLE IF EXISTS {table} CASCADE")
                dropped_items["tables"].append(table)
            
            conn.commit()
            
            logger.warning(f"✅ Module uninstalled - deleted {total_rows} rows")
            
            return TModuleUninstallResult(
                success=True,
                message=f"Time Tracking Module successfully uninstalled. Deleted {total_rows} rows.",
                tables_dropped=dropped_items["tables"],
                views_dropped=dropped_items["views"],
                functions_dropped=dropped_items["functions"],
                rows_deleted=total_rows
            )
        
        except Exception as e:
            conn.rollback()
            raise e
        finally:
            cursor.close()
            conn.close()
    
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Uninstall failed: {e}")
        raise HTTPException(status_code=500, detail=str(e))
