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

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

router = APIRouter(prefix="/custom-fields", tags=["custom-fields"])


class CustomFieldCreate(BaseModel):
    name: str
    label: str
    type: str  # text, number, date, select, boolean
    options: Optional[List[str]] = None
    required: bool = False


class CustomFieldUpdate(BaseModel):
    name: Optional[str] = None
    label: Optional[str] = None
    type: Optional[str] = None
    options: Optional[List[str]] = None
    required: Optional[bool] = None


class CustomFieldOut(BaseModel):
    id: int
    name: str
    label: str
    type: str
    options: Optional[List[str]] = None
    required: bool
    created_at: datetime
    updated_at: datetime
    
    class Config:
        from_attributes = True


@router.post("", response_model=CustomFieldOut, status_code=201)
async def create_custom_field(
    data: CustomFieldCreate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Создать новое кастомное поле"""
    try:
        # Проверяем, что поле с таким именем не существует для этого тенанта
        existing = db.query(CustomField).filter(
            CustomField.tenant_id == current_user.tenant_id,
            CustomField.name == data.name
        ).first()
        
        if existing:
            raise HTTPException(
                status_code=400,
                detail=f"Поле с именем '{data.name}' уже существует"
            )
        
        # Валидация типа
        valid_types = ["text", "number", "date", "select", "boolean"]
        if data.type not in valid_types:
            raise HTTPException(
                status_code=400,
                detail=f"Недопустимый тип поля. Допустимые типы: {', '.join(valid_types)}"
            )
        
        # Для типа 'select' должны быть указаны options
        if data.type == "select" and (not data.options or len(data.options) == 0):
            raise HTTPException(
                status_code=400,
                detail="Для типа 'select' необходимо указать варианты выбора"
            )
        
        db_custom_field = CustomField(
            tenant_id=current_user.tenant_id,
            name=data.name,
            label=data.label,
            type=data.type,
            options=data.options if data.type == "select" else None,
            required=data.required
        )
        db.add(db_custom_field)
        db.commit()
        db.refresh(db_custom_field)
        
        return CustomFieldOut(
            id=db_custom_field.id,
            name=db_custom_field.name,
            label=db_custom_field.label,
            type=db_custom_field.type,
            options=db_custom_field.options or [],
            required=db_custom_field.required,
            created_at=db_custom_field.created_at,
            updated_at=db_custom_field.updated_at
        )
    except HTTPException:
        raise
    except Exception as e:
        db.rollback()
        raise HTTPException(
            status_code=500,
            detail=f"Ошибка создания кастомного поля: {str(e)}"
        )


@router.get("", response_model=List[CustomFieldOut])
async def list_custom_fields(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Получить список кастомных полей"""
    fields = db.query(CustomField).filter(
        CustomField.tenant_id == current_user.tenant_id
    ).order_by(CustomField.created_at.desc()).all()
    
    result = []
    for field in fields:
        result.append(CustomFieldOut(
            id=field.id,
            name=field.name,
            label=field.label,
            type=field.type,
            options=field.options or [],
            required=field.required,
            created_at=field.created_at,
            updated_at=field.updated_at
        ))
    
    return result


@router.put("/{field_id}", response_model=CustomFieldOut)
async def update_custom_field(
    field_id: int,
    data: CustomFieldUpdate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Обновить кастомное поле"""
    field = db.query(CustomField).filter(
        CustomField.id == field_id,
        CustomField.tenant_id == current_user.tenant_id
    ).first()
    
    if not field:
        raise HTTPException(status_code=404, detail="Кастомное поле не найдено")
    
    # Если меняется имя, проверяем уникальность
    if data.name and data.name != field.name:
        existing = db.query(CustomField).filter(
            CustomField.tenant_id == current_user.tenant_id,
            CustomField.name == data.name,
            CustomField.id != field_id
        ).first()
        
        if existing:
            raise HTTPException(
                status_code=400,
                detail=f"Поле с именем '{data.name}' уже существует"
            )
    
    if data.name is not None:
        field.name = data.name
    if data.label is not None:
        field.label = data.label
    if data.type is not None:
        # Валидация типа
        valid_types = ["text", "number", "date", "select", "boolean"]
        if data.type not in valid_types:
            raise HTTPException(
                status_code=400,
                detail=f"Недопустимый тип поля. Допустимые типы: {', '.join(valid_types)}"
            )
        field.type = data.type
    if data.options is not None:
        field.options = data.options if data.type == "select" else None
    if data.required is not None:
        field.required = data.required
    
    field.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(field)
    
    return CustomFieldOut(
        id=field.id,
        name=field.name,
        label=field.label,
        type=field.type,
        options=field.options or [],
        required=field.required,
        created_at=field.created_at,
        updated_at=field.updated_at
    )


@router.delete("/{field_id}")
async def delete_custom_field(
    field_id: int,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Удалить кастомное поле"""
    field = db.query(CustomField).filter(
        CustomField.id == field_id,
        CustomField.tenant_id == current_user.tenant_id
    ).first()
    
    if not field:
        raise HTTPException(status_code=404, detail="Кастомное поле не найдено")
    
    db.delete(field)
    db.commit()
    
    return {"ok": True, "message": "Кастомное поле удалено"}

