from fastapi import APIRouter, Depends, Form, HTTPException, Request, status
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session as DbSession

from app.auth import (
    SESSION_COOKIE,
    create_user_session,
    get_current_user,
    get_current_user_optional,
    hash_password,
    verify_password,
)
from app.database import get_db
from app.models import Session, User

router = APIRouter(tags=["web"])
templates = Jinja2Templates(directory="templates")


@router.get("/", response_class=HTMLResponse)
def index(request: Request, user: User | None = Depends(get_current_user_optional)):
    if user:
        return RedirectResponse("/cabinet", status_code=status.HTTP_302_FOUND)
    return RedirectResponse("/login", status_code=status.HTTP_302_FOUND)


@router.get("/register", response_class=HTMLResponse)
def register_page(request: Request, user: User | None = Depends(get_current_user_optional)):
    if user:
        return RedirectResponse("/cabinet", status_code=status.HTTP_302_FOUND)
    return templates.TemplateResponse(request, "register.html", {"error": None})


@router.post("/register")
def register(
    request: Request,
    email: str = Form(...),
    password: str = Form(...),
    db: DbSession = Depends(get_db),
):
    email = email.strip().lower()
    if len(password) < 6:
        return templates.TemplateResponse(
            request,
            "register.html",
            {"error": "Пароль должен быть не менее 6 символов"},
            status_code=400,
        )
    existing = db.query(User).filter(User.email == email).first()
    if existing:
        return templates.TemplateResponse(
            request,
            "register.html",
            {"error": "Пользователь с такой почтой уже существует"},
            status_code=400,
        )
    user = User(email=email, password_hash=hash_password(password))
    db.add(user)
    db.commit()
    db.refresh(user)
    session = create_user_session(db, user)
    response = RedirectResponse("/cabinet", status_code=status.HTTP_302_FOUND)
    response.set_cookie(
        key=SESSION_COOKIE,
        value=session.token,
        httponly=True,
        samesite="lax",
        max_age=86400,
    )
    return response


@router.get("/login", response_class=HTMLResponse)
def login_page(request: Request, user: User | None = Depends(get_current_user_optional)):
    if user:
        return RedirectResponse("/cabinet", status_code=status.HTTP_302_FOUND)
    return templates.TemplateResponse(request, "login.html", {"error": None})


@router.post("/login")
def login(
    request: Request,
    email: str = Form(...),
    password: str = Form(...),
    db: DbSession = Depends(get_db),
):
    email = email.strip().lower()
    user = db.query(User).filter(User.email == email).first()
    if not user or not verify_password(password, user.password_hash):
        return templates.TemplateResponse(
            request,
            "login.html",
            {"error": "Неверная почта или пароль"},
            status_code=400,
        )
    session = create_user_session(db, user)
    response = RedirectResponse("/cabinet", status_code=status.HTTP_302_FOUND)
    response.set_cookie(
        key=SESSION_COOKIE,
        value=session.token,
        httponly=True,
        samesite="lax",
        max_age=86400,
    )
    return response


@router.post("/logout")
def logout(request: Request, db: DbSession = Depends(get_db)):
    token = request.cookies.get(SESSION_COOKIE)
    if token:
        session = db.query(Session).filter(Session.token == token).first()
        if session:
            session.is_active = False
            db.commit()
    response = RedirectResponse("/login", status_code=status.HTTP_302_FOUND)
    response.delete_cookie(SESSION_COOKIE)
    return response


@router.get("/cabinet", response_class=HTMLResponse)
def cabinet(request: Request, user: User = Depends(get_current_user), db: DbSession = Depends(get_db)):
    sessions = (
        db.query(Session)
        .filter(Session.user_id == user.id, Session.is_active.is_(True))
        .order_by(Session.created_at.desc())
        .all()
    )
    external_data = list(reversed(user.external_data[-10:])) if user.external_data else []
    return templates.TemplateResponse(
        request,
        "cabinet.html",
        {
            "user": user,
            "sessions": sessions,
            "external_data": external_data,
        },
    )
