import logging
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_transactional_session
from app.auth import current_active_user
from app.models import User as UserModel, Expense as ExpenseModel
from app.schemas.cost import ListCostSummary, GroupBalanceSummary
from app.schemas.expense import ExpensePublic
from app.services import costs_service
from app.core.exceptions import (
    ListNotFoundError, 
    ListPermissionError, 
    GroupNotFoundError, 
    GroupPermissionError,
    InvalidOperationError
)

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


@router.get(
    "/lists/{list_id}/cost-summary",
    response_model=ListCostSummary,
    summary="Get Cost Summary for a List",
    tags=["Costs"],
    responses={
        status.HTTP_403_FORBIDDEN: {"description": "User does not have permission to access this list"},
        status.HTTP_404_NOT_FOUND: {"description": "List not found"},
    },
)
async def get_list_cost_summary(
    list_id: int,
    db: AsyncSession = Depends(get_transactional_session),
    current_user: UserModel = Depends(current_active_user),
):
    """
    Retrieves a calculated cost summary for a specific list.
    If an expense has been generated for this list, the summary will be based on that.
    Otherwise, it will be a basic summary of item prices.
    This endpoint is idempotent and does not create any data.
    """
    logger.info(f"User {current_user.email} requesting cost summary for list {list_id}")
    try:
        return await costs_service.get_list_cost_summary_logic(
            db=db, list_id=list_id, current_user_id=current_user.id
        )
    except ListPermissionError as e:
        logger.warning(f"Permission denied for user {current_user.email} on list {list_id}: {str(e)}")
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
    except ListNotFoundError as e:
        logger.warning(f"List {list_id} not found when getting cost summary: {str(e)}")
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))


@router.post(
    "/lists/{list_id}/cost-summary",
    response_model=ExpensePublic,
    status_code=status.HTTP_201_CREATED,
    summary="Generate and Get Expense from List Summary",
    tags=["Costs"],
    responses={
        status.HTTP_403_FORBIDDEN: {"description": "User does not have permission to access this list"},
        status.HTTP_404_NOT_FOUND: {"description": "List not found"},
        status.HTTP_400_BAD_REQUEST: {"description": "Invalid operation (e.g., no items to expense, or expense already exists)"},
    },
)
async def generate_expense_from_list_summary(
    list_id: int,
    db: AsyncSession = Depends(get_transactional_session),
    current_user: UserModel = Depends(current_active_user),
):
    """
    Creates an ITEM_BASED expense from the items in a given list.
    This should be called to finalize the costs for a shopping list and turn it into a formal expense.
    It will fail if an expense for this list already exists.
    """
    logger.info(f"User {current_user.email} requesting to generate expense from list {list_id}")
    try:
        expense = await costs_service.generate_expense_from_list_logic(
            db=db, list_id=list_id, current_user_id=current_user.id
        )
        return expense
    except (ListPermissionError, GroupPermissionError) as e:
        logger.warning(f"Permission denied for user {current_user.email} on list {list_id}: {str(e)}")
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
    except (ListNotFoundError, GroupNotFoundError) as e:
        logger.warning(f"Resource not found for list {list_id}: {str(e)}")
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
    except InvalidOperationError as e:
        logger.warning(f"Invalid operation for list {list_id}: {str(e)}")
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))


@router.get(
    "/groups/{group_id}/balance-summary",
    response_model=GroupBalanceSummary,
    summary="Get Detailed Balance Summary for a Group",
    tags=["Costs", "Groups"],
    responses={
        status.HTTP_403_FORBIDDEN: {"description": "User does not have permission to access this group"},
        status.HTTP_404_NOT_FOUND: {"description": "Group not found"},
    },
)
async def get_group_balance_summary(
    group_id: int,
    db: AsyncSession = Depends(get_transactional_session),
    current_user: UserModel = Depends(current_active_user),
):
    """
    Retrieves a detailed financial balance summary for all users within a specific group.
    It considers all expenses, their splits, and all settlements recorded for the group.
    The user must be a member of the group to view its balance summary.
    """
    logger.info(f"User {current_user.email} requesting balance summary for group {group_id}")
    try:
        return await costs_service.get_group_balance_summary_logic(
            db=db, group_id=group_id, current_user_id=current_user.id
        )
    except GroupPermissionError as e:
        logger.warning(f"Permission denied for user {current_user.email} on group {group_id}: {str(e)}")
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=str(e))
    except GroupNotFoundError as e:
        logger.warning(f"Group {group_id} not found when getting balance summary: {str(e)}")
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e)) 