from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session, select

from app.api.deps import get_session
from app.models.core import PostDraft, Provider, PublishJob, VideoAsset, now_utc
from app.services.upload_requests import create_existing_upload_request

router = APIRouter(prefix="/calendar", tags=["calendar"])


def slot_for(value: datetime | None) -> str:
    if not value:
        return "morning"
    hour = value.hour
    if hour < 11:
        return "morning"
    if hour < 15:
        return "noon"
    if hour < 20:
        return "evening"
    return "night"


@router.get("")
def calendar(session: Session = Depends(get_session)):
    drafts = session.exec(
        select(PostDraft).where(PostDraft.status == "scheduled", PostDraft.scheduled_at != None).order_by(PostDraft.scheduled_at)  # noqa: E711
    ).all()
    jobs = session.exec(select(PublishJob).where(PublishJob.status == "failed").order_by(PublishJob.created_at.desc())).all()
    items = []
    for draft in drafts:
        video = session.get(VideoAsset, draft.video_asset_id)
        if video and (video.status == "archived" or video.is_demo):
            continue
        items.append({
            "id": draft.id,
            "kind": "draft",
            "post_draft_id": draft.id,
            "video_asset_id": draft.video_asset_id,
            "title": draft.title or draft.caption or (video.working_title if video else "Prepared package"),
            "provider": draft.provider,
            "account": draft.platform_account_id,
            "status": draft.status,
            "scheduled_at": draft.scheduled_at,
            "slot": slot_for(draft.scheduled_at),
            "executor": "existing_jarvis_uploader" if draft.provider == Provider.youtube else "manual",
        })
    for job in jobs:
        draft = session.get(PostDraft, job.post_draft_id)
        video = session.get(VideoAsset, draft.video_asset_id) if draft else None
        if video and (video.status == "archived" or video.is_demo):
            continue
        items.append({
            "id": job.id,
            "kind": "upload_job",
            "post_draft_id": job.post_draft_id,
            "video_asset_id": draft.video_asset_id if draft else None,
            "title": draft.title or draft.caption or (video.working_title if video else "Upload job") if draft else "Upload job",
            "provider": job.provider,
            "account": draft.platform_account_id if draft else None,
            "status": job.status,
            "job_type": job.job_type,
            "scheduled_at": draft.scheduled_at if draft else None,
            "slot": slot_for(draft.scheduled_at if draft else None),
            "error_message": job.error_message,
            "executor": "existing_jarvis_uploader" if job.provider == Provider.youtube else "manual",
        })
    return {"items": items, "queue_slots": ["morning", "noon", "evening", "night"]}


def _draft(session: Session, post_draft_id: str) -> PostDraft:
    draft = session.get(PostDraft, post_draft_id)
    if not draft:
        raise HTTPException(status_code=404, detail="Post draft not found")
    return draft


@router.post("/{post_draft_id}/reschedule")
def reschedule(post_draft_id: str, payload: dict, session: Session = Depends(get_session)):
    draft = _draft(session, post_draft_id)
    draft.scheduled_at = datetime.fromisoformat(payload["scheduled_at"].replace("Z", "+00:00"))
    draft.status = "scheduled"
    draft.updated_at = now_utc()
    session.add(draft); session.commit(); session.refresh(draft)
    return {"ok": True, "post_draft_id": draft.id, "status": draft.status, "scheduled_at": draft.scheduled_at}


@router.post("/{post_draft_id}/cancel")
def cancel(post_draft_id: str, session: Session = Depends(get_session)):
    draft = _draft(session, post_draft_id)
    draft.status = "draft"
    draft.scheduled_at = None
    draft.updated_at = now_utc()
    session.add(draft); session.commit(); session.refresh(draft)
    return {"ok": True, "post_draft_id": draft.id, "status": draft.status}


@router.post("/{post_draft_id}/upload-now")
def upload_now(post_draft_id: str, payload: dict | None = None, session: Session = Depends(get_session)):
    draft = _draft(session, post_draft_id)
    if draft.provider != Provider.youtube:
        raise HTTPException(status_code=400, detail="Only YouTube drafts can be uploaded via Jarvis uploader")
    draft.scheduled_at = None
    draft.status = "upload_requested"
    draft.updated_at = now_utc()
    session.add(draft); session.commit()
    request = create_existing_upload_request(session, post_draft_id, payload or {"approval_text": "Creator approved scheduled private upload now."})
    return {"ok": True, "post_draft_id": post_draft_id, "upload_request": request}


@router.post("/{post_draft_id}/retry")
def retry(post_draft_id: str, session: Session = Depends(get_session)):
    return upload_now(post_draft_id, {"approval_text": "Creator requested retry via Calendar."}, session)
