from fastapi import APIRouter, HTTPException
from app.core.database import execute_query
from typing import List, Optional, Dict, Any
from pydantic import BaseModel
from datetime import datetime, date
import logging

logger = logging.getLogger(__name__)

router = APIRouter()

# Pydantic Models
class PrepaidCard(BaseModel):
    id: Optional[int] = None
    card_number: str
    customer_id: int
    purchased_hours: float
    used_hours: float
    remaining_hours: float
    price_per_hour: float
    total_amount: float
    status: str
    purchased_at: Optional[datetime] = None
    expires_at: Optional[datetime] = None
    economic_invoice_number: Optional[str] = None
    economic_product_number: Optional[str] = None
    notes: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

class PrepaidCardCreate(BaseModel):
    customer_id: int
    purchased_hours: float
    price_per_hour: float
    expires_at: Optional[date] = None
    notes: Optional[str] = None


@router.get("/prepaid-cards", response_model=List[Dict[str, Any]])
async def get_prepaid_cards(status: Optional[str] = None, customer_id: Optional[int] = None):
    """
    Get all prepaid cards with customer information
    """
    try:
        query = """
            SELECT 
                pc.*,
                c.name as customer_name,
                c.email as customer_email,
                (SELECT COUNT(*) FROM tticket_prepaid_transactions WHERE card_id = pc.id) as transaction_count
            FROM tticket_prepaid_cards pc
            LEFT JOIN customers c ON pc.customer_id = c.id
            WHERE 1=1
        """
        params = []
        
        if status:
            query += " AND pc.status = %s"
            params.append(status)
            
        if customer_id:
            query += " AND pc.customer_id = %s"
            params.append(customer_id)
            
        query += " ORDER BY pc.created_at DESC"
        
        cards = execute_query(query, tuple(params) if params else None)
        logger.info(f"✅ Retrieved {len(cards) if cards else 0} prepaid cards")
        return cards or []
        
    except Exception as e:
        logger.error(f"❌ Error fetching prepaid cards: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/prepaid-cards/{card_id}", response_model=Dict[str, Any])
async def get_prepaid_card(card_id: int):
    """
    Get a specific prepaid card with transactions
    """
    try:
        result = execute_query("""
            SELECT 
                pc.*,
                c.name as customer_name,
                c.email as customer_email
            FROM tticket_prepaid_cards pc
            LEFT JOIN customers c ON pc.customer_id = c.id
            WHERE pc.id = %s
        """, (card_id,))
        
        if not result or len(result) == 0:
            raise HTTPException(status_code=404, detail="Prepaid card not found")
        
        card = result[0]
            
        # Get transactions
        transactions = execute_query("""
            SELECT 
                pt.*,
                w.ticket_id,
                t.subject as ticket_title
            FROM tticket_prepaid_transactions pt
            LEFT JOIN tticket_worklog w ON pt.worklog_id = w.id
            LEFT JOIN tticket_tickets t ON w.ticket_id = t.id
            WHERE pt.card_id = %s
            ORDER BY pt.created_at DESC
        """, (card_id,))
        
        card['transactions'] = transactions or []
        
        return card
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error fetching prepaid card {card_id}: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/prepaid-cards", response_model=Dict[str, Any])
async def create_prepaid_card(card: PrepaidCardCreate):
    """
    Create a new prepaid card
    """
    try:
        # Calculate total amount
        total_amount = card.purchased_hours * card.price_per_hour
        
        # Check if customer already has active card
        existing = execute_query("""
            SELECT id FROM tticket_prepaid_cards 
            WHERE customer_id = %s AND status = 'active'
        """, (card.customer_id,))
        
        if existing and len(existing) > 0:
            raise HTTPException(
                status_code=400, 
                detail="Customer already has an active prepaid card"
            )
        
        # Create card (need to use fetch=False for INSERT RETURNING)
        conn = None
        try:
            from app.core.database import get_db_connection, release_db_connection
            from psycopg2.extras import RealDictCursor
            
            conn = get_db_connection()
            with conn.cursor(cursor_factory=RealDictCursor) as cursor:
                cursor.execute("""
                    INSERT INTO tticket_prepaid_cards 
                    (customer_id, purchased_hours, price_per_hour, total_amount, expires_at, notes)
                    VALUES (%s, %s, %s, %s, %s, %s)
                    RETURNING *
                """, (
                    card.customer_id,
                    card.purchased_hours,
                    card.price_per_hour,
                    total_amount,
                    card.expires_at,
                    card.notes
                ))
                conn.commit()
                result = cursor.fetchone()
                
                logger.info(f"✅ Created prepaid card: {result['card_number']}")
                return result
        finally:
            if conn:
                release_db_connection(conn)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error creating prepaid card: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/prepaid-cards/{card_id}/status")
async def update_card_status(card_id: int, status: str):
    """
    Update prepaid card status (cancel, reactivate)
    """
    try:
        if status not in ['active', 'cancelled']:
            raise HTTPException(status_code=400, detail="Invalid status")
        
        conn = None
        try:
            from app.core.database import get_db_connection, release_db_connection
            from psycopg2.extras import RealDictCursor
            
            conn = get_db_connection()
            with conn.cursor(cursor_factory=RealDictCursor) as cursor:
                cursor.execute("""
                    UPDATE tticket_prepaid_cards 
                    SET status = %s
                    WHERE id = %s
                    RETURNING *
                """, (status, card_id))
                conn.commit()
                result = cursor.fetchone()
                
                if not result:
                    raise HTTPException(status_code=404, detail="Card not found")
                
                logger.info(f"✅ Updated card {card_id} status to {status}")
                return result
        finally:
            if conn:
                release_db_connection(conn)
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error updating card status: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/prepaid-cards/{card_id}")
async def delete_prepaid_card(card_id: int):
    """
    Delete a prepaid card (only if no transactions)
    """
    try:
        # Check for transactions
        transactions = execute_query("""
            SELECT COUNT(*) as count FROM tticket_prepaid_transactions 
            WHERE card_id = %s
        """, (card_id,))
        
        if transactions and len(transactions) > 0 and transactions[0]['count'] > 0:
            raise HTTPException(
                status_code=400, 
                detail="Cannot delete card with transactions"
            )
        
        execute_query("DELETE FROM tticket_prepaid_cards WHERE id = %s", (card_id,), fetch=False)
        
        logger.info(f"✅ Deleted prepaid card {card_id}")
        return {"message": "Card deleted successfully"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ Error deleting card: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/prepaid-cards/stats/summary", response_model=Dict[str, Any])
async def get_prepaid_stats():
    """
    Get prepaid cards statistics
    """
    try:
        result = execute_query("""
            SELECT 
                COUNT(*) FILTER (WHERE status = 'active') as active_count,
                COUNT(*) FILTER (WHERE status = 'depleted') as depleted_count,
                COUNT(*) FILTER (WHERE status = 'expired') as expired_count,
                COUNT(*) FILTER (WHERE status = 'cancelled') as cancelled_count,
                COALESCE(SUM(remaining_hours) FILTER (WHERE status = 'active'), 0) as total_remaining_hours,
                COALESCE(SUM(used_hours), 0) as total_used_hours,
                COALESCE(SUM(purchased_hours), 0) as total_purchased_hours,
                COALESCE(SUM(total_amount), 0) as total_revenue
            FROM tticket_prepaid_cards
        """)
        
        return result[0] if result and len(result) > 0 else {}
        
    except Exception as e:
        logger.error(f"❌ Error fetching prepaid stats: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))
