"""
Authentication Router
"""
from fastapi import APIRouter, Request, Form, Depends, HTTPException
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from pathlib import Path
from sqlalchemy.orm import Session

from ..models.models import User
from ..services.database import get_db
from ..services.auth_service import hash_password, authenticate_user, create_access_token, get_user_by_email
from ..config import ACCESS_TOKEN_EXPIRE_MINUTES
from ..schemas.schemas import UserLogin, Token

router = APIRouter()
BASE_DIR = Path(__file__).resolve().parent.parent.parent
templates = Jinja2Templates(directory=str(BASE_DIR / "frontend" / "templates"))


@router.get("/login", response_class=HTMLResponse)
async def login_page(request: Request):
    return templates.TemplateResponse("auth/login.html", {"request": request})


@router.get("/register", response_class=HTMLResponse)
async def register_page(request: Request):
    return templates.TemplateResponse("auth/register.html", {"request": request})


@router.post("/register")
async def register(
    request: Request,
    full_name: str = Form(...),
    email: str = Form(...),
    password: str = Form(...),
    role: str = Form(default="client"),
    city: str = Form(default=""),
    db: Session = Depends(get_db),
):
    # Only client/lawyer are self-registrable — never accept arbitrary roles
    # (e.g. "admin") from the form
    if role not in ("client", "lawyer"):
        role = "client"
    if len(password) < 6:
        return templates.TemplateResponse(
            "auth/register.html",
            {"request": request, "error": "Password must be at least 6 characters."},
        )
    if get_user_by_email(db, email):
        return templates.TemplateResponse(
            "auth/register.html",
            {"request": request, "error": "Email already registered."},
        )
    user = User(
        full_name=full_name,
        email=email,
        hashed_password=hash_password(password),
        role=role,
        city=city or None,
    )
    db.add(user)
    db.commit()
    return RedirectResponse(url="/api/auth/login?registered=1", status_code=303)


@router.post("/login")
async def login(
    request: Request,
    email: str = Form(...),
    password: str = Form(...),
    db: Session = Depends(get_db),
):
    user = authenticate_user(db, email, password)
    if not user:
        return templates.TemplateResponse(
            "auth/login.html",
            {"request": request, "error": "Invalid email or password."},
        )
    token = create_access_token({"sub": user.email, "role": user.role})
    redirect_url = "/client/dashboard" if user.role == "client" else "/lawyer/dashboard"
    response = RedirectResponse(url=redirect_url, status_code=303)
    response.set_cookie(
        key="access_token", value=token, httponly=True, samesite="lax",
        max_age=ACCESS_TOKEN_EXPIRE_MINUTES * 60,  # cookie expires with the JWT
    )
    return response


@router.post("/token", response_model=Token)
async def token_login(user_data: UserLogin, db: Session = Depends(get_db)):
    user = authenticate_user(db, user_data.email, user_data.password)
    if not user:
        raise HTTPException(status_code=401, detail="Invalid credentials")
    token = create_access_token({"sub": user.email, "role": user.role})
    return Token(access_token=token, token_type="bearer", role=user.role, full_name=user.full_name)


@router.get("/logout")
async def logout():
    response = RedirectResponse(url="/api/auth/login", status_code=303)
    response.delete_cookie("access_token")
    return response
