"""
Client Router
"""
from fastapi import APIRouter, Depends, Request, Form, HTTPException
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from pathlib import Path

from ..models.models import User, Case, Appointment, Lawyer
from ..models.fyp2_models import Hearing, CaseMessage, CaseDocument
from ..services.database import get_db
from ..services.auth_service import require_client, get_current_user
from ..services.auth_service import decode_token, get_user_by_email
from fastapi import Cookie
from typing import Optional
from ..services.ai_service import analyze_case, VALID_CATEGORIES
from ..services.lawyer_service import recommend_lawyers, get_lawyer_by_id

router = APIRouter()
BASE_DIR = Path(__file__).resolve().parent.parent.parent
templates = Jinja2Templates(directory=str(BASE_DIR / "frontend" / "templates"))


def optional_user(
    session_token: Optional[str] = Cookie(default=None, alias="access_token"),
    db: Session = Depends(get_db),
):
    """Returns user if logged in, None otherwise."""
    if not session_token:
        return None
    payload = decode_token(session_token)
    if not payload:
        return None
    email = payload.get("sub")
    if not email:
        return None
    user = get_user_by_email(db, email)
    return user if user and user.is_active else None


@router.get("/dashboard", response_class=HTMLResponse)
async def client_dashboard(request: Request, user=Depends(require_client), db: Session = Depends(get_db)):
    cases = db.query(Case).filter(Case.client_id == user.id).order_by(Case.created_at.desc()).all()
    appointments = db.query(Appointment).filter(Appointment.client_id == user.id).order_by(Appointment.created_at.desc()).all()
    # Get upcoming hearings for this client
    hearings = []
    case_ids = [c.id for c in cases]
    if case_ids:
        hearings = db.query(Hearing).filter(
            Hearing.case_id.in_(case_ids),
            Hearing.status.in_(["scheduled", "in_progress"])
        ).order_by(Hearing.scheduled_date.asc()).all()
    return templates.TemplateResponse("client/dashboard.html", {
        "request": request, "user": user, "cases": cases,
        "appointments": appointments, "hearings": hearings,
    })


@router.get("/submit-case", response_class=HTMLResponse)
async def submit_case_page(request: Request, user=Depends(require_client)):
    return templates.TemplateResponse("client/submit_case.html", {"request": request, "user": user})


@router.post("/submit-case")
async def submit_case(
    request: Request,
    description: str = Form(...),
    user=Depends(require_client),
    db: Session = Depends(get_db),
):
    analysis = analyze_case(description)
    case = Case(
        client_id=user.id, description=description,
        category=analysis["category"], summary=analysis["summary"],
        legal_guidance=analysis["legal_guidance"], status="reviewed",
    )
    db.add(case)
    db.commit()
    db.refresh(case)
    recommendations = recommend_lawyers(db, analysis["category"], user.city)
    return templates.TemplateResponse("client/case_result.html", {
        "request": request, "user": user,
        "case": case, "analysis": analysis, "recommendations": recommendations,
    })


@router.get("/cases/{case_id}", response_class=HTMLResponse)
async def view_case(case_id: int, request: Request, user=Depends(require_client), db: Session = Depends(get_db)):
    case = db.query(Case).filter(Case.id == case_id, Case.client_id == user.id).first()
    if not case:
        raise HTTPException(status_code=404, detail="Case not found")
    recommendations = recommend_lawyers(db, case.category, user.city) if case.category else []
    appointments = db.query(Appointment).filter(
        Appointment.case_id == case_id,
        Appointment.client_id == user.id
    ).order_by(Appointment.created_at.desc()).all()
    messages = db.query(CaseMessage).filter(
        CaseMessage.case_id == case_id
    ).order_by(CaseMessage.sent_at.asc()).all()
    # Get documents shared by lawyer with this client
    shared_docs = db.query(CaseDocument).filter(
        CaseDocument.case_id == case_id,
        CaseDocument.uploader_role == "lawyer"
    ).order_by(CaseDocument.uploaded_at.desc()).all()
    hearings = db.query(Hearing).filter(
        Hearing.case_id == case_id
    ).order_by(Hearing.scheduled_date.asc()).all()
    return templates.TemplateResponse("client/case_detail.html", {
        "request": request, "user": user, "case": case,
        "recommendations": recommendations,
        "appointments": appointments, "messages": messages,
        "shared_docs": shared_docs, "hearings": hearings,
    })


@router.get("/book-appointment/{lawyer_id}", response_class=HTMLResponse)
async def book_appointment_page(
    lawyer_id: int, request: Request, case_id: int = None,
    user=Depends(require_client), db: Session = Depends(get_db),
):
    lawyer = get_lawyer_by_id(db, lawyer_id)
    if not lawyer:
        raise HTTPException(status_code=404, detail="Lawyer not found")
    cases = db.query(Case).filter(Case.client_id == user.id).all()
    return templates.TemplateResponse("client/book_appointment.html", {
        "request": request, "user": user, "lawyer": lawyer,
        "cases": cases, "preselected_case_id": case_id,
    })


@router.post("/book-appointment/{lawyer_id}")
async def book_appointment(
    lawyer_id: int, request: Request,
    appointment_date: str = Form(...), appointment_time: str = Form(...),
    case_id: str = Form(default=""), notes: str = Form(default=""),
    user=Depends(require_client), db: Session = Depends(get_db),
):
    lawyer = get_lawyer_by_id(db, lawyer_id)
    if not lawyer:
        raise HTTPException(status_code=404, detail="Lawyer not found")
    appt = Appointment(
        client_id=user.id, lawyer_id=lawyer_id,
        case_id=int(case_id) if case_id else None,
        appointment_date=appointment_date, appointment_time=appointment_time,
        notes=notes or None, status="pending",
    )
    db.add(appt)
    db.commit()
    return RedirectResponse(url="/client/dashboard?booked=1", status_code=303)


@router.get("/lawyers", response_class=HTMLResponse)
async def browse_lawyers(
    request: Request, user=Depends(optional_user), db: Session = Depends(get_db),
    specialization: str = None, city: str = None,
):
    query = db.query(Lawyer)
    if specialization:
        query = query.filter(Lawyer.specialization == specialization)
    if city:
        query = query.filter(Lawyer.city.ilike(f"%{city}%"))
    lawyers = query.order_by(Lawyer.rating.desc()).all()
    return templates.TemplateResponse("client/lawyers.html", {
        "request": request, "user": user, "lawyers": lawyers,
        "categories": VALID_CATEGORIES, "selected_spec": specialization or "", "selected_city": city or "",
    })


@router.get("/chatbot", response_class=HTMLResponse)
async def chatbot_page(request: Request, user=Depends(optional_user)):
    return templates.TemplateResponse("client/chatbot.html", {"request": request, "user": user})


@router.post("/cases/{case_id}/message")
async def client_send_message(
    case_id: int, content: str = Form(...),
    user=Depends(require_client), db: Session = Depends(get_db),
):
    # Clients may only message on their own cases
    case = db.query(Case).filter(Case.id == case_id, Case.client_id == user.id).first()
    if not case:
        raise HTTPException(status_code=404, detail="Case not found")
    msg = CaseMessage(case_id=case_id, sender_id=user.id, sender_role="client", content=content.strip())
    db.add(msg); db.commit()
    return RedirectResponse(url=f"/client/cases/{case_id}", status_code=303)
