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 Webhook, User
from app.api.deps import get_current_user


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


class WebhookCreate(BaseModel):
    url: str
    events: List[str] = []
    secret: Optional[str] = None


class WebhookUpdate(BaseModel):
    url: Optional[str] = None
    events: Optional[List[str]] = None
    is_active: Optional[bool] = None


class WebhookOut(BaseModel):
    id: int
    url: str
    events: List[str]
    secret: str
    is_active: bool
    created_at: datetime
    last_triggered: Optional[datetime] = None
    success_count: int = 0
    failure_count: int = 0
    
    class Config:
        from_attributes = True


def generate_webhook_secret() -> str:
    """Генерировать секрет для webhook"""
    random_bytes = secrets.token_bytes(32)
    return f"whsec_{random_bytes.hex()}"


@router.post("", response_model=WebhookOut, status_code=201)
async def create_webhook(
    data: WebhookCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Создать новый webhook"""
    try:
        # Валидация URL
        if not data.url or not data.url.startswith(('http://', 'https://')):
            raise HTTPException(
                status_code=400,
                detail="URL должен начинаться с http:// или https://"
            )
        
        # Генерируем секрет если не указан
        secret = data.secret or generate_webhook_secret()
        
        # Создаем запись в БД
        db_webhook = Webhook(
            tenant_id=current_user.tenant_id,
            url=data.url,
            events=data.events if data.events else [],
            secret=secret,
            is_active=True
        )
        db.add(db_webhook)
        db.commit()
        db.refresh(db_webhook)
        
        return WebhookOut(
            id=db_webhook.id,
            url=db_webhook.url,
            events=db_webhook.events or [],
            secret=db_webhook.secret,
            is_active=db_webhook.is_active,
            created_at=db_webhook.created_at,
            last_triggered=db_webhook.last_triggered,
            success_count=db_webhook.success_count or 0,
            failure_count=db_webhook.failure_count or 0
        )
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=500,
            detail=f"Ошибка создания webhook: {str(e)}"
        )


@router.get("", response_model=List[WebhookOut])
async def list_webhooks(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Получить список webhooks"""
    
    webhooks = db.query(Webhook).filter(
        Webhook.tenant_id == current_user.tenant_id
    ).all()
    
    result = []
    for webhook in webhooks:
        result.append(WebhookOut(
            id=webhook.id,
            url=webhook.url,
            events=webhook.events or [],
            secret=webhook.secret,
            is_active=webhook.is_active,
            created_at=webhook.created_at,
            last_triggered=webhook.last_triggered,
            success_count=webhook.success_count or 0,
            failure_count=webhook.failure_count or 0
        ))
    
    return result


@router.get("/{webhook_id}", response_model=WebhookOut)
async def get_webhook(
    webhook_id: int,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Получить webhook по ID"""
    
    webhook = db.query(Webhook).filter(
        Webhook.id == webhook_id,
        Webhook.tenant_id == current_user.tenant_id
    ).first()
    
    if not webhook:
        raise HTTPException(status_code=404, detail="Webhook не найден")
    
    return WebhookOut(
        id=webhook.id,
        url=webhook.url,
        events=webhook.events or [],
        secret=webhook.secret,
        is_active=webhook.is_active,
        created_at=webhook.created_at,
        last_triggered=webhook.last_triggered,
        success_count=webhook.success_count or 0,
        failure_count=webhook.failure_count or 0
    )


@router.put("/{webhook_id}", response_model=WebhookOut)
async def update_webhook(
    webhook_id: int,
    data: WebhookUpdate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Обновить webhook"""
    
    webhook = db.query(Webhook).filter(
        Webhook.id == webhook_id,
        Webhook.tenant_id == current_user.tenant_id
    ).first()
    
    if not webhook:
        raise HTTPException(status_code=404, detail="Webhook не найден")
    
    if data.url is not None:
        webhook.url = data.url
    if data.events is not None:
        webhook.events = data.events
    if data.is_active is not None:
        webhook.is_active = data.is_active
    
    db.commit()
    db.refresh(webhook)
    
    return WebhookOut(
        id=webhook.id,
        url=webhook.url,
        events=webhook.events or [],
        secret=webhook.secret,
        is_active=webhook.is_active,
        created_at=webhook.created_at,
        last_triggered=webhook.last_triggered,
        success_count=webhook.success_count or 0,
        failure_count=webhook.failure_count or 0
    )


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

