from typing import Optional
from sqlalchemy.ext.asyncio import AsyncSession
from src.core.database import get_db
from src.core.auth import require_enterprise_or_front
from src.services.visualizacoes import VisualizacaoService
import datetime
from fastapi import APIRouter, Depends, HTTPException, Query, status
from src.core.api_responses import (
    build_success_payload,
    SuccessResponse,
    ErrorResponse,
)

router = APIRouter(
    prefix="/visualizacoes",
    tags=["Visualizacoes"]
)

visualizacao_service = VisualizacaoService()


@router.get(
    "/usuarios/{usuario_id}/atividades",
    summary="Atividades por Usuário",
    description=(
        "Retorna todas as atividades de um usuário específico.\n\n"
        "Busca atividades através dos computadores vinculados ao usuário.\n\n"
        "Query Parameters:\n"
        "- data_inicio: Data/hora de início (ISO: YYYY-MM-DDTHH:MM:SS)\n"
        "- data_fim: Data/hora de fim (ISO: YYYY-MM-DDTHH:MM:SS)\n"
        "- evento: Filtrar por tipo de evento\n"
        "- processo: Filtrar por processo"
    ),
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {
            "description": "Atividades do usuário encontradas"},
        404: {
            "description": "Usuário não encontrado",
            "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
    },
)
async def obter_atividades_usuario(
    usuario_id: int,
    data_inicio: Optional[str] = Query(
        None,
        description="Data/hora de início",
        examples="2025-01-01T00:00:00",
    ),
    data_fim: Optional[str] = Query(
        None,
        description="Data/hora de fim",
        examples="2025-01-31T23:59:59",
    ),
    evento: Optional[str] = Query(
        None,
        description="Filtrar por evento",
    ),
    processo: Optional[str] = Query(
        None,
        description="Filtrar por processo",
    ),
    db: AsyncSession = Depends(get_db),
    _auth=Depends(require_enterprise_or_front),
):
    """Obter atividades de um usuário específico."""

    data_inicio_dt = None
    data_fim_dt = None

    if data_inicio:
        try:
            data_inicio_dt = datetime.datetime.fromisoformat(
                data_inicio.replace(' ', 'T'))
        except (ValueError, AttributeError):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=(
                    "Formato de data_inicio inválido. "
                    "Use formato ISO (YYYY-MM-DDTHH:MM:SS)"
                ),
            )

    if data_fim:
        try:
            data_fim_dt = datetime.datetime.fromisoformat(
                data_fim.replace(' ', 'T'))
        except (ValueError, AttributeError):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=(
                    "Formato de data_fim inválido. "
                    "Use formato ISO (YYYY-MM-DDTHH:MM:SS)"
                ),
            )

    try:
        resultado = await visualizacao_service.obter_atividades_por_usuario(
            db=db,
            usuario_id=usuario_id,
            data_inicio=data_inicio_dt,
            data_fim=data_fim_dt,
            evento=evento,
            processo=processo
        )

        if not resultado:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Usuário não encontrado ou sem atividades"
            )

        total_atividades = len(resultado.get("atividades", []))
        return build_success_payload(
            data=resultado,
            message=(
                f"Total de {total_atividades} atividade(s) "
                "encontrada(s) para o usuário"
            ),
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Erro ao buscar atividades: {str(e)}"
        )


@router.get(
    "/times/{time_id}/atividades",
    summary="Atividades por Time",
    description=(
        "Retorna todas as atividades dos usuários que pertencem a um time.\n\n"
        "Busca atividades através dos computadores vinculados.\n\n"
        "Query Parameters:\n"
        "- data_inicio: Data/hora de início (ISO: YYYY-MM-DDTHH:MM:SS)\n"
        "- data_fim: Data/hora de fim (ISO: YYYY-MM-DDTHH:MM:SS)\n"
        "- evento: Filtrar por tipo de evento\n"
        "- processo: Filtrar por processo"
    ),
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {
            "description": "Atividades do time encontradas"},
        404: {
            "description": "Time não encontrado",
            "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
    },
)
async def obter_atividades_time(
    time_id: int,
    data_inicio: Optional[str] = Query(
        None,
        description="Data/hora de início",
        examples="2025-01-01T00:00:00",
    ),
    data_fim: Optional[str] = Query(
        None,
        description="Data/hora de fim",
        examples="2025-01-31T23:59:59",
    ),
    evento: Optional[str] = Query(
        None,
        description="Filtrar por evento",
    ),
    processo: Optional[str] = Query(
        None,
        description="Filtrar por processo",
    ),
    db: AsyncSession = Depends(get_db),
    _auth=Depends(require_enterprise_or_front),
):
    """Obter atividades de todos os usuários de um time."""

    data_inicio_dt = None
    data_fim_dt = None

    if data_inicio:
        try:
            data_inicio_dt = datetime.datetime.fromisoformat(
                data_inicio.replace(' ', 'T'))
        except (ValueError, AttributeError):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=(
                    "Formato de data_inicio inválido. "
                    "Use formato ISO (YYYY-MM-DDTHH:MM:SS)"
                ),
            )

    if data_fim:
        try:
            data_fim_dt = datetime.datetime.fromisoformat(
                data_fim.replace(' ', 'T'))
        except (ValueError, AttributeError):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=(
                    "Formato de data_fim inválido. "
                    "Use formato ISO (YYYY-MM-DDTHH:MM:SS)"
                ),
            )

    try:
        resultado = await visualizacao_service.obter_atividades_por_time(
            db=db,
            time_id=time_id,
            data_inicio=data_inicio_dt,
            data_fim=data_fim_dt,
            evento=evento,
            processo=processo
        )

        if not resultado or not resultado.get("usuarios"):
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Time não encontrado ou sem usuários"
            )

        total_atividades = sum(
            len(u.get("atividades", []))
            for u in resultado.get("usuarios", [])
        )
        return build_success_payload(
            data=resultado,
            message=(
                f"Total de {total_atividades} atividade(s) "
                "encontrada(s) para o time"
            ),
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Erro ao buscar atividades: {str(e)}"
        )


@router.get(
    "/usuarios/{usuario_id}/diagnostico",
    summary="Diagnóstico de Usuário",
    description=(
        "Faz um diagnóstico completo do usuário.\n\n"
        "Retorna:\n"
        "- Informações do usuário\n"
        "- Computadores vinculados ao usuário\n"
        "- Computadores não vinculados (mas com mesmo nome_usuario)\n"
        "- Total de atividades e últimas 5 atividades\n"
        "- Recomendações para resolver problemas"),
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {
            "description": "Diagnóstico realizado com sucesso"},
        404: {
            "description": "Usuário não encontrado",
            "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
    },
)
async def diagnosticar_usuario(
    usuario_id: int,
    db: AsyncSession = Depends(get_db),
    _auth=Depends(require_enterprise_or_front),
):
    """Faz um diagnóstico completo do usuário."""

    try:
        resultado = await visualizacao_service.diagnosticar_usuario(
            db=db,
            usuario_id=usuario_id
        )

        if not resultado:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Usuário não encontrado"
            )

        return build_success_payload(
            data=resultado,
            message="Diagnóstico realizado com sucesso"
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Erro ao fazer diagnóstico: {str(e)}"
        )
