from fastapi import APIRouter, Depends, HTTPException, Query
from typing import List, Dict
from pydantic import BaseModel, Field
from datetime import datetime, date, timedelta
from app.db import database
from typing import Optional

router = APIRouter()

# Database Collections
PROJECTS_COLLECTION = "projects"
VISITORS_COLLECTION = "visitors"
VISITS_COLLECTION = "visits"
INTERACTIONS_COLLECTION = "interactions"
GOALS_COLLECTION = "goals"
CHATS_COLLECTION ="chats"

class GraphData(BaseModel):
    date: str  # ISO formatted string
    interactions: int
    visitors: int

class ResponseGraphData(BaseModel):
    date: str  # ISO formatted string
    responses: int

class DashboardMetrics(BaseModel):
    active_projects: int
    total_interactions: int
    total_visitors: int
    total_visits: int
    total_goals: int
    graph_data: List[GraphData]
    daily_responses: List[ResponseGraphData]

@router.get("/{account_id}/", response_model=DashboardMetrics)
async def get_dashboard_overview(
    account_id: str, 
    from_date: date = Query(..., alias='from'), 
    to_date: date = Query(..., alias='to'), 
    project_id: Optional[str] = Query(None, alias='project_id'), 
    db: database.MongoDB = Depends(database.get_mongo_db)
):
    try:
        from_datetime = datetime.combine(from_date, datetime.min.time())
        to_datetime = datetime.combine(to_date, datetime.max.time())
        
        # Common query filter
        base_filter = {"account_id": account_id}
        if project_id:
            base_filter["project_id"] = project_id

        # Adjust filters for string/date fields
        date_filter = {"$gte": from_datetime.isoformat(), "$lte": to_datetime.isoformat()}
        datetime_filter = {"$gte": from_datetime, "$lte": to_datetime}

        # Active projects count
        projects_filter = {**base_filter, "created_date": datetime_filter}
        active_projects_count = db[PROJECTS_COLLECTION].count_documents(projects_filter)

        # Total interactions count
        interactions_filter = {**base_filter, "timestamp": datetime_filter}
        total_interactions_count = db[INTERACTIONS_COLLECTION].count_documents(interactions_filter)
        
        if project_id:
            # Total goals count
            goals_filter = {"project_id": project_id}
            goals_filter = {**goals_filter, "timestamp": datetime_filter}
            total_goals_count = db[GOALS_COLLECTION].count_documents(goals_filter)
        else:
            total_goals_count = 0

        # Total visitors count
        visitors_filter = {**base_filter, "first_visited_datetime": datetime_filter}
        total_visitors_count = db[VISITORS_COLLECTION].count_documents(visitors_filter)

        # Total visits count
        visits_filter = {**base_filter, "visit_date": datetime_filter}
        total_visits_count = db[VISITS_COLLECTION].count_documents(visits_filter)

        # Count of messages from chats collection where sender is 'system'
        system_messages_filter = {
            **base_filter,
            "type": "system",
            "timestamp": datetime_filter  # Assuming the timestamp field to compare the date
        }
        total_system_messages_count = db[CHATS_COLLECTION].count_documents(system_messages_filter)

        # Graph data
        graph_data = []
        current_date = from_datetime
        while current_date <= to_datetime:
            next_date = current_date + timedelta(days=1)
            day_interactions_filter = {**base_filter, "timestamp": {"$gte": current_date, "$lt": next_date}}
            day_visitors_filter = {**base_filter, "first_visited_datetime": {"$gte": current_date, "$lt": next_date}}
            interactions_count = db[INTERACTIONS_COLLECTION].count_documents(day_interactions_filter)
            visitors_count = db[VISITORS_COLLECTION].count_documents(day_visitors_filter)
            graph_data.append(GraphData(date=current_date.date().isoformat(), interactions=interactions_count, visitors=visitors_count))
            current_date = next_date

        daily_responses = []
        # Loop over each day in the date range
        current_date = from_datetime
        while current_date <= to_datetime:
            next_date = current_date + timedelta(days=1)
            # Filter for system messages within the current day
            system_messages_filter = {
                **base_filter,
                "type": "system",  # Adjust to match documents where type is 'system'
                "timestamp": {"$gte": current_date, "$lt": next_date}  # Filter documents for the current day
            }
            # Count the number of system messages for the current day
            responses_count = db[CHATS_COLLECTION].count_documents(system_messages_filter)

            # Append the count and the date to the list
            daily_responses.append(ResponseGraphData(date= current_date.date().isoformat(),responses= responses_count))

            # Move to the next day
            current_date = next_date

        return DashboardMetrics(
            active_projects=active_projects_count,
            total_interactions=total_interactions_count,
            total_goals=total_goals_count,
            total_visitors=total_visitors_count,
            total_visits=total_visits_count,
            total_system_messages=total_system_messages_count,
            graph_data=graph_data,
            daily_responses=daily_responses,
        )
    except Exception as e:
        print(e)
        raise HTTPException(status_code=500, detail=str(e))
