from datetime import date, timedelta
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
from pydantic import BaseModel

from database import get_db
from models.user import User
from models.calendar_events import CalendarEvent
from auth import get_current_user, require_cap

router = APIRouter()


# Pydantic schemas
class CalendarEventCreate(BaseModel):
    event_date: date
    event_type: str  # reminder, event, note
    title: str
    description: str | None = None


class CalendarEventUpdate(BaseModel):
    event_date: date | None = None
    event_type: str | None = None
    title: str | None = None
    description: str | None = None


class CalendarEventResponse(BaseModel):
    id: int
    event_date: date
    event_type: str
    title: str
    description: str | None
    created_at: str

    class Config:
        from_attributes = True


# Endpoints
@router.get("/")
async def list_events(
    from_date: Optional[date] = None,
    to_date: Optional[date] = None,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> list[CalendarEventResponse]:
    """List events for date range"""
    query = select(CalendarEvent).where(
        CalendarEvent.kitchen_id == current_user.kitchen_id
    )

    if from_date:
        query = query.where(CalendarEvent.event_date >= from_date)
    if to_date:
        query = query.where(CalendarEvent.event_date <= to_date)

    query = query.order_by(CalendarEvent.event_date, CalendarEvent.created_at)
    result = await db.execute(query)
    events = result.scalars().all()

    return [
        CalendarEventResponse(
            id=e.id,
            event_date=e.event_date,
            event_type=e.event_type,
            title=e.title,
            description=e.description,
            created_at=e.created_at.isoformat()
        )
        for e in events
    ]


@router.get("/{date}")
async def get_events_for_date(
    date: date,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> list[CalendarEventResponse]:
    """Get all events for a specific date"""
    result = await db.execute(
        select(CalendarEvent).where(
            and_(
                CalendarEvent.kitchen_id == current_user.kitchen_id,
                CalendarEvent.event_date == date
            )
        ).order_by(CalendarEvent.created_at)
    )
    events = result.scalars().all()

    return [
        CalendarEventResponse(
            id=e.id,
            event_date=e.event_date,
            event_type=e.event_type,
            title=e.title,
            description=e.description,
            created_at=e.created_at.isoformat()
        )
        for e in events
    ]


@router.post("/")
async def create_event(
    event: CalendarEventCreate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
) -> CalendarEventResponse:
    """Create new event"""
    new_event = CalendarEvent(
        kitchen_id=current_user.kitchen_id,
        event_date=event.event_date,
        event_type=event.event_type,
        title=event.title,
        description=event.description,
        created_by=current_user.id
    )
    db.add(new_event)
    await db.commit()
    await db.refresh(new_event)

    return CalendarEventResponse(
        id=new_event.id,
        event_date=new_event.event_date,
        event_type=new_event.event_type,
        title=new_event.title,
        description=new_event.description,
        created_at=new_event.created_at.isoformat()
    )


@router.put("/{id}")
async def update_event(
    id: int,
    update: CalendarEventUpdate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
):
    """Update existing event"""
    result = await db.execute(
        select(CalendarEvent).where(
            and_(
                CalendarEvent.id == id,
                CalendarEvent.kitchen_id == current_user.kitchen_id
            )
        )
    )
    event = result.scalar_one_or_none()

    if not event:
        raise HTTPException(status_code=404, detail="Event not found")

    if update.event_date is not None:
        event.event_date = update.event_date
    if update.event_type is not None:
        event.event_type = update.event_type
    if update.title is not None:
        event.title = update.title
    if update.description is not None:
        event.description = update.description

    await db.commit()
    await db.refresh(event)

    return CalendarEventResponse(
        id=event.id,
        event_date=event.event_date,
        event_type=event.event_type,
        title=event.title,
        description=event.description,
        created_at=event.created_at.isoformat()
    )


@router.delete("/{id}")
async def delete_event(
    id: int,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
):
    """Delete event"""
    result = await db.execute(
        select(CalendarEvent).where(
            and_(
                CalendarEvent.id == id,
                CalendarEvent.kitchen_id == current_user.kitchen_id
            )
        )
    )
    event = result.scalar_one_or_none()

    if not event:
        raise HTTPException(status_code=404, detail="Event not found")

    await db.delete(event)
    await db.commit()

    return {"message": "Event deleted"}


@router.get("/dashboard/upcoming")
async def get_upcoming_events(
    limit: int = 3,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db)
):
    """Get next N upcoming events for dashboard widget"""
    today = date.today()

    result = await db.execute(
        select(CalendarEvent).where(
            and_(
                CalendarEvent.kitchen_id == current_user.kitchen_id,
                CalendarEvent.event_date >= today
            )
        ).order_by(CalendarEvent.event_date, CalendarEvent.created_at).limit(limit)
    )
    events = result.scalars().all()

    return {
        "total_count": len(events),
        "upcoming_events": [
            {
                "id": e.id,
                "event_date": e.event_date.isoformat(),
                "event_type": e.event_type,
                "title": e.title
            }
            for e in events
        ]
    }
