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

from app.db.session import get_db
from app.db.models import User, CustomTrigger, UserIndustryTemplate, IndustryTemplate, RecurringSchedule, Rule, ChainStep
from app.api.deps import get_current_user

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


# Pydantic schemas
class CustomTriggerOut(BaseModel):
    """Кастомный триггер"""
    id: int
    name: str
    display_name: str
    description: str | None
    category: str | None
    is_active: bool
    created_at: datetime

    class Config:
        from_attributes = True


class CreateCustomTriggerRequest(BaseModel):
    """Запрос на создание кастомного триггера"""
    name: str  # "custom.appointment.cancelled"
    display_name: str  # "Отмена записи"
    description: str | None = None
    category: str | None = None  # "appointment", "order", "booking"


class UpdateCustomTriggerRequest(BaseModel):
    """Запрос на обновление кастомного триггера"""
    display_name: str | None = None
    description: str | None = None
    category: str | None = None
    is_active: bool | None = None


# API Endpoints

@router.get("", response_model=List[CustomTriggerOut])
def list_custom_triggers(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    """Получить список кастомных триггеров пользователя"""
    triggers = db.query(CustomTrigger).filter(
        CustomTrigger.tenant_id == current_user.tenant_id
    ).order_by(CustomTrigger.created_at.desc()).all()
    
    return triggers


@router.post("", response_model=CustomTriggerOut, status_code=201)
def create_custom_trigger(
    request: CreateCustomTriggerRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    """Создать кастомный триггер"""
    
    # Проверяем уникальность имени в рамках тенанта
    existing = db.query(CustomTrigger).filter(
        and_(
            CustomTrigger.tenant_id == current_user.tenant_id,
            CustomTrigger.name == request.name
        )
    ).first()
    
    if existing:
        raise HTTPException(
            status_code=400,
            detail=f"Триггер с именем '{request.name}' уже существует"
        )
    
    # Создаём триггер
    trigger = CustomTrigger(
        tenant_id=current_user.tenant_id,
        name=request.name,
        display_name=request.display_name,
        description=request.description,
        category=request.category,
        is_active=True
    )
    
    db.add(trigger)
    db.commit()
    db.refresh(trigger)
    
    return trigger


@router.put("/{trigger_id}", response_model=CustomTriggerOut)
def update_custom_trigger(
    trigger_id: int,
    request: UpdateCustomTriggerRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    """Обновить кастомный триггер"""
    
    trigger = db.query(CustomTrigger).filter(
        and_(
            CustomTrigger.id == trigger_id,
            CustomTrigger.tenant_id == current_user.tenant_id
        )
    ).first()
    
    if not trigger:
        raise HTTPException(status_code=404, detail="Триггер не найден")
    
    # Обновляем поля
    if request.display_name is not None:
        trigger.display_name = request.display_name
    if request.description is not None:
        trigger.description = request.description
    if request.category is not None:
        trigger.category = request.category
    if request.is_active is not None:
        trigger.is_active = request.is_active
    
    trigger.updated_at = datetime.utcnow()
    db.commit()
    db.refresh(trigger)
    
    return trigger


@router.delete("/{trigger_id}")
def delete_custom_trigger(
    trigger_id: int,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    """Удалить кастомный триггер"""
    
    trigger = db.query(CustomTrigger).filter(
        and_(
            CustomTrigger.id == trigger_id,
            CustomTrigger.tenant_id == current_user.tenant_id
        )
    ).first()
    
    if not trigger:
        raise HTTPException(status_code=404, detail="Триггер не найден")
    
    # Проверяем использование триггера в различных местах
    usage_info = check_trigger_usage(db, trigger.id, trigger.name, current_user.tenant_id)
    
    if usage_info["is_used"]:
        # Триггер используется, формируем детальное сообщение
        usage_messages = []
        
        if usage_info["details"]["user_templates"]:
            count = len(usage_info["details"]["user_templates"])
            usage_messages.append(f"используется в {count} шаблон{'ах' if count > 1 else 'е'}")
        
        if usage_info["details"]["recurring_schedules"]:
            count = len(usage_info["details"]["recurring_schedules"])
            usage_messages.append(f"используется в {count} расписани{'ях' if count > 1 else 'и'}")
        
        if usage_info["details"]["rules"]:
            count = len(usage_info["details"]["rules"])
            usage_messages.append(f"используется в {count} правил{'ах' if count > 1 else 'е'}")
        
        if usage_info["details"]["chain_steps"]:
            count = len(usage_info["details"]["chain_steps"])
            usage_messages.append(f"используется в {count} шаг{'ах' if count > 1 else 'е'} цепочки")
        
        message = f"Невозможно удалить триггер '{trigger.display_name}': " + ", ".join(usage_messages) + "."
        
        # Возвращаем информацию об использовании
        raise HTTPException(
            status_code=400,
            detail={
                "message": message,
                "usage": usage_info["details"],
                "trigger_name": trigger.display_name
            }
        )
    
    # Триггер не используется, можно удалить
    db.delete(trigger)
    db.commit()
    
    return {"success": True, "message": "Триггер удалён"}


def check_trigger_usage(db: Session, trigger_id: int, trigger_name: str, tenant_id: int) -> dict:
    """
    Проверяет, используется ли триггер в различных местах системы.
    
    Args:
        db: Сессия базы данных
        trigger_id: ID триггера
        trigger_name: Имя триггера (например, "custom.appointment.cancelled")
        tenant_id: ID тенанта
        
    Returns:
        Словарь с информацией об использовании:
        {
            "is_used": bool,
            "details": {
                "user_templates": [...],
                "recurring_schedules": [...],
                "rules": [...],
                "chain_steps": [...]
            }
        }
    """
    usage_details = {
        "user_templates": [],
        "recurring_schedules": [],
        "rules": [],
        "chain_steps": []
    }
    
    # 1. Проверяем использование в UserIndustryTemplate через IndustryTemplate.trigger_type
    # Находим все IndustryTemplate с таким trigger_type
    industry_templates = db.query(IndustryTemplate).filter(
        IndustryTemplate.trigger_type == trigger_name
    ).all()
    
    if industry_templates:
        industry_template_ids = [it.id for it in industry_templates]
        user_templates = db.query(UserIndustryTemplate).filter(
            UserIndustryTemplate.tenant_id == tenant_id,
            UserIndustryTemplate.industry_template_id.in_(industry_template_ids)
        ).all()
        
        for ut in user_templates:
            industry_template = next((it for it in industry_templates if it.id == ut.industry_template_id), None)
            usage_details["user_templates"].append({
                "id": ut.id,
                "name": ut.custom_name or (industry_template.name if industry_template else "Неизвестно"),
                "type": "user_template"
            })
    
    # 2. Проверяем использование в RecurringSchedule через user_template_id
    if usage_details["user_templates"]:
        user_template_ids = [ut["id"] for ut in usage_details["user_templates"]]
        recurring_schedules = db.query(RecurringSchedule).filter(
            RecurringSchedule.tenant_id == tenant_id,
            RecurringSchedule.user_template_id.in_(user_template_ids)
        ).all()
        
        for rs in recurring_schedules:
            usage_details["recurring_schedules"].append({
                "id": rs.id,
                "name": rs.name,
                "type": "recurring_schedule"
            })
    
    # 3. Проверяем использование в Rule через user_template_id
    if usage_details["user_templates"]:
        user_template_ids = [ut["id"] for ut in usage_details["user_templates"]]
        rules = db.query(Rule).filter(
            Rule.tenant_id == tenant_id,
            Rule.user_template_id.in_(user_template_ids)
        ).all()
        
        for rule in rules:
            usage_details["rules"].append({
                "id": rule.id,
                "name": rule.name,
                "type": "rule"
            })
    
    # 4. Проверяем использование в ChainStep через user_template_id
    if usage_details["user_templates"]:
        user_template_ids = [ut["id"] for ut in usage_details["user_templates"]]
        chain_steps = db.query(ChainStep).filter(
            ChainStep.user_template_id.in_(user_template_ids)
        ).all()
        
        for cs in chain_steps:
            usage_details["chain_steps"].append({
                "id": cs.id,
                "chain_id": cs.chain_id,
                "order": cs.order,
                "type": "chain_step"
            })
    
    # Определяем, используется ли триггер
    is_used = (
        len(usage_details["user_templates"]) > 0 or
        len(usage_details["recurring_schedules"]) > 0 or
        len(usage_details["rules"]) > 0 or
        len(usage_details["chain_steps"]) > 0
    )
    
    return {
        "is_used": is_used,
        "details": usage_details
    }


@router.get("/available", response_model=Dict[str, List[str]])
def get_available_triggers(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    """Получить все доступные триггеры (встроенные + кастомные)"""
    
    # Встроенные триггеры
    builtin_triggers = {
        "appointment": [
            "appointment.created",
            "appointment.soon", 
            "appointment.completed",
            "appointment.followup",
            "appointment.cancelled"
        ],
        "booking": [
            "booking.created",
            "booking.soon",
            "booking.completed",
            "booking.cancelled"
        ],
        "order": [
            "order.created",
            "order.completed",
            "order.cancelled",
            "order.shipped"
        ],
        "delivery": [
            "courier.dispatched",
            "order.delivered",
            "delivery.failed"
        ],
        "education": [
            "lesson.soon",
            "lesson.starting",
            "lesson.completed",
            "lesson.cancelled"
        ],
        "maintenance": [
            "maintenance.due",
            "maintenance.overdue"
        ]
    }
    
    # Кастомные триггеры пользователя
    custom_triggers = db.query(CustomTrigger).filter(
        and_(
            CustomTrigger.tenant_id == current_user.tenant_id,
            CustomTrigger.is_active == True
        )
    ).all()
    
    # Добавляем кастомные триггеры в соответствующие категории
    for trigger in custom_triggers:
        category = trigger.category or "custom"
        if category not in builtin_triggers:
            builtin_triggers[category] = []
        
        if trigger.name not in builtin_triggers[category]:
            builtin_triggers[category].append(trigger.name)
    
    return builtin_triggers


@router.get("/trigger-info/{trigger_name}")
def get_trigger_info(
    trigger_name: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
):
    """Получить информацию о конкретном триггере"""
    
    # Сначала ищем в кастомных
    custom_trigger = db.query(CustomTrigger).filter(
        and_(
            CustomTrigger.tenant_id == current_user.tenant_id,
            CustomTrigger.name == trigger_name
        )
    ).first()
    
    if custom_trigger:
        return {
            "name": custom_trigger.name,
            "display_name": custom_trigger.display_name,
            "description": custom_trigger.description,
            "category": custom_trigger.category,
            "is_custom": True
        }
    
    # Встроенные триггеры
    builtin_info = {
        "appointment.created": {
            "display_name": "При создании записи",
            "description": "Срабатывает когда создается новая запись на приём",
            "category": "appointment"
        },
        "appointment.soon": {
            "display_name": "Перед приёмом", 
            "description": "Срабатывает за указанное время до приёма",
            "category": "appointment"
        },
        "appointment.completed": {
            "display_name": "После приёма",
            "description": "Срабатывает после завершения приёма",
            "category": "appointment"
        },
        "appointment.followup": {
            "display_name": "Повторный визит",
            "description": "Срабатывает через указанное время после приёма",
            "category": "appointment"
        },
        "booking.created": {
            "display_name": "При создании записи",
            "description": "Срабатывает при создании записи в салоне",
            "category": "booking"
        },
        "booking.soon": {
            "display_name": "Перед визитом",
            "description": "Напоминание перед визитом в салон",
            "category": "booking"
        },
        "booking.completed": {
            "display_name": "После визита",
            "description": "Срабатывает после завершения визита",
            "category": "booking"
        },
        "order.created": {
            "display_name": "При создании заказа",
            "description": "Срабатывает при создании нового заказа",
            "category": "order"
        },
        "order.completed": {
            "display_name": "Заказ готов",
            "description": "Срабатывает когда заказ готов к выдаче",
            "category": "order"
        },
        "courier.dispatched": {
            "display_name": "Курьер выехал",
            "description": "Срабатывает когда курьер отправляется к клиенту",
            "category": "delivery"
        },
        "order.delivered": {
            "display_name": "Доставлено",
            "description": "Срабатывает после успешной доставки",
            "category": "delivery"
        },
        "lesson.soon": {
            "display_name": "Перед уроком",
            "description": "Напоминание перед началом урока",
            "category": "education"
        },
        "lesson.starting": {
            "display_name": "Урок начинается",
            "description": "Срабатывает в момент начала урока",
            "category": "education"
        },
        "lesson.completed": {
            "display_name": "После урока",
            "description": "Срабатывает после завершения урока",
            "category": "education"
        }
    }
    
    if trigger_name in builtin_info:
        info = builtin_info[trigger_name]
        return {
            "name": trigger_name,
            "display_name": info["display_name"],
            "description": info["description"],
            "category": info["category"],
            "is_custom": False
        }
    
    raise HTTPException(status_code=404, detail="Триггер не найден")
