"""
Lawyer Router — Fully connected version.

How the connection works:
  - Lawyers table = dataset from Excel (name, city, specialization etc.)
  - Users table   = login accounts (email, password, role)
  - When a lawyer logs in, we match their user account to a lawyer
    profile by email. If no match, we let them pick one OR auto-assign.
  - Appointment.lawyer_id = lawyers.id (NOT users.id)
  - So the dashboard shows appointments for the matched lawyer profile.
"""
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 Appointment, Lawyer, User, Case
from ..services.database import get_db
from ..services.auth_service import require_lawyer
from ..services.lawyer_service import get_lawyer_for_user

router = APIRouter()
BASE_DIR = Path(__file__).resolve().parent.parent.parent
templates = Jinja2Templates(directory=str(BASE_DIR / "frontend" / "templates"))


@router.get("/dashboard", response_class=HTMLResponse)
async def lawyer_dashboard(
    request: Request,
    user=Depends(require_lawyer),
    db: Session = Depends(get_db),
):
    lawyer = get_lawyer_for_user(db, user)

    appointments = []
    if lawyer:
        raw = (
            db.query(Appointment)
            .filter(Appointment.lawyer_id == lawyer.id)
            .order_by(Appointment.created_at.desc())
            .all()
        )
        for appt in raw:
            client = db.query(User).filter(User.id == appt.client_id).first()
            case = db.query(Case).filter(Case.id == appt.case_id).first() if appt.case_id else None
            appt.client_name   = client.full_name if client else f"Client #{appt.client_id}"
            appt.client_email  = client.email if client else "—"
            appt.client_city   = client.city if client else "—"
            appt.case_category = case.category if case else "—"
            appt.case_status   = case.status if case else "—"
            appt.case_summary  = (case.summary[:100] + "…") if case and case.summary and len(case.summary) > 100 else (case.summary if case else "—")
            appointments.append(appt)

    # All lawyers for the "switch profile" feature
    all_lawyers = db.query(Lawyer).order_by(Lawyer.rating.desc()).all()

    # Build platform-wide notification list — which lawyers have pending requests, from whom
    notif_lawyers = []
    all_pending = db.query(Appointment).filter(Appointment.status == "pending").all()
    pending_by_lawyer = {}
    for appt in all_pending:
        pending_by_lawyer.setdefault(appt.lawyer_id, []).append(appt)

    for lw_id, appts in pending_by_lawyer.items():
        lw = db.query(Lawyer).filter(Lawyer.id == lw_id).first()
        if not lw:
            continue
        client_names = []
        for a in appts[:3]:
            cl = db.query(User).filter(User.id == a.client_id).first()
            if cl:
                client_names.append(cl.full_name)
        notif_lawyers.append({
            "lawyer": lw,
            "count": len(appts),
            "client_names": client_names,
            "is_me": (lawyer and lw.id == lawyer.id),
        })
    # Sort: your own profile's notifications first, then by count
    notif_lawyers.sort(key=lambda x: (not x["is_me"], -x["count"]))

    platform_notifications = sum(n["count"] for n in notif_lawyers)

    return templates.TemplateResponse("lawyer/dashboard.html", {
        "request":      request,
        "user":         user,
        "lawyer":       lawyer,
        "appointments": appointments,
        "all_lawyers":  all_lawyers,
        "platform_notifications": platform_notifications,
        "notif_lawyers": notif_lawyers,
    })


@router.post("/switch-profile")
async def switch_lawyer_profile(
    lawyer_id: int = Form(...),
    user=Depends(require_lawyer),
    db: Session = Depends(get_db),
):
    """Allow a lawyer user to switch which lawyer profile they are linked to."""
    new_lawyer = db.query(Lawyer).filter(Lawyer.id == lawyer_id).first()
    if not new_lawyer:
        raise HTTPException(status_code=404, detail="Lawyer profile not found")

    # Refuse to take over a profile already claimed by another registered user
    claimed_by_other = db.query(User).filter(
        User.email == new_lawyer.contact_email,
        User.id != user.id,
    ).first()
    if claimed_by_other:
        raise HTTPException(status_code=403, detail="That profile is linked to another account")

    # Remove old link
    old = db.query(Lawyer).filter(Lawyer.contact_email == user.email).first()
    if old:
        old.contact_email = f"unlinked_{old.id}@legalfirm.pk"

    new_lawyer.contact_email = user.email
    db.commit()

    return RedirectResponse(url="/lawyer/dashboard", status_code=303)


@router.post("/appointments/{appt_id}/update")
async def update_appointment_status(
    appt_id: int,
    request: Request,
    status: str = Form(...),
    user=Depends(require_lawyer),
    db: Session = Depends(get_db),
):
    lawyer = get_lawyer_for_user(db, user)
    appt = db.query(Appointment).filter(Appointment.id == appt_id).first()
    if not appt or not lawyer or appt.lawyer_id != lawyer.id:
        raise HTTPException(status_code=403, detail="This appointment is not assigned to you")
    if status in ("confirmed", "cancelled", "pending"):
        appt.status = status
        db.commit()
    # Redirect back to case view if that's where the action came from
    redirect = request.query_params.get("redirect", "/lawyer/dashboard")
    return RedirectResponse(url=redirect, status_code=303)


@router.get("/case/{case_id}", response_class=HTMLResponse)
async def lawyer_view_case(
    case_id: int,
    request: Request,
    user=Depends(require_lawyer),
    db: Session = Depends(get_db),
):
    """Lawyer views full case details for any appointment linked to them."""
    case = db.query(Case).filter(Case.id == case_id).first()
    if not case:
        raise HTTPException(status_code=404, detail="Case not found")

    # Only allow access if the case is linked to this lawyer via an appointment
    lawyer = get_lawyer_for_user(db, user)
    linked = lawyer and db.query(Appointment).filter(
        Appointment.case_id == case_id,
        Appointment.lawyer_id == lawyer.id,
    ).first()
    if not linked:
        raise HTTPException(status_code=403, detail="This case is not linked to you")

    client = db.query(User).filter(User.id == case.client_id).first()

    # Get all appointments for this case
    appointments = (
        db.query(Appointment)
        .filter(Appointment.case_id == case_id)
        .order_by(Appointment.created_at.desc())
        .all()
    )

    return templates.TemplateResponse("lawyer/case_view.html", {
        "request":      request,
        "user":         user,
        "case":         case,
        "client":       client,
        "appointments": appointments,
    })


@router.get("/directory", response_class=HTMLResponse)
async def lawyer_directory(
    request: Request,
    specialization: str = "",
    city: str = "",
    notifications_only: str = "",
    user=Depends(require_lawyer),
    db: Session = Depends(get_db),
):
    """Lawyer-facing directory — find peers, see who has pending client notifications."""
    query = db.query(Lawyer)
    if specialization:
        query = query.filter(Lawyer.specialization == specialization)
    if city:
        query = query.filter(Lawyer.city.ilike(f"%{city}%"))
    all_lawyers = query.all()

    # Enrich each lawyer with appointment / notification data
    for lw in all_lawyers:
        lw.appointment_count = db.query(Appointment).filter(Appointment.lawyer_id == lw.id).count()
        pending = db.query(Appointment).filter(
            Appointment.lawyer_id == lw.id, Appointment.status == "pending"
        ).order_by(Appointment.created_at.desc()).all()
        lw.pending_count = len(pending)
        lw.latest_pending_client = None
        if pending:
            latest_client = db.query(User).filter(User.id == pending[0].client_id).first()
            lw.latest_pending_client = latest_client.full_name if latest_client else None

    # Filter to notifications only if requested
    if notifications_only == "1":
        all_lawyers = [lw for lw in all_lawyers if lw.pending_count > 0]

    # Sort: lawyers WITH notifications first (by count desc), then by rating
    lawyers = sorted(all_lawyers, key=lambda lw: (-lw.pending_count, -lw.rating))

    categories = [row[0] for row in db.query(Lawyer.specialization).distinct().all()]
    my_lawyer = get_lawyer_for_user(db, user)

    total_notifications = sum(lw.pending_count for lw in lawyers)
    lawyers_with_notifications = sum(1 for lw in lawyers if lw.pending_count > 0)

    return templates.TemplateResponse("lawyer/directory.html", {
        "request": request, "user": user, "lawyers": lawyers,
        "categories": categories, "selected_spec": specialization, "selected_city": city,
        "my_lawyer_id": my_lawyer.id if my_lawyer else None,
        "notifications_only": notifications_only == "1",
        "total_notifications": total_notifications,
        "lawyers_with_notifications": lawyers_with_notifications,
    })

@router.get("/ocr")
async def ocr_quick_access(user=Depends(require_lawyer), db: Session = Depends(get_db)):
    """
    Document OCR has no standalone page — it lives inside each case workspace.
    Redirect to the most recent active case, or to the office tray if no cases yet.
    """
    lawyer = get_lawyer_for_user(db, user)
    if lawyer:
        latest_appt = db.query(Appointment).filter(
            Appointment.lawyer_id == lawyer.id,
            Appointment.case_id.isnot(None)
        ).order_by(Appointment.created_at.desc()).first()
        if latest_appt and latest_appt.case_id:
            return RedirectResponse(url=f"/lawyer/office/case/{latest_appt.case_id}#documents", status_code=303)
    return RedirectResponse(url="/lawyer/office", status_code=303)
