from typing import Any, Optional, Tuple, List
from datetime import datetime

from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.user import User
from app.models.material_cost import MaterialCost
from app.models.user_oauth import UserOAuth


async def get_consumption_list(
    db: AsyncSession,
    page: int = 1,
    page_size: int = 20,
    advertiser_id: Optional[str] = None,
    user_id: Optional[str] = None,
    consume_date: Optional[List[str]] = None,
    current_user: Optional[User] = None,
) -> Tuple[List[MaterialCost], int]:
    offset = (page - 1) * page_size
    
    query = select(MaterialCost).where(MaterialCost.deleted_at.is_(None))
    
    if current_user:
        query = query.join(
            UserOAuth,
            MaterialCost.oauth_id == UserOAuth.id,
        ).where(
            UserOAuth.user_id == current_user.id,
            UserOAuth.deleted_at.is_(None),
        )
    
    if user_id:
        query = query.join(
            UserOAuth,
            MaterialCost.oauth_id == UserOAuth.id,
        ).where(UserOAuth.user_id == user_id)
    
    if advertiser_id:
        query = query.where(MaterialCost.advertiser_id == advertiser_id)
    
    if consume_date and len(consume_date) >= 2:
        start_date_obj = datetime.strptime(consume_date[0], "%Y-%m-%d").date()
        end_date_obj = datetime.strptime(consume_date[1], "%Y-%m-%d").date()
        query = query.where(MaterialCost.consume_date >= start_date_obj)
        query = query.where(MaterialCost.consume_date <= end_date_obj)
    
    result = await db.execute(
        query.order_by(MaterialCost.consume_date.desc())
        .offset(offset)
        .limit(page_size)
    )
    consumptions = result.scalars().all()
    
    count_query = select(func.count(MaterialCost.id)).where(MaterialCost.deleted_at.is_(None))
    
    if current_user:
        count_query = count_query.join(
            UserOAuth,
            MaterialCost.oauth_id == UserOAuth.id,
        ).where(
            UserOAuth.user_id == current_user.id,
            UserOAuth.deleted_at.is_(None),
        )
    
    if user_id:
        count_query = count_query.join(
            UserOAuth,
            MaterialCost.oauth_id == UserOAuth.id,
        ).where(UserOAuth.user_id == user_id)
    
    if advertiser_id:
        count_query = count_query.where(MaterialCost.advertiser_id == advertiser_id)
    
    if consume_date and len(consume_date) >= 2:
        start_date_obj = datetime.strptime(consume_date[0], "%Y-%m-%d").date()
        end_date_obj = datetime.strptime(consume_date[1], "%Y-%m-%d").date()
        count_query = count_query.where(MaterialCost.consume_date >= start_date_obj)
        count_query = count_query.where(MaterialCost.consume_date <= end_date_obj)
    
    total_result = await db.execute(count_query)
    total = total_result.scalar_one()
    
    return consumptions, total


def format_consumption_response(consumptions: List[MaterialCost], include_oauth_id: bool = False) -> List[dict]:
    result = []
    for consumption in consumptions:
        item = {
            "id": consumption.id,
            "advertiser_id": consumption.advertiser_id,
            "material_id": consumption.material_id,
            "consume_date": consumption.consume_date.isoformat() if consumption.consume_date else None,
            "stat_cost": consumption.stat_cost,
            "show_cnt": consumption.show_cnt,
            "cpm_platform": consumption.cpm_platform,
            "click_cnt": consumption.click_cnt,
            "ctr": consumption.ctr,
            "cpc_platform": consumption.cpc_platform,
            "convert_cnt": consumption.convert_cnt,
            "conversion_cost": consumption.conversion_cost,
            "conversion_rate": consumption.conversion_rate,
            "deep_convert_cnt": consumption.deep_convert_cnt,
            "deep_convert_cost": consumption.deep_convert_cost,
            "deep_convert_rate": consumption.deep_convert_rate,
            "active": consumption.active,
            "active_cost": consumption.active_cost,
            "active_rate": consumption.active_rate,
            "active_register": consumption.active_register,
            "active_register_cost": consumption.active_register_cost,
            "active_register_rate": consumption.active_register_rate,
            "attribution_next_day_open_cnt": consumption.attribution_next_day_open_cnt,
            "attribution_next_day_open_cost": consumption.attribution_next_day_open_cost,
            "attribution_next_day_open_rate": consumption.attribution_next_day_open_rate,
            "active_pay": consumption.active_pay,
            "active_pay_cost": consumption.active_pay_cost,
            "active_pay_rate": consumption.active_pay_rate,
            "phone": consumption.phone,
            "form": consumption.form,
            "download_start": consumption.download_start,
            "form_submit": consumption.form_submit,
            "button": consumption.button,
            "view": consumption.view,
            "message": consumption.message,
            "consult": consumption.consult,
            "consult_effective": consumption.consult_effective,
            "shopping": consumption.shopping,
            "customer_effective": consumption.customer_effective,
            "attribution_game_in_app_ltv_1day": consumption.attribution_game_in_app_ltv_1day,
            "attribution_game_in_app_roi_1day": consumption.attribution_game_in_app_roi_1day,
            "loan_completion": consumption.loan_completion,
            "loan_completion_cost": consumption.loan_completion_cost,
            "loan_completion_rate": consumption.loan_completion_rate,
            "loan_credit": consumption.loan_credit,
            "loan_credit_cost": consumption.loan_credit_cost,
            "loan_credit_rate": consumption.loan_credit_rate,
            "in_app_order_gmv": consumption.in_app_order_gmv,
            "in_app_order_roi": consumption.in_app_order_roi,
            "in_app_pay_gmv": consumption.in_app_pay_gmv,
            "in_app_pay_roi": consumption.in_app_pay_roi,
            "total_play": consumption.total_play,
            "valid_play": consumption.valid_play,
            "valid_play_cost": consumption.valid_play_cost,
            "valid_play_rate": consumption.valid_play_rate,
            "valid_play_of_mille": consumption.valid_play_of_mille,
            "valid_play_cost_of_mille": consumption.valid_play_cost_of_mille,
            "average_play_time_per_play": consumption.average_play_time_per_play,
            "play_over_rate": consumption.play_over_rate,
            "dy_like": consumption.dy_like,
            "dy_comment": consumption.dy_comment,
            "dy_share": consumption.dy_share,
            "report_cnt": consumption.report_cnt,
            "created_at": consumption.created_at,
        }
        if include_oauth_id:
            item["oauth_id"] = consumption.oauth_id
        result.append(item)
    return result