from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.orm import Session
from typing import List
from datetime import date

from app.core.database import get_db
from app.core.security import decode_access_token
from app.models.health import HealthMetric
from app.schemas.health import HealthMetricCreate, HealthMetricResponse, HealthMetricUpdate

router = APIRouter()
security = HTTPBearer()

def get_current_user_id(credentials: HTTPAuthorizationCredentials = Depends(security)) -> str:
    """Extrai user_id do token JWT"""
    token = credentials.credentials
    payload = decode_access_token(token)
    if not payload:
        raise HTTPException(status_code=401, detail="Token inválido")
    return payload.get("sub")

@router.post("/", response_model=HealthMetricResponse, status_code=status.HTTP_201_CREATED)
async def create_health_metric(
    metric_data: HealthMetricCreate,
    user_id: str = Depends(get_current_user_id),
    db: Session = Depends(get_db)
):
    """Criar nova métrica de saúde"""
    new_metric = HealthMetric(
        user_id=user_id,
        measurement_date=metric_data.measurement_date,
        measurement_time=metric_data.measurement_time,
        weight=metric_data.weight,
        height=metric_data.height,
        body_fat_percentage=metric_data.body_fat_percentage,
        muscle_mass=metric_data.muscle_mass,
        waist=metric_data.waist,
        chest=metric_data.chest,
        hips=metric_data.hips,
        notes=metric_data.notes
    )
    
    db.add(new_metric)
    db.commit()
    db.refresh(new_metric)
    
    return new_metric

@router.get("/", response_model=List[HealthMetricResponse])
async def list_health_metrics(
    user_id: str = Depends(get_current_user_id),
    db: Session = Depends(get_db),
    limit: int = 100
):
    """Listar todas as métricas de saúde do usuário"""
    metrics = db.query(HealthMetric).filter(
        HealthMetric.user_id == user_id
    ).order_by(HealthMetric.measurement_date.desc()).limit(limit).all()
    
    return metrics

@router.get("/latest", response_model=HealthMetricResponse)
async def get_latest_metric(
    user_id: str = Depends(get_current_user_id),
    db: Session = Depends(get_db)
):
    """Obter última métrica registrada"""
    metric = db.query(HealthMetric).filter(
        HealthMetric.user_id == user_id
    ).order_by(HealthMetric.measurement_date.desc()).first()
    
    if not metric:
        raise HTTPException(status_code=404, detail="Nenhuma métrica encontrada")
    
    return metric

@router.get("/{metric_id}", response_model=HealthMetricResponse)
async def get_health_metric(
    metric_id: str,
    user_id: str = Depends(get_current_user_id),
    db: Session = Depends(get_db)
):
    """Obter métrica específica"""
    metric = db.query(HealthMetric).filter(
        HealthMetric.id == metric_id,
        HealthMetric.user_id == user_id
    ).first()
    
    if not metric:
        raise HTTPException(status_code=404, detail="Métrica não encontrada")
    
    return metric

@router.put("/{metric_id}", response_model=HealthMetricResponse)
async def update_health_metric(
    metric_id: str,
    metric_data: HealthMetricUpdate,
    user_id: str = Depends(get_current_user_id),
    db: Session = Depends(get_db)
):
    """Atualizar métrica de saúde"""
    metric = db.query(HealthMetric).filter(
        HealthMetric.id == metric_id,
        HealthMetric.user_id == user_id
    ).first()
    
    if not metric:
        raise HTTPException(status_code=404, detail="Métrica não encontrada")
    
    # Atualizar campos
    update_data = metric_data.dict(exclude_unset=True)
    for field, value in update_data.items():
        setattr(metric, field, value)
    
    db.commit()
    db.refresh(metric)
    
    return metric

@router.delete("/{metric_id}")
async def delete_health_metric(
    metric_id: str,
    user_id: str = Depends(get_current_user_id),
    db: Session = Depends(get_db)
):
    """Deletar métrica de saúde"""
    metric = db.query(HealthMetric).filter(
        HealthMetric.id == metric_id,
        HealthMetric.user_id == user_id
    ).first()
    
    if not metric:
        raise HTTPException(status_code=404, detail="Métrica não encontrada")
    
    db.delete(metric)
    db.commit()
    
    return {"message": "Métrica deletada com sucesso"}

@router.get("/stats/summary")
async def get_health_stats(
    user_id: str = Depends(get_current_user_id),
    db: Session = Depends(get_db)
):
    """Estatísticas e resumo de saúde"""
    latest = db.query(HealthMetric).filter(
        HealthMetric.user_id == user_id
    ).order_by(HealthMetric.measurement_date.desc()).first()
    
    # Pegar primeira e última medição para calcular diferença
    first = db.query(HealthMetric).filter(
        HealthMetric.user_id == user_id,
        HealthMetric.weight.isnot(None)
    ).order_by(HealthMetric.measurement_date.asc()).first()
    
    stats = {
        "current_weight": float(latest.weight) if latest and latest.weight else None,
        "current_height": float(latest.height) if latest and latest.height else None,
        "current_body_fat": float(latest.body_fat_percentage) if latest and latest.body_fat_percentage else None,
        "weight_change": None,
        "total_measurements": db.query(HealthMetric).filter(HealthMetric.user_id == user_id).count()
    }
    
    if latest and first and latest.weight and first.weight:
        stats["weight_change"] = float(latest.weight - first.weight)
    
    return stats

