from fastapi import APIRouter, Depends, Form, Request
from fastapi.responses import RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session

from ..auth import get_current_user, get_db, require_admin
from ..repositories import ProjectRepository, TaskRepository, UserRepository
from ..services import ProjectService, TaskService, UserService, send_overdue_alerts, task_progress_metrics

router = APIRouter(prefix="/admin")

templates = Jinja2Templates(directory="app/templates")


@router.get("")
def admin_home(request: Request, db: Session = Depends(get_db)):
    user = require_admin(get_current_user(request, db))
    users = UserRepository(db).list_all()
    projects = ProjectRepository(db).list_all()
    user_status = request.query_params.get("user_status")
    user_error = request.query_params.get("user_error")
    user_messages = {
        "updated": "Usuario actualizado correctamente.",
        "empty_email": "El correo no puede estar vacio.",
        "email_exists": "El correo ya esta registrado por otro usuario.",
        "not_found": "No fue posible encontrar el usuario.",
        "unknown": "No fue posible actualizar el usuario.",
    }
    task_repo = TaskRepository(db)
    tasks = []
    overdue_tasks = []
    for project in projects:
        project_tasks = task_repo.list_by_project(project.id)
        tasks.extend(project_tasks)
        for task in project_tasks:
            if task.status != "in_progress":
                continue
            metrics = task_progress_metrics(task)
            if metrics["overdue_days"] > 0:
                overdue_tasks.append(
                    {
                        "project": project,
                        "task": task,
                        "metrics": metrics,
                    }
                )
    overdue_tasks.sort(key=lambda item: item["metrics"]["overdue_days"], reverse=True)
    send_overdue_alerts(db, tasks)
    return templates.TemplateResponse(
        "admin.html",
        {
            "request": request,
            "user": user,
            "users": users,
            "projects": projects,
            "tasks": tasks,
            "overdue_tasks": overdue_tasks,
            "user_success": user_messages.get(user_status),
            "user_error": user_messages.get(user_error),
        },
    )


@router.post("/users")
def create_user(
    request: Request,
    username: str = Form(...),
    email: str = Form(...),
    password: str = Form(...),
    role: str = Form("user"),
    db: Session = Depends(get_db),
):
    user = require_admin(get_current_user(request, db))
    service = UserService(db)
    try:
        service.create_user(username, email, password, role)
    except ValueError:
        return RedirectResponse("/admin?error=user", status_code=302)
    return RedirectResponse("/admin", status_code=302)


@router.post("/users/{user_id}")
def update_user(
    user_id: int,
    request: Request,
    email: str = Form(...),
    password: str = Form(""),
    db: Session = Depends(get_db),
):
    require_admin(get_current_user(request, db))
    repo = UserRepository(db)
    target_user = repo.get_by_id(user_id)
    if not target_user:
        return RedirectResponse("/admin?user_error=not_found", status_code=302)

    service = UserService(db)
    try:
        service.admin_update_user(target_user, email, password.strip() or None)
    except ValueError as exc:
        error_code = exc.args[0] if exc.args else "unknown"
        return RedirectResponse(f"/admin?user_error={error_code}", status_code=302)
    return RedirectResponse("/admin?user_status=updated", status_code=302)


@router.post("/projects")
def create_project(
    request: Request,
    name: str = Form(...),
    description: str = Form(""),
    is_group: str = Form("false"),
    db: Session = Depends(get_db),
):
    user = require_admin(get_current_user(request, db))
    service = ProjectService(db)
    service.create_project(name, description or None, is_group == "true", user.id)
    return RedirectResponse("/admin", status_code=302)


@router.post("/projects/members")
def add_member(
    request: Request,
    project_id: int = Form(...),
    user_id: int = Form(...),
    db: Session = Depends(get_db),
):
    require_admin(get_current_user(request, db))
    service = ProjectService(db)
    try:
        service.add_member(project_id, user_id)
    except ValueError:
        return RedirectResponse("/admin?error=member", status_code=302)
    return RedirectResponse("/admin", status_code=302)


@router.post("/tasks")
def create_task(
    request: Request,
    project_id: int = Form(...),
    title: str = Form(...),
    description: str = Form(""),
    priority: str = Form("medium"),
    duration_days: int = Form(...),
    assigned_user_id: str = Form(""),
    db: Session = Depends(get_db),
):
    user = require_admin(get_current_user(request, db))
    if duration_days < 1:
        return RedirectResponse("/admin?error=duration", status_code=302)
    service = TaskService(db)
    assigned_id = int(assigned_user_id) if assigned_user_id else None
    service.create_task(project_id, title, description or None, priority, duration_days, user.id, assigned_id)
    return RedirectResponse("/admin", status_code=302)


@router.post("/tasks/assign")
def assign_task(
    request: Request,
    task_id: int = Form(...),
    user_id: int = Form(...),
    db: Session = Depends(get_db),
):
    require_admin(get_current_user(request, db))
    repo = TaskRepository(db)
    task = repo.get(task_id)
    if task:
        service = TaskService(db)
        service.assign_task(task, user_id)
    return RedirectResponse("/admin", status_code=302)
