from sqlalchemy.orm import Session
from src.marketing.apps.Calendar.model import Calendar 
from src.marketing.apps.Calendar import schema
from src.utils.db import get_db
from fastapi import HTTPException,status
from src.marketing.apps.Calendar import utils
from typing import List
from sqlalchemy.orm import joinedload
from src.marketing.apps.Account.model import ConnectedAccount
from src.marketing.apps.post.model import CalendarPost
from fastapi.responses import JSONResponse
import pytz


# Create a new calendar
def create_calendar(db: Session, calendar_data: schema.CalendarCreate) -> schema.CalendarOut:
    
    slug = calendar_data.name.lower().replace(" ", "-")
    unique_slug = utils.generate_unique_slug(db, slug)
    if not unique_slug:
        raise ValueError("Failed to generate a unique slug")
    
    calendar = Calendar(**calendar_data.model_dump( exclude={"slug"}), slug=unique_slug)

    db.add(calendar)
    db.commit()
    db.refresh(calendar)
    return schema.CalendarOut.model_validate(calendar)



#---------------------------------------------------------------------------------------------------------------------------------
# Get a calendar by branch_id

def get_calendar_by_branch_id(
    db: Session,
    branch_id: int,
    show_connected_accounts: bool = False,
    show_posts: bool = False,
    show_post_types: bool = False
) -> List[schema.CalendarOut]:
    try:
        query = db.query(Calendar).filter(
            Calendar.branch_id == branch_id,
            Calendar.is_deleted == False
        )

        # Conditional relationship loading
        if show_connected_accounts:
            query = query.options(joinedload(Calendar.connected_accounts))

        if show_posts:
            if show_post_types:
                query = query.options(
                    joinedload(Calendar.posts).joinedload(CalendarPost.post_types)
                )
            else:
                query = query.options(joinedload(Calendar.posts))
    

        calendars = query.all()

        if not branch_id:
            raise HTTPException(
            status_code=400,
            detail={
                "success": False,
                "message": "Branch ID is required",
                "data": []
            }
        )

        # return [schema.CalendarOut.model_validate(calendar) for calendar in calendars]
        calendar_outputs = []

        for calendar in calendars:
            calendar_out = schema.CalendarOut.model_validate(calendar)

            # Remove connected_accounts if not requested
            if not show_connected_accounts and hasattr(calendar_out, "connected_accounts"):
                calendar_out.connected_accounts = []

            # Remove posts if not requested
            if not show_posts and hasattr(calendar_out, "posts"):
                calendar_out.posts = []

            # Strip post_types if not requested
            if not show_post_types and calendar_out.posts:
                for post in calendar_out.posts:
                    post.post_types = []

            calendar_outputs.append(calendar_out)

        return calendar_outputs 


    except HTTPException as e:
        raise e
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "success": False,
                "message": str(e),
                "data": []
            }
        )
    

#---------------------------------------------------------------------------------------------------------------------------------


# Update a calendar
def update_calendar(db: Session, calendar_id: int, calendar_data: schema.CalendarUpdate) -> schema.CalendarOut:
    calendar = db.query(Calendar).filter(Calendar.id == calendar_id, Calendar.is_deleted == False).first()
    # if not calendar:
    #     raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Calendar not found")
    if not calendar:
        return None
          
    update_data = calendar_data.model_dump(exclude_unset=True)

    # If name is updated, regenerate slug
    if "name" in update_data:
        new_slug_base = update_data["name"].lower().replace(" ", "-")
        unique_slug = utils.generate_unique_slug(db, new_slug_base)
        if not unique_slug:
            raise ValueError("Failed to generate a unique slug")
        update_data["slug"] = unique_slug

    for key, value in update_data.items():
        setattr(calendar, key, value)

    db.commit()
    db.refresh(calendar)
    return schema.CalendarOut.model_validate(calendar)


def get_calendar_by_id(db: Session, calendar_id: int) -> schema.CalendarOut:
    calendar = db.query(Calendar).filter(Calendar.id == calendar_id, Calendar.is_deleted==False).first()
    
    if not calendar:
        return None
    return schema.CalendarOut.model_validate(calendar)

# Delete a calendar
def delete_calendar(db: Session, calendar_id: int) -> None:
    calendar = db.query(Calendar).filter(Calendar.id == calendar_id).first()
    if not calendar:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Calendar not found")
    
    calendar.is_deleted = True
    db.commit()


#Get all timezones
def get_all_timezones() -> List[str]:
    """Get all available timezones from pytz."""
    return pytz.all_timezones 
