import secrets
import hashlib
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List, Optional

from app.db.session import get_db
from app.db.models import ApiKey, User
from app.api.deps import get_current_user


router = APIRouter(prefix="/api-keys", tags=["api-keys"])


class ApiKeyCreate(BaseModel):
    name: str
    scopes: List[str] = []
    expires_at: Optional[str] = None


class ApiKeyOut(BaseModel):
    id: int
    name: str
    key_prefix: str  # Первые 8 символов ключа
    scopes: List[str]
    created_at: datetime
    expires_at: Optional[datetime] = None
    
    class Config:
        from_attributes = True


class ApiKeyCreateResponse(BaseModel):
    id: int
    name: str
    key: str  # Полный ключ (показывается только один раз при создании)
    scopes: List[str]
    created_at: datetime
    expires_at: Optional[datetime] = None


def generate_api_key() -> str:
    """Генерировать новый API ключ"""
    random_bytes = secrets.token_bytes(32)
    key = f"sk_live_{random_bytes.hex()}"
    return key


def hash_api_key(key: str) -> str:
    """Хешировать API ключ для безопасного хранения"""
    return hashlib.sha256(key.encode()).hexdigest()


@router.post("", response_model=ApiKeyCreateResponse, status_code=201)
async def create_api_key(
    data: ApiKeyCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Создать новый API ключ"""
    
    # Генерируем ключ
    api_key = generate_api_key()
    key_hash = hash_api_key(api_key)
    
    # Парсим дату истечения если указана
    expires_at = None
    if data.expires_at:
        try:
            # Парсим ISO формат даты
            if isinstance(data.expires_at, str):
                expires_at = datetime.fromisoformat(data.expires_at.replace('Z', '+00:00'))
            else:
                expires_at = data.expires_at
        except Exception:
            raise HTTPException(status_code=400, detail="Неверный формат даты")
    
    # Создаем запись в БД
    db_key = ApiKey(
        tenant_id=current_user.tenant_id,
        user_id=current_user.id,
        name=data.name,
        key_hash=key_hash,
        scopes=data.scopes,
        expires_at=expires_at
    )
    db.add(db_key)
    db.commit()
    db.refresh(db_key)
    
    return ApiKeyCreateResponse(
        id=db_key.id,
        name=db_key.name,
        key=api_key,  # Возвращаем оригинальный ключ только один раз
        scopes=db_key.scopes,
        created_at=db_key.created_at,
        expires_at=db_key.expires_at
    )


@router.get("", response_model=List[ApiKeyOut])
async def list_api_keys(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Получить список API ключей"""
    
    keys = db.query(ApiKey).filter(
        ApiKey.tenant_id == current_user.tenant_id
    ).all()
    
    result = []
    for key in keys:
        # Генерируем префикс ключа для отображения
        key_prefix = key.key_hash[:8] + "..." if len(key.key_hash) > 8 else key.key_hash
        
        result.append(ApiKeyOut(
            id=key.id,
            name=key.name,
            key_prefix=key_prefix,
            scopes=key.scopes or [],
            created_at=key.created_at,
            expires_at=key.expires_at
        ))
    
    return result


@router.delete("/{key_id}")
async def delete_api_key(
    key_id: int,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Удалить API ключ"""
    
    key = db.query(ApiKey).filter(
        ApiKey.id == key_id,
        ApiKey.tenant_id == current_user.tenant_id
    ).first()
    
    if not key:
        raise HTTPException(status_code=404, detail="API ключ не найден")
    
    db.delete(key)
    db.commit()
    
    return {"ok": True, "message": "API ключ удален"}

