# app/routers/agent.py

import resend
from sqlalchemy import select, join
from app.models.agent import *
from app.models.visitor import *
from app.core.database import get_db
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi import APIRouter, Depends, HTTPException, Query
from app.services.agent import register_agent, login_agent
from app.schemas.agent import *
from app.utils.util import *

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

# ---------------------
# Load Resend API KEY
# ---------------------
resend.api_key = os.getenv("RESEND_API_KEY")

# ------------------------------
# Get All Agents
# ------------------------------
@router.get("/")
async def get_agents(
    db: AsyncSession = Depends(get_db),
    limit: int = Query(10, ge=1),
    offset: int = Query(0, ge=0)
):

    # 1️⃣ Total count (no pagination)
    total_result = await db.execute(select(func.count(Agent.id)))
    total = total_result.scalar() or 0

    # 2️⃣ Paginated query
    result = await db.execute(
        select(
            Agent.id,
            Agent.name,
            Agent.email,
            Agent.is_online,
            Agent.last_seen_at
        )
        .limit(limit)
        .offset(offset)
    )

    rows = result.all()

    agents = [
        {
            "id": r[0],
            "name": r[1],
            "email": r[2],
            "is_online": r[3],
            "last_seen_at": r[4]
        }
        for r in rows
    ]

    return {
        "agents": agents,
        "total": total,
        "limit": limit,
        "offset": offset,
        "has_more": offset + limit < total
    }



@router.post("/register", response_model=AgentOut)
async def register_agent_api( data: AgentCreate, db: AsyncSession = Depends(get_db) ):
    try:
        agent = await register_agent(db, data)
        return agent
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/login", response_model=AgentOut)
async def login_agent_api( data: AgentLogin, db: AsyncSession = Depends(get_db)):
    agent = await login_agent(db, data)
    if not agent:
        raise HTTPException(status_code=401, detail="Invalid credentials")
    return agent


@router.get("/me/{agent_id}", response_model=AgentOut)
async def get_agent_me( agent_id: int, db: AsyncSession = Depends(get_db) ):
    result = await db.execute(select(Agent).where(Agent.id == agent_id))
    agent = result.scalar_one_or_none()
    if not agent:
        raise HTTPException(status_code=404, detail="Agent not found")
    return agent

# ------------------------------------
# UPDATE AGENT INFO (Change Password)
# ------------------------------------
@router.put("/update/{agent_id}")
async def update_agent( agent_id: int, data: AgentUpdate, db: AsyncSession = Depends(get_db) ):
    
    # Fetch agent
    result = await db.execute(select(Agent).where(Agent.id == agent_id))
    agent = result.scalar_one_or_none()

    if not agent:
        raise HTTPException(status_code=404, detail="Agent not found")

    updated = False

    # Update name
    if data.name and data.name != agent.name:
        agent.name = data.name
        updated = True

    # Password update
    if data.current_password or data.new_password:

        # Must send both
        if not data.current_password or not data.new_password:
            raise HTTPException(
                status_code=400,
                detail="Both current_password and new_password are required"
            )

        if data.current_password != agent.password_hash:
            raise HTTPException(status_code=400, detail="Current password incorrect")

        agent.password_hash = data.new_password
        updated = True

    if not updated:
        return {"message": "No changes applied"}

    await db.commit()
    await db.refresh(agent)

    return {
        "id": agent.id,
        "name": agent.name,
        "email": agent.email
    }


# --------------------------------------------
# FORGOT PASSWORD API FOR AGENT
# --------------------------------------------
@router.post("/forgot-password")
async def forgot_password(payload: ForgotPasswordRequest, db: AsyncSession = Depends(get_db)):

    stmt = select(Agent).where(Agent.email == payload.email)
    result = await db.execute(stmt)
    agent = result.scalar_one_or_none()

    if not agent:
        raise HTTPException(status_code=404, detail="Please Provide Valid Email ID")

    # Create reset token
    reset_token = create_reset_token(agent.id)

    # Frontend reset-password page link
    reset_link = f"{payload.frontend_url}/reset-password?token={reset_token}"

    # Send email with Resend
    try:
        
        email = resend.Emails.send({
            "from": "onboarding@resend.dev",
            "to": agent.email,
            "subject": "Reset Your Password",
            "html": f"""
                <p>Hello {agent.name},</p>
                <p>You requested a password reset. Click below link:</p>
                <p><a href="{reset_link}" target="_blank">Reset Password</a></p>
                <p>If you did not request this, ignore this email.</p>
            """
        })

        print(" >>>email>>> ", email)

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Email sending failed: {str(e)}")

    return {
        "message": "Password reset link sent to email",
        "reset_token": reset_token,  # Remove later for production
        "reset_link": reset_link
    }


# --------------------------------------------
# RESET PASSWORD API FOR AGENT
# --------------------------------------------
@router.post("/reset-password")
async def reset_password(
    payload: ResetPasswordRequest,
    db: AsyncSession = Depends(get_db)
):
    # Validate token
    agent_id = verify_reset_token(payload.token)

    if not agent_id:
        raise HTTPException(status_code=400, detail="Invalid or expired token")

    # Fetch agent
    stmt = select(Agent).where(Agent.id == agent_id)
    result = await db.execute(stmt)
    agent = result.scalar_one_or_none()

    if not agent:
        raise HTTPException(status_code=404, detail="Agent not found")

    # Update password (should be hashed ideally)
    agent.password_hash = payload.new_password

    await db.commit()

    return {"message": "Password reset successfully"}


# ------------------------------------
# GET ASSIGNMENT HISTORY OF AGENT
# ------------------------------------

# @router.get("/assignments/{agent_id}", response_model=list[AssignmentHistoryResponse])
# async def get_agent_assignment_history(
#     agent_id: int,
#     db: AsyncSession = Depends(get_db),
#     limit: int = Query(10, ge=1, le=100),
#     offset: int = Query(0, ge=0)
# ):  
#     query = (
#         select(
#             AgentAssignmentHistory.id,
#             AgentAssignmentHistory.agent_id,       
#             Visitor.id.label("visitor_id"),
#             Visitor.visitor_id.label("visitor_name"),
#             AgentAssignmentHistory.started_at,
#             AgentAssignmentHistory.ended_at
#         )
#         .join(Visitor, AgentAssignmentHistory.visitor_id == Visitor.id)
#         .where(AgentAssignmentHistory.agent_id == agent_id)
#         .order_by(AgentAssignmentHistory.started_at.desc())
#         .limit(limit)
#         .offset(offset)
#     )

#     result = await db.execute(query)
#     rows = result.fetchall()

#     return [dict(row._mapping) for row in rows]

@router.get("/assignments/{agent_id}")
async def get_agent_assignment_history(
    agent_id: int,
    db: AsyncSession = Depends(get_db),
    limit: int = Query(10, ge=1),
    offset: int = Query(0, ge=0)
):
    
    query = (
        select(
            AgentAssignmentHistory.id,
            AgentAssignmentHistory.agent_id,
            Visitor.id.label("visitor_id"),
            Visitor.visitor_id.label("visitor_name"),
            AgentAssignmentHistory.started_at,
            AgentAssignmentHistory.ended_at
        )
        .join(Visitor, AgentAssignmentHistory.visitor_id == Visitor.id)
        .where(AgentAssignmentHistory.agent_id == agent_id)
        .order_by(AgentAssignmentHistory.started_at.desc())
        .limit(limit)
        .offset(offset)
    )

    result = await db.execute(query)
    assignments = [dict(row._mapping) for row in result.fetchall()]

    # --- Get total count ---
    count_query = select(func.count()).select_from(AgentAssignmentHistory).where(
        AgentAssignmentHistory.agent_id == agent_id
    )
    total = (await db.execute(count_query)).scalar()

    return {
        "assignments": assignments,
        "total": total
    }
